diff --git a/NEWS b/NEWS index 77c430e1ad845..b30f82a0775c6 100644 --- a/NEWS +++ b/NEWS @@ -65,6 +65,9 @@ PHP NEWS - Output: . Fixed calculation of aligned buffer size. (cmb) +- PCRE: + . Upgraded to pre2lib from 10.44 to 10.45. (nielsdos) + - PDO_PGSQL: . Added Iterable support for PDO::pgsqlCopyFromArray. (KentarouTakeda) . Implement GH-15387 Pdo\Pgsql::setAttribute(PDO::ATTR_PREFETCH, 0) or diff --git a/UPGRADING b/UPGRADING index c8e4d45b7cae9..3a906de901e1d 100644 --- a/UPGRADING +++ b/UPGRADING @@ -250,6 +250,9 @@ PHP 8.5 UPGRADE NOTES - Fileinfo: . Upgraded to file 5.46. +- PCRE: + . Upgraded to pcre2lib from 10.44 to 10.45. + - Readline: . The return types of readline_add_history(), readline_clear_history(), and readline_callback_handler_install() have been changed to true, rather diff --git a/ext/pcre/config.w32 b/ext/pcre/config.w32 index 7c09456b89616..d3c15160d0b0a 100644 --- a/ext/pcre/config.w32 +++ b/ext/pcre/config.w32 @@ -2,7 +2,7 @@ EXTENSION("pcre", "php_pcre.c", false /* never shared */, "-Iext/pcre/pcre2lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); -ADD_SOURCES("ext/pcre/pcre2lib", "pcre2_auto_possess.c pcre2_chartables.c pcre2_compile.c pcre2_config.c pcre2_context.c pcre2_chkdint.c pcre2_dfa_match.c pcre2_error.c pcre2_jit_compile.c pcre2_maketables.c pcre2_match.c pcre2_match_data.c pcre2_newline.c pcre2_ord2utf.c pcre2_pattern_info.c pcre2_serialize.c pcre2_string_utils.c pcre2_study.c pcre2_substitute.c pcre2_substring.c pcre2_tables.c pcre2_ucd.c pcre2_valid_utf.c pcre2_xclass.c pcre2_find_bracket.c pcre2_convert.c pcre2_extuni.c pcre2_script_run.c", "pcre"); +ADD_SOURCES("ext/pcre/pcre2lib", "pcre2_auto_possess.c pcre2_chartables.c pcre2_compile.c pcre2_compile_class.c pcre2_config.c pcre2_context.c pcre2_chkdint.c pcre2_dfa_match.c pcre2_error.c pcre2_jit_compile.c pcre2_maketables.c pcre2_match.c pcre2_match_data.c pcre2_newline.c pcre2_ord2utf.c pcre2_pattern_info.c pcre2_serialize.c pcre2_string_utils.c pcre2_study.c pcre2_substitute.c pcre2_substring.c pcre2_tables.c pcre2_ucd.c pcre2_valid_utf.c pcre2_xclass.c pcre2_find_bracket.c pcre2_convert.c pcre2_extuni.c pcre2_script_run.c", "pcre"); ADD_DEF_FILE("ext\\pcre\\php_pcre.def"); AC_DEFINE('HAVE_BUNDLED_PCRE', 1, 'Define to 1 if PHP uses the bundled PCRE library.'); diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index 7c2a8460cc5d1..bf48aa53130c5 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -68,6 +68,7 @@ else pcre2lib/pcre2_chartables.c pcre2lib/pcre2_chkdint.c pcre2lib/pcre2_compile.c + pcre2lib/pcre2_compile_class.c pcre2lib/pcre2_config.c pcre2lib/pcre2_context.c pcre2lib/pcre2_convert.c diff --git a/ext/pcre/pcre2lib/config.h b/ext/pcre/pcre2lib/config.h index 859d76f24419d..368c6f9865951 100644 --- a/ext/pcre/pcre2lib/config.h +++ b/ext/pcre/pcre2lib/config.h @@ -104,6 +104,32 @@ #define MAX_VARLOOKBEHIND 255 #endif +/* The value of NEWLINE_DEFAULT determines the default newline character + sequence. PCRE2 client programs can override this by selecting other values + at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5 + (ANYCRLF), and 6 (NUL). */ +#ifndef NEWLINE_DEFAULT +#define NEWLINE_DEFAULT 2 +#endif + +/* The value of PCRE2GREP_BUFSIZE is the starting size of the buffer used by + pcre2grep to hold parts of the file it is searching. The buffer will be + expanded up to PCRE2GREP_MAX_BUFSIZE if necessary, for files containing + very long lines. The actual amount of memory used by pcre2grep is three + times this number, because it allows for the buffering of "before" and + "after" lines. */ +#ifndef PCRE2GREP_BUFSIZE +#define PCRE2GREP_BUFSIZE 20480 +#endif + +/* The value of PCRE2GREP_MAX_BUFSIZE specifies the maximum size of the buffer + used by pcre2grep to hold parts of the file it is searching. The actual + amount of memory used by pcre2grep is three times this number, because it + allows for the buffering of "before" and "after" lines. */ +#ifndef PCRE2GREP_MAX_BUFSIZE +#define PCRE2GREP_MAX_BUFSIZE 1048576 +#endif + /* to make a symbol visible */ #ifndef PCRE2_EXPORT #define PCRE2_EXPORT diff --git a/ext/pcre/pcre2lib/pcre2.h b/ext/pcre/pcre2lib/pcre2.h index a322d9f2d56f9..6d1a8758ba966 100644 --- a/ext/pcre/pcre2lib/pcre2.h +++ b/ext/pcre/pcre2lib/pcre2.h @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 44 +#define PCRE2_MINOR 45 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2024-06-07 +#define PCRE2_DATE 2025-02-05 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -143,6 +143,7 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_EXTENDED_MORE 0x01000000u /* C */ #define PCRE2_LITERAL 0x02000000u /* C */ #define PCRE2_MATCH_INVALID_UTF 0x04000000u /* J M D */ +#define PCRE2_ALT_EXTENDED_CLASS 0x08000000u /* C */ /* An additional compile options word is available in the compile context. */ @@ -159,6 +160,10 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_EXTRA_ASCII_BSW 0x00000400u /* C */ #define PCRE2_EXTRA_ASCII_POSIX 0x00000800u /* C */ #define PCRE2_EXTRA_ASCII_DIGIT 0x00001000u /* C */ +#define PCRE2_EXTRA_PYTHON_OCTAL 0x00002000u /* C */ +#define PCRE2_EXTRA_NO_BS0 0x00004000u /* C */ +#define PCRE2_EXTRA_NEVER_CALLOUT 0x00008000u /* C */ +#define PCRE2_EXTRA_TURKISH_CASING 0x00010000u /* C */ /* These are for pcre2_jit_compile(). */ @@ -166,6 +171,7 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_JIT_PARTIAL_SOFT 0x00000002u #define PCRE2_JIT_PARTIAL_HARD 0x00000004u #define PCRE2_JIT_INVALID_UTF 0x00000100u +#define PCRE2_JIT_TEST_ALLOC 0x00000200u /* These are for pcre2_match(), pcre2_dfa_match(), pcre2_jit_match(), and pcre2_substitute(). Some are allowed only for one of the functions, and in @@ -320,7 +326,23 @@ pcre2_pattern_convert(). */ #define PCRE2_ERROR_TOO_MANY_CAPTURES 197 #define PCRE2_ERROR_CONDITION_ATOMIC_ASSERTION_EXPECTED 198 #define PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND 199 - +#define PCRE2_ERROR_MAX_VAR_LOOKBEHIND_EXCEEDED 200 +#define PCRE2_ERROR_PATTERN_COMPILED_SIZE_TOO_BIG 201 +#define PCRE2_ERROR_OVERSIZE_PYTHON_OCTAL 202 +#define PCRE2_ERROR_CALLOUT_CALLER_DISABLED 203 +#define PCRE2_ERROR_EXTRA_CASING_REQUIRES_UNICODE 204 +#define PCRE2_ERROR_TURKISH_CASING_REQUIRES_UTF 205 +#define PCRE2_ERROR_EXTRA_CASING_INCOMPATIBLE 206 +#define PCRE2_ERROR_ECLASS_NEST_TOO_DEEP 207 +#define PCRE2_ERROR_ECLASS_INVALID_OPERATOR 208 +#define PCRE2_ERROR_ECLASS_UNEXPECTED_OPERATOR 209 +#define PCRE2_ERROR_ECLASS_EXPECTED_OPERAND 210 +#define PCRE2_ERROR_ECLASS_MIXED_OPERATORS 211 +#define PCRE2_ERROR_ECLASS_HINT_SQUARE_BRACKET 212 +#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_EXPR 213 +#define PCRE2_ERROR_PERL_ECLASS_EMPTY_EXPR 214 +#define PCRE2_ERROR_PERL_ECLASS_MISSING_CLOSE 215 +#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_CHAR 216 /* "Expected" matching error codes: no match and partial match. */ @@ -407,6 +429,9 @@ released, the numbers must not be changed. */ #define PCRE2_ERROR_INTERNAL_DUPMATCH (-65) #define PCRE2_ERROR_DFA_UINVALID_UTF (-66) #define PCRE2_ERROR_INVALIDOFFSET (-67) +#define PCRE2_ERROR_JIT_UNSUPPORTED (-68) +#define PCRE2_ERROR_REPLACECASE (-69) +#define PCRE2_ERROR_TOOLARGEREPLACE (-70) /* Request types for pcre2_pattern_info() */ @@ -460,6 +485,30 @@ released, the numbers must not be changed. */ #define PCRE2_CONFIG_COMPILED_WIDTHS 14 #define PCRE2_CONFIG_TABLES_LENGTH 15 +/* Optimization directives for pcre2_set_optimize(). +For binary compatibility, only add to this list; do not renumber. */ + +#define PCRE2_OPTIMIZATION_NONE 0 +#define PCRE2_OPTIMIZATION_FULL 1 + +#define PCRE2_AUTO_POSSESS 64 +#define PCRE2_AUTO_POSSESS_OFF 65 +#define PCRE2_DOTSTAR_ANCHOR 66 +#define PCRE2_DOTSTAR_ANCHOR_OFF 67 +#define PCRE2_START_OPTIMIZE 68 +#define PCRE2_START_OPTIMIZE_OFF 69 + +/* Types used in pcre2_set_substitute_case_callout(). + +PCRE2_SUBSTITUTE_CASE_LOWER and PCRE2_SUBSTITUTE_CASE_UPPER are passed to the +callout to indicate that the case of the entire callout input should be +case-transformed. PCRE2_SUBSTITUTE_CASE_TITLE_FIRST is passed to indicate that +only the first character or glyph should be transformed to Unicode titlecase, +and the rest to lowercase. */ + +#define PCRE2_SUBSTITUTE_CASE_LOWER 1 +#define PCRE2_SUBSTITUTE_CASE_UPPER 2 +#define PCRE2_SUBSTITUTE_CASE_TITLE_FIRST 3 /* Types for code units in patterns and subject strings. */ @@ -613,7 +662,9 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_parens_nest_limit(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_compile_recursion_guard(pcre2_compile_context *, \ - int (*)(uint32_t, void *), void *); + int (*)(uint32_t, void *), void *); \ +PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ + pcre2_set_optimize(pcre2_compile_context *, uint32_t); #define PCRE2_MATCH_CONTEXT_FUNCTIONS \ PCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \ @@ -628,6 +679,11 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_substitute_callout(pcre2_match_context *, \ int (*)(pcre2_substitute_callout_block *, void *), void *); \ +PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ + pcre2_set_substitute_case_callout(pcre2_match_context *, \ + PCRE2_SIZE (*)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE, int, \ + void *), \ + void *); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ @@ -740,6 +796,7 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **); + /* Functions for serializing / deserializing compiled patterns. */ #define PCRE2_SERIALIZE_FUNCTIONS \ @@ -907,7 +964,9 @@ pcre2_compile are called by application code. */ #define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) #define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) #define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) +#define pcre2_set_optimize PCRE2_SUFFIX(pcre2_set_optimize_) #define pcre2_set_substitute_callout PCRE2_SUFFIX(pcre2_set_substitute_callout_) +#define pcre2_set_substitute_case_callout PCRE2_SUFFIX(pcre2_set_substitute_case_callout_) #define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) #define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) #define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) diff --git a/ext/pcre/pcre2lib/pcre2_auto_possess.c b/ext/pcre/pcre2lib/pcre2_auto_possess.c index 210d13d37aa88..6d7f27b6904ca 100644 --- a/ext/pcre/pcre2lib/pcre2_auto_possess.c +++ b/ext/pcre/pcre2lib/pcre2_auto_possess.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -49,6 +49,10 @@ repeats into possessive repeats where possible. */ #include "pcre2_internal.h" +/* This macro represents the max size of list[] and that is used to keep +track of UCD info in several places, it should be kept on sync with the +value used by GenerateUcd.py */ +#define MAX_LIST 8 /************************************************* * Tables for auto-possessification * @@ -64,7 +68,7 @@ The Unicode property types (\P and \p) have to be present to fill out the table because of what their opcode values are, but the table values should always be zero because property types are handled separately in the code. The last four columns apply to items that cannot be repeated, so there is no need to have -rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is +rows for them. Note that OP_DIGIT etc. are generated only when PCRE2_UCP is *not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ #define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1) @@ -123,21 +127,21 @@ opcode is used to select the column. The values are as follows: */ static const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = { -/* ANY LAMP GC PC SC SCX ALNUM SPACE PXSPACE WORD CLIST UCNC BIDICL BOOL */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */ - { 0, 3, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_LAMP */ - { 0, 0, 2, 4, 0, 0, 9, 10, 10, 11, 0, 0, 0, 0 }, /* PT_GC */ - { 0, 0, 5, 2, 0, 0, 15, 16, 16, 17, 0, 0, 0, 0 }, /* PT_PC */ - { 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SC */ - { 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SCX */ - { 0, 3, 6, 12, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_ALNUM */ - { 0, 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_SPACE */ - { 0, 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_PXSPACE */ - { 0, 0, 8, 14, 0, 0, 0, 1, 1, 3, 0, 0, 0, 0 }, /* PT_WORD */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, /* PT_UCNC */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_BIDICL */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* PT_BOOL */ +/* LAMP GC PC SC SCX ALNUM SPACE PXSPACE WORD CLIST UCNC BIDICL BOOL */ + { 3, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_LAMP */ + { 0, 2, 4, 0, 0, 9, 10, 10, 11, 0, 0, 0, 0 }, /* PT_GC */ + { 0, 5, 2, 0, 0, 15, 16, 16, 17, 0, 0, 0, 0 }, /* PT_PC */ + { 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SC */ + { 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SCX */ + { 3, 6, 12, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_ALNUM */ + { 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_SPACE */ + { 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_PXSPACE */ + { 0, 8, 14, 0, 0, 0, 1, 1, 3, 0, 0, 0, 0 }, /* PT_WORD */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, /* PT_UCNC */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_BIDICL */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* PT_BOOL */ + /* PT_ANY does not need a record. */ }; /* This table is used to check whether auto-possessification is possible @@ -199,7 +203,7 @@ static BOOL check_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata, BOOL negated) { -BOOL ok; +BOOL ok, rc; const uint32_t *p; const ucd_record *prop = GET_UCD(c); @@ -240,12 +244,13 @@ switch(ptype) { HSPACE_CASES: VSPACE_CASES: - return negated; + rc = negated; + break; default: - return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated; + rc = (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated; } - break; /* Control never reaches here */ + return rc; case PT_WORD: return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || @@ -259,7 +264,8 @@ switch(ptype) if (c < *p) return !negated; if (c == *p++) return negated; } - break; /* Control never reaches here */ + PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ + break; /* Haven't yet thought these through. */ @@ -328,6 +334,7 @@ get_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc, PCRE2_UCHAR c = *code; PCRE2_UCHAR base; PCRE2_SPTR end; +PCRE2_SPTR class_end; uint32_t chr; #ifdef SUPPORT_UNICODE @@ -450,10 +457,12 @@ switch(c) code += 2; do { - if (clist_dest >= list + 8) + if (clist_dest >= list + MAX_LIST) { - /* Early return if there is not enough space. This should never - happen, since all clists are shorter than 5 character now. */ + /* Early return if there is not enough space. GenerateUcd.py + generated a list with more than 5 characters and something + must be done about that going forward. */ + PCRE2_DEBUG_UNREACHABLE(); /* Remove if it ever triggers */ list[2] = code[0]; list[3] = code[1]; return code; @@ -473,11 +482,13 @@ switch(c) case OP_CLASS: #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - if (c == OP_XCLASS) + case OP_ECLASS: + if (c == OP_XCLASS || c == OP_ECLASS) end = code + GET(code, 0) - 1; else #endif end = code + 32 / sizeof(PCRE2_UCHAR); + class_end = end; switch(*end) { @@ -505,6 +516,7 @@ switch(c) break; } list[2] = (uint32_t)(end - code); + list[3] = (uint32_t)(end - class_end); return end; } @@ -537,7 +549,7 @@ compare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb, const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit) { PCRE2_UCHAR c; -uint32_t list[8]; +uint32_t list[MAX_LIST]; const uint32_t *chr_ptr; const uint32_t *ochr_ptr; const uint32_t *list_ptr; @@ -581,7 +593,7 @@ for(;;) continue; } - /* At the end of a branch, skip to the end of the group. */ + /* At the end of a branch, skip to the end of the group and process it. */ if (c == OP_ALT) { @@ -638,19 +650,29 @@ for(;;) return FALSE; break; - /* Atomic sub-patterns and assertions can always auto-possessify their - last iterator except for variable length lookbehinds. However, if the - group was entered as a result of checking a previous iterator, this is - not possible. */ + /* Atomic sub-patterns and forward assertions can always auto-possessify + their last iterator. However, if the group was entered as a result of + checking a previous iterator, this is not possible. */ case OP_ASSERT: case OP_ASSERT_NOT: case OP_ONCE: return !entered_a_group; + /* Fixed-length lookbehinds can be treated the same way, but variable + length lookbehinds must not auto-possessify their last iterator. Note + that in order to identify a variable length lookbehind we must check + through all branches, because some may be of fixed length. */ + case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: - return (bracode[1+LINK_SIZE] == OP_VREVERSE)? FALSE : !entered_a_group; + do + { + if (bracode[1+LINK_SIZE] == OP_VREVERSE) return FALSE; /* Variable */ + bracode += GET(bracode, 1); + } + while (*bracode == OP_ALT); + return !entered_a_group; /* Not variable length */ /* Non-atomic assertions - don't possessify last iterator. This needs more thought. */ @@ -748,12 +770,12 @@ for(;;) if (base_list[0] == OP_CLASS) #endif { - set1 = (uint8_t *)(base_end - base_list[2]); + set1 = (const uint8_t *)(base_end - base_list[2]); list_ptr = list; } else { - set1 = (uint8_t *)(code - list[2]); + set1 = (const uint8_t *)(code - list[2]); list_ptr = base_list; } @@ -762,13 +784,14 @@ for(;;) { case OP_CLASS: case OP_NCLASS: - set2 = (uint8_t *) + set2 = (const uint8_t *) ((list_ptr == list ? code : base_end) - list_ptr[2]); break; #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE; + xclass_flags = (list_ptr == list ? code : base_end) - + list_ptr[2] + LINK_SIZE; if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE; if ((*xclass_flags & XCL_MAP) == 0) { @@ -777,7 +800,7 @@ for(;;) /* Might be an empty repeat. */ continue; } - set2 = (uint8_t *)(xclass_flags + 1); + set2 = (const uint8_t *)(xclass_flags + 1); break; #endif @@ -785,21 +808,21 @@ for(;;) invert_bits = TRUE; /* Fall through */ case OP_DIGIT: - set2 = (uint8_t *)(cb->cbits + cbit_digit); + set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; /* Fall through */ case OP_WHITESPACE: - set2 = (uint8_t *)(cb->cbits + cbit_space); + set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; /* Fall through */ case OP_WORDCHAR: - set2 = (uint8_t *)(cb->cbits + cbit_word); + set2 = (const uint8_t *)(cb->cbits + cbit_word); break; default: @@ -1084,7 +1107,7 @@ for(;;) case OP_CLASS: if (chr > 255) break; - class_bitset = (uint8_t *) + class_bitset = (const uint8_t *) ((list_ptr == list ? code : base_end) - list_ptr[2]); if ((class_bitset[chr >> 3] & (1u << (chr & 7))) != 0) return FALSE; break; @@ -1092,9 +1115,18 @@ for(;;) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) - - list_ptr[2] + LINK_SIZE, utf)) return FALSE; + list_ptr[2] + LINK_SIZE, (const uint8_t*)cb->start_code, utf)) + return FALSE; break; -#endif + + case OP_ECLASS: + if (PRIV(eclass)(chr, + (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE, + (list_ptr == list ? code : base_end) - list_ptr[3], + (const uint8_t*)cb->start_code, utf)) + return FALSE; + break; +#endif /* SUPPORT_WIDE_CHARS */ default: return FALSE; @@ -1109,8 +1141,8 @@ for(;;) if (list[1] == 0) return TRUE; } -/* Control never reaches here. There used to be a fail-save return FALSE; here, -but some compilers complain about an unreachable statement. */ +PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ +return FALSE; /* Avoid compiler warnings */ } @@ -1140,7 +1172,7 @@ PRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb) PCRE2_UCHAR c; PCRE2_SPTR end; PCRE2_UCHAR *repeat_opcode; -uint32_t list[8]; +uint32_t list[MAX_LIST]; int rec_limit = 1000; /* Was 10,000 but clang+ASAN uses a lot of stack. */ BOOL utf = (cb->external_options & PCRE2_UTF) != 0; BOOL ucp = (cb->external_options & PCRE2_UCP) != 0; @@ -1149,7 +1181,11 @@ for (;;) { c = *code; - if (c >= OP_TABLE_LENGTH) return -1; /* Something gone wrong */ + if (c >= OP_TABLE_LENGTH) + { + PCRE2_DEBUG_UNREACHABLE(); + return -1; /* Something gone wrong */ + } if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) { @@ -1198,10 +1234,14 @@ for (;;) } c = *code; } - else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS) + else if (c == OP_CLASS || c == OP_NCLASS +#ifdef SUPPORT_WIDE_CHARS + || c == OP_XCLASS || c == OP_ECLASS +#endif + ) { #ifdef SUPPORT_WIDE_CHARS - if (c == OP_XCLASS) + if (c == OP_XCLASS || c == OP_ECLASS) repeat_opcode = code + GET(code, 1); else #endif @@ -1211,7 +1251,7 @@ for (;;) if (c >= OP_CRSTAR && c <= OP_CRMINRANGE) { /* The return from get_chr_property_list() will never be NULL when - *code (aka c) is one of the three class opcodes. However, gcc with + *code (aka c) is one of the four class opcodes. However, gcc with -fanalyzer notes that a NULL return is possible, and grumbles. Hence we put in a check. */ @@ -1279,6 +1319,7 @@ for (;;) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: + case OP_ECLASS: code += GET(code, 1); break; #endif diff --git a/ext/pcre/pcre2lib/pcre2_chkdint.c b/ext/pcre/pcre2lib/pcre2_chkdint.c index d04f6f8cf1afa..70830236999d8 100644 --- a/ext/pcre/pcre2lib/pcre2_chkdint.c +++ b/ext/pcre/pcre2lib/pcre2_chkdint.c @@ -74,9 +74,7 @@ if (__builtin_mul_overflow(a, b, &m)) return TRUE; #else INT64_OR_DOUBLE m; -#ifdef PCRE2_DEBUG -if (a < 0 || b < 0) abort(); -#endif +PCRE2_ASSERT(a >= 0 && b >= 0); m = (INT64_OR_DOUBLE)a * (INT64_OR_DOUBLE)b; @@ -93,4 +91,4 @@ if (m > PCRE2_SIZE_MAX) return TRUE; return FALSE; } -/* End of pcre_chkdint.c */ +/* End of pcre2_chkdint.c */ diff --git a/ext/pcre/pcre2lib/pcre2_compile.c b/ext/pcre/pcre2lib/pcre2_compile.c index 8e6787aba38ec..0ffac8939cb69 100644 --- a/ext/pcre/pcre2lib/pcre2_compile.c +++ b/ext/pcre/pcre2lib/pcre2_compile.c @@ -47,7 +47,7 @@ POSSIBILITY OF SUCH DAMAGE. #define PSSTART start_pattern /* Field containing processed string start */ #define PSEND end_pattern /* Field containing processed string end */ -#include "pcre2_internal.h" +#include "pcre2_compile.h" /* In rare error cases debugging might require calling pcre2_printint(). */ @@ -108,20 +108,8 @@ them will be able to (i.e. assume a 64-bit world). */ #define SIZEOFFSET 2 #endif -/* Macros for manipulating elements of the parsed pattern vector. */ - -#define META_CODE(x) (x & 0xffff0000u) -#define META_DATA(x) (x & 0x0000ffffu) -#define META_DIFF(x,y) ((x-y)>>16) - /* Function definitions to allow mutual recursion */ -#ifdef SUPPORT_UNICODE -static unsigned int - add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t, uint32_t, - compile_block *, const uint32_t *, unsigned int); -#endif - static int compile_regex(uint32_t, uint32_t, PCRE2_UCHAR **, uint32_t **, int *, uint32_t, uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *, @@ -199,106 +187,6 @@ don't have to check them every time. */ #define OFLOW_MAX (INT_MAX - 20) -/* Code values for parsed patterns, which are stored in a vector of 32-bit -unsigned ints. Values less than META_END are literal data values. The coding -for identifying the item is in the top 16-bits, leaving 16 bits for the -additional data that some of them need. The META_CODE, META_DATA, and META_DIFF -macros are used to manipulate parsed pattern elements. - -NOTE: When these definitions are changed, the table of extra lengths for each -code (meta_extra_lengths, just below) must be updated to remain in step. */ - -#define META_END 0x80000000u /* End of pattern */ - -#define META_ALT 0x80010000u /* alternation */ -#define META_ATOMIC 0x80020000u /* atomic group */ -#define META_BACKREF 0x80030000u /* Back ref */ -#define META_BACKREF_BYNAME 0x80040000u /* \k'name' */ -#define META_BIGVALUE 0x80050000u /* Next is a literal > META_END */ -#define META_CALLOUT_NUMBER 0x80060000u /* (?C with numerical argument */ -#define META_CALLOUT_STRING 0x80070000u /* (?C with string argument */ -#define META_CAPTURE 0x80080000u /* Capturing parenthesis */ -#define META_CIRCUMFLEX 0x80090000u /* ^ metacharacter */ -#define META_CLASS 0x800a0000u /* start non-empty class */ -#define META_CLASS_EMPTY 0x800b0000u /* empty class */ -#define META_CLASS_EMPTY_NOT 0x800c0000u /* negative empty class */ -#define META_CLASS_END 0x800d0000u /* end of non-empty class */ -#define META_CLASS_NOT 0x800e0000u /* start non-empty negative class */ -#define META_COND_ASSERT 0x800f0000u /* (?(?assertion)... */ -#define META_COND_DEFINE 0x80100000u /* (?(DEFINE)... */ -#define META_COND_NAME 0x80110000u /* (?()... */ -#define META_COND_NUMBER 0x80120000u /* (?(digits)... */ -#define META_COND_RNAME 0x80130000u /* (?(R&name)... */ -#define META_COND_RNUMBER 0x80140000u /* (?(Rdigits)... */ -#define META_COND_VERSION 0x80150000u /* (?(VERSIONx.y)... */ -#define META_DOLLAR 0x80160000u /* $ metacharacter */ -#define META_DOT 0x80170000u /* . metacharacter */ -#define META_ESCAPE 0x80180000u /* \d and friends */ -#define META_KET 0x80190000u /* closing parenthesis */ -#define META_NOCAPTURE 0x801a0000u /* no capture parens */ -#define META_OPTIONS 0x801b0000u /* (?i) and friends */ -#define META_POSIX 0x801c0000u /* POSIX class item */ -#define META_POSIX_NEG 0x801d0000u /* negative POSIX class item */ -#define META_RANGE_ESCAPED 0x801e0000u /* range with at least one escape */ -#define META_RANGE_LITERAL 0x801f0000u /* range defined literally */ -#define META_RECURSE 0x80200000u /* Recursion */ -#define META_RECURSE_BYNAME 0x80210000u /* (?&name) */ -#define META_SCRIPT_RUN 0x80220000u /* (*script_run:...) */ - -/* These must be kept together to make it easy to check that an assertion -is present where expected in a conditional group. */ - -#define META_LOOKAHEAD 0x80230000u /* (?= */ -#define META_LOOKAHEADNOT 0x80240000u /* (?! */ -#define META_LOOKBEHIND 0x80250000u /* (?<= */ -#define META_LOOKBEHINDNOT 0x80260000u /* (? */ CHAR_GREATER_THAN_SIGN, /* ? */ CHAR_QUESTION_MARK, + /* @ */ CHAR_COMMERCIAL_AT, /* A */ -ESC_A, + /* B */ -ESC_B, /* C */ -ESC_C, + /* D */ -ESC_D, /* E */ -ESC_E, + /* F */ 0, /* G */ -ESC_G, + /* H */ -ESC_H, /* I */ 0, + /* J */ 0, /* K */ -ESC_K, + /* L */ 0, /* M */ 0, + /* N */ -ESC_N, /* O */ 0, + /* P */ -ESC_P, /* Q */ -ESC_Q, + /* R */ -ESC_R, /* S */ -ESC_S, + /* T */ 0, /* U */ 0, + /* V */ -ESC_V, /* W */ -ESC_W, + /* X */ -ESC_X, /* Y */ 0, + /* Z */ -ESC_Z, /* [ */ CHAR_LEFT_SQUARE_BRACKET, + /* \ */ CHAR_BACKSLASH, /* ] */ CHAR_RIGHT_SQUARE_BRACKET, + /* ^ */ CHAR_CIRCUMFLEX_ACCENT, /* _ */ CHAR_UNDERSCORE, + /* ` */ CHAR_GRAVE_ACCENT, /* a */ CHAR_BEL, + /* b */ -ESC_b, /* c */ 0, + /* d */ -ESC_d, /* e */ CHAR_ESC, + /* f */ CHAR_FF, /* g */ 0, + /* h */ -ESC_h, /* i */ 0, + /* j */ 0, /* k */ -ESC_k, + /* l */ 0, /* m */ 0, + /* n */ CHAR_LF, /* o */ 0, + /* p */ -ESC_p, /* q */ 0, + /* r */ CHAR_CR, /* s */ -ESC_s, + /* t */ CHAR_HT, /* u */ 0, + /* v */ -ESC_v, /* w */ -ESC_w, + /* x */ 0, /* y */ 0, + /* z */ -ESC_z }; #else @@ -656,6 +542,8 @@ static const char alasnames[] = STRING_non_atomic_positive_lookbehind0 STRING_negative_lookahead0 STRING_negative_lookbehind0 + STRING_scs0 + STRING_scan_substring0 STRING_atomic0 STRING_sr0 STRING_asr0 @@ -675,6 +563,8 @@ static const alasitem alasmeta[] = { { 30, META_LOOKBEHIND_NA }, { 18, META_LOOKAHEADNOT }, { 19, META_LOOKBEHINDNOT }, + { 3, META_SCS }, + { 14, META_SCS }, { 6, META_ATOMIC }, { 2, META_SCRIPT_RUN }, /* sr = script run */ { 3, META_ATOMIC_SCRIPT_RUN }, /* asr = atomic script run */ @@ -694,8 +584,11 @@ static uint32_t chartypeoffset[] = { now all in a single string, to reduce the number of relocations when a shared library is dynamically loaded. The list of lengths is terminated by a zero length entry. The first three must be alpha, lower, upper, as this is assumed -for handling case independence. The indices for several classes are needed, so -identify them. */ +for handling case independence. + +The indices for several classes are stored in pcre2_compile.h - these must +be kept in sync with posix_names, posix_name_lengths, posix_class_maps, +and posix_substitutes. */ static const char posix_names[] = STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 @@ -706,12 +599,6 @@ static const char posix_names[] = static const uint8_t posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; -#define PC_DIGIT 7 -#define PC_GRAPH 8 -#define PC_PRINT 9 -#define PC_PUNCT 10 -#define PC_XDIGIT 13 - /* Table of class bit maps for each POSIX class. Each class is formed from a base map, with an optional addition or removal of another map. Then, for some classes, there is some additional tweaking: for [:blank:] the vertical space @@ -722,7 +609,7 @@ addition or a negative value for map subtraction (if there are two maps). The absolute value of the third field has these meanings: 0 => no tweaking, 1 => remove vertical space characters, 2 => remove underscore. */ -static const int posix_class_maps[] = { +const int PRIV(posix_class_maps)[] = { cbit_word, cbit_digit, -2, /* alpha */ cbit_lower, -1, 0, /* lower */ cbit_upper, -1, 0, /* upper */ @@ -760,7 +647,6 @@ static int posix_substitutes[] = { PT_WORD, 0, /* word */ /* Perl and POSIX space are the same */ PT_PXXDIGIT, 0 /* xdigit */ /* Perl has additional hex digits */ }; -#define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t))) #endif /* SUPPORT_UNICODE */ /* Masks for checking option settings. When PCRE2_LITERAL is set, only a subset @@ -778,10 +664,11 @@ are allowed. */ PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MATCH_UNSET_BACKREF| \ PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C|PCRE2_NEVER_UCP| \ PCRE2_NEVER_UTF|PCRE2_NO_AUTO_CAPTURE|PCRE2_NO_AUTO_POSSESS| \ - PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY) + PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_ALT_EXTENDED_CLASS) #define PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS \ - (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_CASELESS_RESTRICT) + (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD| \ + PCRE2_EXTRA_CASELESS_RESTRICT|PCRE2_EXTRA_TURKISH_CASING) #define PUBLIC_COMPILE_EXTRA_OPTIONS \ (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \ @@ -789,27 +676,8 @@ are allowed. */ PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX| \ PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK|PCRE2_EXTRA_ASCII_BSD| \ PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW|PCRE2_EXTRA_ASCII_POSIX| \ - PCRE2_EXTRA_ASCII_DIGIT) - -/* Compile time error code numbers. They are given names so that they can more -easily be tracked. When a new number is added, the tables called eint1 and -eint2 in pcre2posix.c may need to be updated, and a new error text must be -added to compile_error_texts in pcre2_error.c. Also, the error codes in -pcre2.h.in must be updated - their values are exactly 100 greater than these -values. */ - -enum { ERR0 = COMPILE_ERROR_BASE, - ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, - ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, - ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, - ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, - ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, - ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, - ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, - ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, - ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, - ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100, - ERR101 }; + PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_PYTHON_OCTAL|PCRE2_EXTRA_NO_BS0| \ + PCRE2_EXTRA_NEVER_CALLOUT) /* This is a table of start-of-pattern options such as (*UTF) and settings such as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward @@ -817,16 +685,18 @@ compatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is generic and always supported. */ enum { PSO_OPT, /* Value is an option bit */ + PSO_XOPT, /* Value is an xoption bit */ PSO_FLG, /* Value is a flag bit */ PSO_NL, /* Value is a newline type */ PSO_BSR, /* Value is a \R type */ PSO_LIMH, /* Read integer value for heap limit */ PSO_LIMM, /* Read integer value for match limit */ - PSO_LIMD /* Read integer value for depth limit */ + PSO_LIMD, /* Read integer value for depth limit */ + PSO_OPTMZ /* Value is an optimization bit */ }; typedef struct pso { - const uint8_t *name; + const char *name; uint16_t length; uint16_t type; uint32_t value; @@ -835,27 +705,29 @@ typedef struct pso { /* NB: STRING_UTFn_RIGHTPAR contains the length as well */ static const pso pso_list[] = { - { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, - { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, - { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, - { (uint8_t *)STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET }, - { (uint8_t *)STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET }, - { (uint8_t *)STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPT, PCRE2_NO_AUTO_POSSESS }, - { (uint8_t *)STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPT, PCRE2_NO_DOTSTAR_ANCHOR }, - { (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT }, - { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE }, - { (uint8_t *)STRING_LIMIT_HEAP_EQ, 11, PSO_LIMH, 0 }, - { (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 }, - { (uint8_t *)STRING_LIMIT_DEPTH_EQ, 12, PSO_LIMD, 0 }, - { (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMD, 0 }, - { (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR }, - { (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF }, - { (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF }, - { (uint8_t *)STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY }, - { (uint8_t *)STRING_NUL_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_NUL }, - { (uint8_t *)STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF }, - { (uint8_t *)STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF }, - { (uint8_t *)STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE } + { STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, + { STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, + { STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, + { STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET }, + { STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET }, + { STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPTMZ, PCRE2_OPTIM_AUTO_POSSESS }, + { STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPTMZ, PCRE2_OPTIM_DOTSTAR_ANCHOR }, + { STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT }, + { STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPTMZ, PCRE2_OPTIM_START_OPTIMIZE }, + { STRING_CASELESS_RESTRICT_RIGHTPAR, 18, PSO_XOPT, PCRE2_EXTRA_CASELESS_RESTRICT }, + { STRING_TURKISH_CASING_RIGHTPAR, 15, PSO_XOPT, PCRE2_EXTRA_TURKISH_CASING }, + { STRING_LIMIT_HEAP_EQ, 11, PSO_LIMH, 0 }, + { STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 }, + { STRING_LIMIT_DEPTH_EQ, 12, PSO_LIMD, 0 }, + { STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMD, 0 }, + { STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR }, + { STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF }, + { STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF }, + { STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY }, + { STRING_NUL_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_NUL }, + { STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF }, + { STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF }, + { STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE } }; /* This table is used when converting repeating opcodes into possessified @@ -910,12 +782,15 @@ static const uint8_t opcode_possessify[] = { OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */ 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */ - 0, 0, 0, /* CLASS, NCLASS, XCLASS */ + 0, 0, 0, 0, /* CLASS, NCLASS, XCLASS, ECLASS */ 0, 0, /* REF, REFI */ 0, 0, /* DNREF, DNREFI */ - 0, 0 /* RECURSE, CALLOUT */ + 0, 0, /* RECURSE, CALLOUT */ }; +/* Compile-time check that the table has the correct size. */ +STATIC_ASSERT(sizeof(opcode_possessify) == OP_CALLOUT+1, opcode_possessify); + #ifdef DEBUG_SHOW_PARSED /************************************************* @@ -977,7 +852,7 @@ for (;;) { uint32_t ptype = *pptr >> 16; uint32_t pvalue = *pptr++ & 0xffff; - fprintf(stderr, "META \\%c %d %d", (meta_arg == ESC_P)? 'P':'p', + fprintf(stderr, "META \\%c %d %d", (meta_arg == ESC_P)? CHAR_P:CHAR_p, ptype, pvalue); } else @@ -1152,6 +1027,24 @@ for (;;) fprintf(stderr, "%zd", offset); break; + case META_OFFSET: + fprintf(stderr, "META_OFFSET offset="); + GETOFFSET(offset, pptr); + fprintf(stderr, "%zd", offset); + break; + + case META_SCS: + fprintf(stderr, "META (*scan_substring:"); + break; + + case META_SCS_NAME: + fprintf(stderr, "META_SCS_NAME length=%d relative_offset=%d", *pptr++, (int)meta_arg); + break; + + case META_SCS_NUMBER: + fprintf(stderr, "META_SCS_NUMBER %d relative_offset=%d", *pptr++, (int)meta_arg); + break; + case META_MARK: fprintf(stderr, "META (*MARK:"); goto SHOWARG; @@ -1180,6 +1073,12 @@ for (;;) } fprintf(stderr, ") length=%u", length); break; + + case META_ECLASS_AND: fprintf(stderr, "META_ECLASS_AND"); break; + case META_ECLASS_OR: fprintf(stderr, "META_ECLASS_OR"); break; + case META_ECLASS_SUB: fprintf(stderr, "META_ECLASS_SUB"); break; + case META_ECLASS_XOR: fprintf(stderr, "META_ECLASS_XOR"); break; + case META_ECLASS_NOT: fprintf(stderr, "META_ECLASS_NOT"); break; } fprintf(stderr, "\n"); } @@ -1199,7 +1098,7 @@ associated JIT data. */ PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION pcre2_code_copy(const pcre2_code *code) { -PCRE2_SIZE* ref_count; +PCRE2_SIZE *ref_count; pcre2_code *newcode; if (code == NULL) return NULL; @@ -1311,7 +1210,10 @@ result must be greater than zero. ptrptr points to the character pointer variable ptrend points to the end of the input string allow_sign if < 0, sign not allowed; if >= 0, sign is relative to this - max_value the largest number allowed + max_value the largest number allowed; + you must not pass a value for max_value larger than + INT_MAX/10 - 1 because this function relies on max_value to + avoid integer overflow max_error the error to give for an over-large number intptr where to put the result errcodeptr where to put an error code @@ -1330,6 +1232,8 @@ uint32_t n = 0; PCRE2_SPTR ptr = *ptrptr; BOOL yield = FALSE; +PCRE2_ASSERT(max_value <= INT_MAX/10 - 1); + *errorcodeptr = 0; if (allow_sign >= 0 && ptr < ptrend) @@ -1350,10 +1254,11 @@ if (allow_sign >= 0 && ptr < ptrend) if (ptr >= ptrend || !IS_DIGIT(*ptr)) return FALSE; while (ptr < ptrend && IS_DIGIT(*ptr)) { - n = n * 10 + *ptr++ - CHAR_0; + n = n * 10 + (*ptr++ - CHAR_0); if (n > max_value) { *errorcodeptr = max_error; + while (ptr < ptrend && IS_DIGIT(*ptr)) ptr++; goto EXIT; } } @@ -1367,7 +1272,7 @@ if (allow_sign >= 0 && sign != 0) } if (sign > 0) n += allow_sign; - else if ((int)n > allow_sign) + else if (n > (uint32_t)allow_sign) { *errorcodeptr = ERR15; /* Non-existent subpattern */ goto EXIT; @@ -1454,7 +1359,7 @@ else if (pp >= ptrend || *pp != CHAR_RIGHT_CURLY_BRACKET) return FALSE; } -/* Now process the quantifier for real. We know it must be {n} or (n,} or {,m} +/* Now process the quantifier for real. We know it must be {n} or {n,} or {,m} or {n,m}. The only error that read_number() can return is for a number that is too big. If *errorcodeptr is returned as zero it means no number was found. */ @@ -1521,15 +1426,15 @@ return yield; /* This function is called when a \ has been encountered. It either returns a positive value for a simple escape such as \d, or 0 for a data character, which -is placed in chptr. A backreference to group n is returned as negative n. On +is placed in chptr. A backreference to group n is returned as -(n+1). On entry, ptr is pointing at the character after \. On exit, it points after the final code unit of the escape sequence. This function is also called from pcre2_substitute() to handle escape sequences in replacement strings. In this case, the cb argument is NULL, and in the case of escapes that have further processing, only sequences that define a data -character are recognised. The isclass argument is not relevant; the options -argument is the final value of the compiled pattern's options. +character are recognised. The options argument is the final value of the +compiled pattern's options. Arguments: ptrptr points to the input position pointer @@ -1538,7 +1443,8 @@ argument is the final value of the compiled pattern's options. errorcodeptr points to the errorcode variable (containing zero) options the current options bits xoptions the current extra options bits - isclass TRUE if inside a character class + bracount the number of capturing parentheses encountered so far + isclass TRUE if in a character class cb compile data block or NULL when called from pcre2_substitute() Returns: zero => a data character @@ -1549,8 +1455,8 @@ Returns: zero => a data character int PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr, - int *errorcodeptr, uint32_t options, uint32_t xoptions, BOOL isclass, - compile_block *cb) + int *errorcodeptr, uint32_t options, uint32_t xoptions, uint32_t bracount, + BOOL isclass, compile_block *cb) { BOOL utf = (options & PCRE2_UTF) != 0; BOOL alt_bsux = @@ -1619,17 +1525,23 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) if (ptrend - p > 1 && *p == CHAR_U && p[1] == CHAR_PLUS) { -#ifdef EBCDIC - *errorcodeptr = ERR93; -#else +#ifndef EBCDIC if (utf) { ptr = p + 2; escape = 0; /* Not a fancy escape after all */ goto COME_FROM_NU; } - else *errorcodeptr = ERR93; #endif + *errorcodeptr = ERR93; + } + + /* Give an error in contexts where quantifiers are not allowed + (character classes; substitution strings). */ + + else if (isclass || cb == NULL) + { + *errorcodeptr = ERR37; } /* Give an error if what follows is not a quantifier, but don't override @@ -1660,7 +1572,8 @@ else if (cb == NULL) { - if (c != CHAR_c && c != CHAR_o && c != CHAR_x) + if (c < CHAR_0 || + (c > CHAR_9 && (c != CHAR_c && c != CHAR_o && c != CHAR_x && c != CHAR_g))) { *errorcodeptr = ERR3; return 0; @@ -1715,6 +1628,7 @@ else hptr >= ptrend || /* Hit end of input */ *hptr != CHAR_RIGHT_CURLY_BRACKET) /* No } terminator */ { + if (isclass) break; /* In a class, just treat as '\u' literal */ escape = ESC_ub; /* Special return */ ptr++; /* Skip { */ break; /* Hex escape not recognized */ @@ -1773,8 +1687,14 @@ else (possibly recursive) subroutine calls, _not_ backreferences. We return the ESC_g code. - Summary: Return a negative number for a numerical back reference, ESC_k for - a named back reference, and ESC_g for a named or numbered subroutine call. + Summary: Return a negative number for a numerical back reference (offset + by 1), ESC_k for a named back reference, and ESC_g for a named or + numbered subroutine call. + + The above describes the \g behaviour inside patterns. Inside replacement + strings (pcre2_substitute) we support only \g for Python + compatibility. Return ESG_g for the named case, and -(num+1) for the + numbered case. */ case CHAR_g: @@ -1786,6 +1706,40 @@ else break; } + if (cb == NULL) + { + PCRE2_SPTR p; + /* Substitution strings */ + if (*ptr != CHAR_LESS_THAN_SIGN) + { + *errorcodeptr = ERR57; + break; + } + + p = ptr + 1; + + if (!read_number(&p, ptrend, -1, MAX_GROUP_NUMBER, ERR61, &s, + errorcodeptr)) + { + if (*errorcodeptr == 0) escape = ESC_g; /* No number found */ + break; + } + + if (p >= ptrend || *p != CHAR_GREATER_THAN_SIGN) + { + /* not advancing ptr; report error at the \g character */ + *errorcodeptr = ERR57; + break; + } + + /* This is the reason that back references are returned as -(s+1) rather + than just -s. In a pattern, \0 is not a back reference, but \g<0> is + valid in a substitution string, so this must be representable. */ + ptr = p + 1; + escape = -(s+1); + break; + } + if (*ptr == CHAR_LESS_THAN_SIGN || *ptr == CHAR_APOSTROPHE) { escape = ESC_g; @@ -1800,7 +1754,7 @@ else PCRE2_SPTR p = ptr + 1; while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; - if (!read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s, + if (!read_number(&p, ptrend, bracount, MAX_GROUP_NUMBER, ERR61, &s, errorcodeptr)) { if (*errorcodeptr == 0) escape = ESC_k; /* No number found */ @@ -1810,6 +1764,7 @@ else if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET) { + /* not advancing ptr; report error at the \g character */ *errorcodeptr = ERR57; break; } @@ -1820,7 +1775,7 @@ else else { - if (!read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s, + if (!read_number(&ptr, ptrend, bracount, MAX_GROUP_NUMBER, ERR61, &s, errorcodeptr)) { if (*errorcodeptr == 0) *errorcodeptr = ERR57; /* No number found */ @@ -1834,7 +1789,7 @@ else break; } - escape = -s; + escape = -(s+1); break; /* The handling of escape sequences consisting of a string of digits @@ -1846,7 +1801,16 @@ else number is less than 10, or if there are that many previous extracting left brackets, it is a back reference. Otherwise, up to three octal digits are read to form an escaped character code. Thus \123 is likely to be octal 123 - (cf \0123, which is octal 012 followed by the literal 3). + (cf \0123, which is octal 012 followed by the literal 3). This is the "Perl + style" of handling ambiguous octal/backrefences such as \12. + + There is an alternative disambiguation strategy, selected by + PCRE2_EXTRA_PYTHON_OCTAL, which follows Python's behaviour. An octal must + have either a leading zero, or exactly three octal digits; otherwise it's + a backreference. The disambiguation is stable, and does not depend on how + many capture groups are defined (it's simply an invalid backreference if + there is no corresponding capture group). Additionally, octal values above + \377 (\xff) are rejected. Inside a character class, \ followed by a digit is always either a literal 8 or 9 or an octal number. */ @@ -1854,24 +1818,65 @@ else case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: - if (!isclass) + if (isclass) + { + /* Fall through to octal handling; never a backreference inside a class. */ + } + else if ((xoptions & PCRE2_EXTRA_PYTHON_OCTAL) != 0) + { + /* Python-style disambiguation. */ + if (ptr[-1] <= CHAR_7 && ptr + 1 < ptrend && ptr[0] >= CHAR_0 && + ptr[0] <= CHAR_7 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7) + { + /* We peeked a three-digit octal, so fall through */ + } + else + { + /* We are at a digit, so the only possible error from read_number() is + a number that is too large. */ + ptr--; /* Back to the digit */ + + if (!read_number(&ptr, ptrend, -1, MAX_GROUP_NUMBER, 0, &s, errorcodeptr)) + { + *errorcodeptr = ERR61; + break; + } + + escape = -(s+1); + break; + } + } + else { + /* Perl-style disambiguation. */ oldptr = ptr; ptr--; /* Back to the digit */ /* As we know we are at a digit, the only possible error from - read_number() is a number that is too large to be a group number. In this - case we fall through handle this as not a group reference. If we have - read a small enough number, check for a back reference. + read_number() is a number that is too large to be a group number. Because + that number might be still valid if read as an octal, errorcodeptr is not + set on failure and therefore a sentinel value of INT_MAX is used instead + of the original value, and will be used later to properly set the error, + if not falling through. */ + + if (!read_number(&ptr, ptrend, -1, MAX_GROUP_NUMBER, 0, &s, errorcodeptr)) + s = INT_MAX; - \1 to \9 are always back references. \8x and \9x are too; \1x to \7x + /* \1 to \9 are always back references. \8x and \9x are too; \1x to \7x are octal escapes if there are not that many previous captures. */ - if (read_number(&ptr, ptrend, -1, INT_MAX/10 - 1, 0, &s, errorcodeptr) && - (s < 10 || oldptr[-1] >= CHAR_8 || s <= (int)cb->bracount)) + if (s < 10 || c >= CHAR_8 || (unsigned)s <= bracount) { - if (s > (int)MAX_GROUP_NUMBER) *errorcodeptr = ERR61; - else escape = -s; /* Indicates a back reference */ + /* s > MAX_GROUP_NUMBER should not be possible because of read_number(), + but we keep it just to be safe and because it will also catch the + sentinel value that was set on failure by that function. */ + + if ((unsigned)s > MAX_GROUP_NUMBER) + { + PCRE2_ASSERT(s == INT_MAX); + *errorcodeptr = ERR61; + } + else escape = -(s+1); /* Indicates a back reference */ break; } @@ -1890,16 +1895,26 @@ else /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least significant 8 bits of octal numbers (I think this is what early Perls used - to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode, + to do). Nowadays we allow for larger numbers in UTF-8 mode and 16/32-bit mode, but no more than 3 octal digits. */ case CHAR_0: c -= CHAR_0; while(i++ < 2 && ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) c = c * 8 + *ptr++ - CHAR_0; + if (c > 0xff) + { + if ((xoptions & PCRE2_EXTRA_PYTHON_OCTAL) != 0) *errorcodeptr = ERR102; #if PCRE2_CODE_UNIT_WIDTH == 8 - if (!utf && c > 0xff) *errorcodeptr = ERR51; + else if (!utf) *errorcodeptr = ERR51; #endif + } + + /* PCRE2_EXTRA_NO_BS0 disables the NUL escape '\0' but doesn't affect + two- or three-character octal escapes \00 and \000, nor \x00. */ + + if ((xoptions & PCRE2_EXTRA_NO_BS0) != 0 && c == 0 && i == 1) + *errorcodeptr = ERR98; break; /* \o is a relatively new Perl feature, supporting a more general way of @@ -1928,7 +1943,7 @@ else cc = *ptr++; if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ #if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x20000000l) { overflow = TRUE; break; } + if (c >= 0x20000000u) { overflow = TRUE; break; } #endif c = (c << 3) + (cc - CHAR_0); #if PCRE2_CODE_UNIT_WIDTH == 8 @@ -2054,10 +2069,29 @@ else else { - c = 0; - if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */ + /* Perl has the surprising/broken behaviour that \x without following + hex digits is treated as an escape for NUL. Their source code laments + this but keeps it for backwards compatibility. A warning is printed + when "use warnings" is enabled. Because we don't have warnings, we + simply forbid it. */ + if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) + { + /* Not a hex digit */ + *errorcodeptr = ERR78; + break; + } ptr++; c = cc; + + /* With "use re 'strict'" Perl actually requires exactly two digits (error + for \x, \xA and \xAAA). While \x was already rejected, this seems overly + strict, and there seems little incentive to align with that, given the + backwards-compatibility cost. + + For comparison, note that other engines disagree. For example: + - Java allows 1 or 2 hex digits. Error if 0 digits. No error if >2 digits + - .NET requires 2 hex digits. Error if 0, 1 digits. No error if >2 digits. + */ if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */ ptr++; c = (c << 4) | cc; @@ -2179,37 +2213,65 @@ c = *ptr++; *negptr = FALSE; /* \P or \p can be followed by a name in {}, optionally preceded by ^ for -negation. */ +negation. We must be handling Unicode encoding here, though we may be compiling +for UTF-8 input in an EBCDIC environment. (PCRE2 does not support both EBCDIC +input and Unicode input in the same build.) In accordance with Unicode's "loose +matching" rules, ASCII white space, hyphens, and underscores are ignored. We +don't use isspace() or tolower() because (a) code points may be greater than +255, and (b) they wouldn't work when compiling for Unicode in an EBCDIC +environment. */ if (c == CHAR_LEFT_CURLY_BRACKET) { if (ptr >= cb->end_pattern) goto ERROR_RETURN; - if (*ptr == CHAR_CIRCUMFLEX_ACCENT) - { - *negptr = TRUE; - ptr++; - } - for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++) { + REDO: + if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; -#if PCRE2_CODE_UNIT_WIDTH != 8 - while (c == '_' || c == '-' || (c <= 0xff && isspace(c))) -#else - while (c == '_' || c == '-' || isspace(c)) -#endif + + /* Skip ignorable Unicode characters. */ + + while (c == CHAR_UNDERSCORE || c == CHAR_MINUS || c == CHAR_SPACE || + (c >= CHAR_HT && c <= CHAR_CR)) { if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; } - if (c == CHAR_NUL) goto ERROR_RETURN; + + /* The first significant character being circumflex negates the meaning of + the item. */ + + if (i == 0 && !*negptr && c == CHAR_CIRCUMFLEX_ACCENT) + { + *negptr = TRUE; + goto REDO; + } + if (c == CHAR_RIGHT_CURLY_BRACKET) break; - name[i] = tolower(c); - if ((c == ':' || c == '=') && vptr == NULL) vptr = name + i; + + /* Names consist of ASCII letters and digits, but equals and colon may also + occur as a name/value separator. We must also allow for \p{L&}. A simple + check for a value between '&' and 'z' suffices because anything else in a + name or value will cause an "unknown property" error anyway. */ + + if (c < CHAR_AMPERSAND || c > CHAR_z) goto ERROR_RETURN; + + /* Lower case a capital letter or remember where the name/value separator + is. */ + + if (c >= CHAR_A && c <= CHAR_Z) c |= 0x20; + else if ((c == CHAR_COLON || c == CHAR_EQUALS_SIGN) && vptr == NULL) + vptr = name + i; + + name[i] = c; } + /* Error if the loop didn't end with '}' - either we hit the end of the + pattern or the name was longer than any legal property name. */ + if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN; name[i] = 0; } @@ -2217,14 +2279,19 @@ if (c == CHAR_LEFT_CURLY_BRACKET) /* If { doesn't follow \p or \P there is just one following character, which must be an ASCII letter. */ -else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0) +else if (c >= CHAR_A && c <= CHAR_Z) + { + name[0] = c | 0x20; /* Lower case */ + name[1] = 0; + } +else if (c >= CHAR_a && c <= CHAR_z) { - name[0] = tolower(c); + name[0] = c; name[1] = 0; } else goto ERROR_RETURN; -*ptrptr = ptr; +*ptrptr = ptr; /* Update pattern pointer */ /* If the property contains ':' or '=' we have class name and value separately specified. The following are supported: @@ -2482,6 +2549,9 @@ if (ptr >= ptrend) /* No characters in name */ *nameptr = ptr; *offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern); +/* If this logic were ever to change, the matching function in pcre2_substitute.c +ought to be updated to match. */ + /* In UTF mode, a group name may contain letters and decimal digits as defined by Unicode properties, and underscores, but must not start with a digit. */ @@ -2700,6 +2770,60 @@ return parsed_pattern; +/************************************************* +* Maximum size of parsed_pattern for given input * +*************************************************/ + +/* This function is called from parse_regex() below, to determine the amount +of memory to allocate for parsed_pattern. It is also called to check whether +the amount of data written respects the amount of memory allocated. + +Arguments: + ptr points to the start of the pattern + ptrend points to the end of the pattern + utf TRUE in UTF mode + options the options bits + +Returns: the number of uint32_t units for parsed_pattern +*/ +static ptrdiff_t +max_parsed_pattern(PCRE2_SPTR ptr, PCRE2_SPTR ptrend, BOOL utf, + uint32_t options) +{ +PCRE2_SIZE big32count = 0; +ptrdiff_t parsed_size_needed; + +/* When PCRE2_AUTO_CALLOUT is not set, in all but one case the number of +unsigned 32-bit ints written out to the parsed pattern is bounded by the length +of the pattern. The exceptional case is when running in 32-bit, non-UTF mode, +when literal characters greater than META_END (0x80000000) have to be coded as +two units. In this case, therefore, we scan the pattern to check for such +values. */ + +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (!utf) + { + PCRE2_SPTR p; + for (p = ptr; p < ptrend; p++) if (*p >= META_END) big32count++; + } +#else +(void)utf; /* Avoid compiler warning */ +#endif + +parsed_size_needed = (ptrend - ptr) + big32count; + +/* When PCRE2_AUTO_CALLOUT is set we have to assume a numerical callout (4 +elements) for each character. This is overkill, but memory is plentiful these +days. */ + +if ((options & PCRE2_AUTO_CALLOUT) != 0) + parsed_size_needed += (ptrend - ptr) * 4; + +return parsed_size_needed; +} + + + /************************************************* * Parse regex and identify named groups * *************************************************/ @@ -2751,7 +2875,33 @@ the main compiling phase. */ /* States used for analyzing ranges in character classes. The two OK values must be last. */ -enum { RANGE_NO, RANGE_STARTED, RANGE_OK_ESCAPED, RANGE_OK_LITERAL }; +enum { + RANGE_NO, /* State after '[' (initial), or '[a-z'; hyphen is literal */ + RANGE_STARTED, /* State after '[1-'; last-emitted code is META_RANGE_XYZ */ + RANGE_FORBID_NO, /* State after '[\d'; '-]' is allowed but not '-1]' */ + RANGE_FORBID_STARTED, /* State after '[\d-'*/ + RANGE_OK_ESCAPED, /* State after '[\1'; hyphen may be a range */ + RANGE_OK_LITERAL /* State after '[1'; hyphen may be a range */ +}; + +/* States used for analyzing operators and operands in extended character +classes. */ + +enum { + CLASS_OP_EMPTY, /* At start of an expression; empty previous contents */ + CLASS_OP_OPERAND, /* Have preceding operand; after "z" a "--" can follow */ + CLASS_OP_OPERATOR /* Have preceding operator; after "--" operand must follow */ +}; + +/* States used for determining the parse mode in character classes. The two +PERL_EXT values must be last. */ + +enum { + CLASS_MODE_NORMAL, /* Ordinary PCRE2 '[...]' class. */ + CLASS_MODE_ALT_EXT, /* UTS#18-style extended '[...]' class. */ + CLASS_MODE_PERL_EXT, /* Perl extended '(?[...])' class. */ + CLASS_MODE_PERL_EXT_LEAF /* Leaf within extended '(?[ [...] ])' class. */ +}; /* Only in 32-bit mode can there be literals > META_END. A macro encapsulates the storing of literal values in the main parsed pattern, where they can always @@ -2770,13 +2920,16 @@ be quantified. */ /* Here's the actual function. */ -static int parse_regex(PCRE2_SPTR ptr, uint32_t options, BOOL *has_lookbehind, - compile_block *cb) +static int parse_regex(PCRE2_SPTR ptr, uint32_t options, uint32_t xoptions, + BOOL *has_lookbehind, compile_block *cb) { uint32_t c; uint32_t delimiter; uint32_t namelen; uint32_t class_range_state; +uint32_t class_op_state; +uint32_t class_mode_state; +uint32_t *class_start; uint32_t *verblengthptr = NULL; /* Value avoids compiler warning */ uint32_t *verbstartptr = NULL; uint32_t *previous_callout = NULL; @@ -2786,8 +2939,9 @@ uint32_t *this_parsed_item = NULL; uint32_t *prev_parsed_item = NULL; uint32_t meta_quantifier = 0; uint32_t add_after_mark = 0; -uint32_t xoptions = cb->cx->extra_options; uint16_t nest_depth = 0; +int16_t class_depth_m1 = -1; /* The m1 means minus 1. */ +int16_t class_maxdepth_m1 = -1; int after_manual_callout = 0; int expect_cond_assert = 0; int errorcode = 0; @@ -2804,8 +2958,17 @@ PCRE2_SPTR thisptr; PCRE2_SPTR name; PCRE2_SPTR ptrend = cb->end_pattern; PCRE2_SPTR verbnamestart = NULL; /* Value avoids compiler warning */ +PCRE2_SPTR class_range_forbid_ptr = NULL; named_group *ng; nest_save *top_nest, *end_nests; +#ifdef PCRE2_DEBUG +uint32_t *parsed_pattern_check; +ptrdiff_t parsed_pattern_extra = 0; +ptrdiff_t parsed_pattern_extra_check = 0; +PCRE2_SPTR ptr_check; +#endif + +PCRE2_ASSERT(parsed_pattern != NULL); /* Insert leading items for word and line matching (features provided for the benefit of pcre2grep). */ @@ -2821,6 +2984,11 @@ else if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0) *parsed_pattern++ = META_NOCAPTURE; } +#ifdef PCRE2_DEBUG +parsed_pattern_check = parsed_pattern; +ptr_check = ptr; +#endif + /* If the pattern is actually a literal string, process it separately to avoid cluttering up the main loop. */ @@ -2830,6 +2998,7 @@ if ((options & PCRE2_LITERAL) != 0) { if (parsed_pattern >= parsed_pattern_end) { + PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR63; /* Internal error (parsed pattern overflow) */ goto FAILED; } @@ -2873,18 +3042,40 @@ while (ptr < ptrend) PCRE2_SPTR tempptr; PCRE2_SIZE offset; - if (parsed_pattern >= parsed_pattern_end) - { - errorcode = ERR63; /* Internal error (parsed pattern overflow) */ - goto FAILED; - } - if (nest_depth > cb->cx->parens_nest_limit) { errorcode = ERR19; goto FAILED; /* Parentheses too deeply nested */ } + /* Check that we haven't emitted too much into parsed_pattern. We allocate + a suitably-sized buffer upfront, then do unchecked writes to it. If we only + write a little bit too much, everything will appear to be OK, because the + upfront size is an overestimate... but a malicious pattern could end up + forcing a write past the buffer end. We must catch this during + development. */ + +#ifdef PCRE2_DEBUG + /* Strong post-write check. Won't help in release builds - at this point + the write has already occurred so it's too late. However, should stop us + committing unsafe code. */ + PCRE2_ASSERT((parsed_pattern - parsed_pattern_check) + + (parsed_pattern_extra - parsed_pattern_extra_check) <= + max_parsed_pattern(ptr_check, ptr, utf, options)); + parsed_pattern_check = parsed_pattern; + parsed_pattern_extra_check = parsed_pattern_extra; + ptr_check = ptr; +#endif + + if (parsed_pattern >= parsed_pattern_end) + { + /* Weak pre-write check; only ensures parsed_pattern[0] is writeable + (but the code below can write many chars). Better than nothing. */ + PCRE2_DEBUG_UNREACHABLE(); + errorcode = ERR63; /* Internal error (parsed pattern overflow) */ + goto FAILED; + } + /* If the last time round this loop something was added, parsed_pattern will no longer be equal to this_parsed_item. Remember where the previous item started and reset for the next item. Note that sometimes round the loop, @@ -3004,7 +3195,7 @@ while (ptr < ptrend) if ((options & PCRE2_ALT_VERBNAMES) != 0) { escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - xoptions, FALSE, cb); + xoptions, cb->bracount, FALSE, cb); if (errorcode != 0) goto FAILED; } else escape = 0; /* Treat all as literal */ @@ -3204,7 +3395,7 @@ while (ptr < ptrend) case CHAR_BACKSLASH: tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - xoptions, FALSE, cb); + xoptions, cb->bracount, FALSE, cb); if (errorcode != 0) { ESCAPE_FAILED: @@ -3235,7 +3426,7 @@ while (ptr < ptrend) else if (escape < 0) { offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 1); - escape = -escape; + escape = -escape - 1; *parsed_pattern++ = META_BACKREF | (uint32_t)escape; if (escape < 10) { @@ -3347,7 +3538,7 @@ while (ptr < ptrend) /* When \g is used with quotes or angle brackets as delimiters, it is a numerical or named subroutine call, and control comes here. When used - with brace delimiters it is a numberical back reference and does not come + with brace delimiters it is a numerical back reference and does not come here because check_escape() returns it directly as a reference. \k is always a named back reference. */ @@ -3458,7 +3649,7 @@ while (ptr < ptrend) if (!prev_okquantifier) { errorcode = ERR9; - goto FAILED_BACK; + goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549 } /* Most (*VERB)s are not allowed to be quantified, but an ungreedy @@ -3474,6 +3665,11 @@ while (ptr < ptrend) *verbstartptr = META_NOCAPTURE; parsed_pattern[1] = META_KET; parsed_pattern += 2; + +#ifdef PCRE2_DEBUG + PCRE2_ASSERT(parsed_pattern_extra >= 2); + parsed_pattern_extra -= 2; +#endif } /* Now we can put the quantifier into the parsed pattern vector. At this @@ -3493,7 +3689,6 @@ while (ptr < ptrend) /* ---- Character class ---- */ case CHAR_LEFT_SQUARE_BRACKET: - okquantifier = TRUE; /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is used for "start of word" and "end of word". As these are otherwise illegal @@ -3531,6 +3726,7 @@ while (ptr < ptrend) } *parsed_pattern++ = META_KET; ptr += 6; + okquantifier = TRUE; break; } @@ -3545,46 +3741,14 @@ while (ptr < ptrend) goto FAILED; } - /* Process a regular character class. If the first character is '^', set - the negation flag. If the first few characters (either before or after ^) - are \Q\E or \E or space or tab in extended-more mode, we skip them too. - This makes for compatibility with Perl. */ - - negate_class = FALSE; - while (ptr < ptrend) - { - GETCHARINCTEST(c, ptr); - if (c == CHAR_BACKSLASH) - { - if (ptr < ptrend && *ptr == CHAR_E) ptr++; - else if (ptrend - ptr >= 3 && - PRIV(strncmp_c8)(ptr, STR_Q STR_BACKSLASH STR_E, 3) == 0) - ptr += 3; - else - break; - } - else if ((options & PCRE2_EXTENDED_MORE) != 0 && - (c == CHAR_SPACE || c == CHAR_HT)) /* Note: just these two */ - continue; - else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) - negate_class = TRUE; - else break; - } - - /* Now the real contents of the class; c has the first "real" character. - Empty classes are permitted only if the option is set. */ - - if (c == CHAR_RIGHT_SQUARE_BRACKET && - (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0) - { - *parsed_pattern++ = negate_class? META_CLASS_EMPTY_NOT : META_CLASS_EMPTY; - break; /* End of class processing */ - } + class_mode_state = ((options & PCRE2_ALT_EXTENDED_CLASS) != 0)? + CLASS_MODE_ALT_EXT : CLASS_MODE_NORMAL; - /* Process a non-empty class. */ + /* Jump here from '(?[...])'. That jump must initialize class_mode_state, + set c to the '[' character, and ptr to just after the '['. */ - *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS; - class_range_state = RANGE_NO; + FROM_PERL_EXTENDED_CLASS: + okquantifier = TRUE; /* In an EBCDIC environment, Perl treats alphabetic ranges specially because there are holes in the encoding, and simply using the range A-Z @@ -3594,7 +3758,16 @@ while (ptr < ptrend) character values are literal or not, and a state variable for handling ranges. */ - /* Loop for the contents of the class */ + /* Loop for the contents of the class. Classes may be nested, if + PCRE2_ALT_EXTENDED_CLASS is set, or the class is of the form (?[...]). */ + + /* c is still set to '[' so the loop will handle the start of the class. */ + + class_depth_m1 = -1; + class_maxdepth_m1 = -1; + class_range_state = RANGE_NO; + class_op_state = CLASS_OP_EMPTY; + class_start = NULL; for (;;) { @@ -3610,13 +3783,26 @@ while (ptr < ptrend) ptr++; /* Skip the 'E' */ goto CLASS_CONTINUE; } + + /* Surprisingly, you cannot use \Q..\E to escape a character inside a + Perl extended class. However, empty \Q\E sequences are allowed, so here + were're only giving an error if the \Q..\E is non-empty. */ + + if (class_mode_state == CLASS_MODE_PERL_EXT) + { + errorcode = ERR116; + goto FAILED; + } + goto CLASS_LITERAL; } - /* Skip over space and tab (only) in extended-more mode. */ + /* Skip over space and tab (only) in extended-more mode, or anywhere + inside a Perl extended class (which implies /xx). */ - if ((options & PCRE2_EXTENDED_MORE) != 0 && - (c == CHAR_SPACE || c == CHAR_HT)) + if ((c == CHAR_SPACE || c == CHAR_HT) && + ((options & PCRE2_EXTENDED_MORE) != 0 || + class_mode_state >= CLASS_MODE_PERL_EXT)) goto CLASS_CONTINUE; /* Handle POSIX class names. Perl allows a negation extension of the @@ -3625,7 +3811,8 @@ while (ptr < ptrend) [.ch.] and [=ch=] ("collating elements") and fault them, as Perl 5.6 and 5.8 do. */ - if (c == CHAR_LEFT_SQUARE_BRACKET && + if (class_depth_m1 >= 0 && + c == CHAR_LEFT_SQUARE_BRACKET && ptrend - ptr >= 3 && (*ptr == CHAR_COLON || *ptr == CHAR_DOT || *ptr == CHAR_EQUALS_SIGN) && @@ -3641,14 +3828,41 @@ while (ptr < ptrend) if (class_range_state == RANGE_STARTED) { + ptr = tempptr + 2; + errorcode = ERR50; + goto FAILED; + } + + /* Perl treats a hyphen after a POSIX class as a literal, not the + start of a range. However, it gives a warning in its warning mode + unless the hyphen is the last character in the class. PCRE does not + have a warning mode, so we give an error, because this is likely an + error on the user's part. + + Roll back to the hyphen for the error position. */ + + if (class_range_state == RANGE_FORBID_STARTED) + { + ptr = class_range_forbid_ptr; errorcode = ERR50; goto FAILED; } + /* Disallow implicit union in Perl extended classes. */ + + if (class_op_state == CLASS_OP_OPERAND && + class_mode_state == CLASS_MODE_PERL_EXT) + { + ptr = tempptr + 2; + errorcode = ERR113; + goto FAILED; + } + if (*ptr != CHAR_COLON) { + ptr = tempptr + 2; errorcode = ERR13; - goto FAILED_BACK; + goto FAILED; } if (*(++ptr) == CHAR_CIRCUMFLEX_ACCENT) @@ -3658,33 +3872,19 @@ while (ptr < ptrend) } posix_class = check_posix_name(ptr, (int)(tempptr - ptr)); + ptr = tempptr + 2; if (posix_class < 0) { errorcode = ERR30; goto FAILED; } - ptr = tempptr + 2; - - /* Perl treats a hyphen after a POSIX class as a literal, not the - start of a range. However, it gives a warning in its warning mode - unless the hyphen is the last character in the class. PCRE does not - have a warning mode, so we give an error, because this is likely an - error on the user's part. */ - - if (ptr < ptrend - 1 && *ptr == CHAR_MINUS && - ptr[1] != CHAR_RIGHT_SQUARE_BRACKET) - { - errorcode = ERR50; - goto FAILED; - } - /* Set "a hyphen is not the start of a range" for the -] case, and also - in case the POSIX class is followed by \E or \Q\E (possibly repeated - - fuzzers do that kind of thing) and *then* a hyphen. This causes that - hyphen to be treated as a literal. I don't think it's worth setting up - special apparatus to do otherwise. */ + /* Set "a hyphen is forbidden to be the start of a range". For the '-]' + case, the hyphen is treated as a literal, but for '-1' it is disallowed + (because it would be interpreted as range). */ - class_range_state = RANGE_NO; + class_range_state = RANGE_FORBID_NO; + class_op_state = CLASS_OP_OPERAND; /* When PCRE2_UCP is set, unless PCRE2_EXTRA_ASCII_POSIX is set, some of the POSIX classes are converted to use Unicode properties \p or \P @@ -3727,56 +3927,344 @@ while (ptr < ptrend) *parsed_pattern++ = posix_class; } - /* Handle potential start of range */ + /* Check for the start of the outermost class, or the start of a nested class. */ - else if (c == CHAR_MINUS && class_range_state >= RANGE_OK_ESCAPED) + else if ((c == CHAR_LEFT_SQUARE_BRACKET && + (class_depth_m1 < 0 || class_mode_state == CLASS_MODE_ALT_EXT || + class_mode_state == CLASS_MODE_PERL_EXT)) || + (c == CHAR_LEFT_PARENTHESIS && + class_mode_state == CLASS_MODE_PERL_EXT)) { - *parsed_pattern++ = (class_range_state == RANGE_OK_LITERAL)? - META_RANGE_LITERAL : META_RANGE_ESCAPED; - class_range_state = RANGE_STARTED; - } + uint32_t start_c = c; + uint32_t new_class_mode_state; - /* Handle a literal character */ + /* Update the class mode, if moving into a 'leaf' inside a Perl extended + class. */ + + if (start_c == CHAR_LEFT_SQUARE_BRACKET && + class_mode_state == CLASS_MODE_PERL_EXT && class_depth_m1 >= 0) + new_class_mode_state = CLASS_MODE_PERL_EXT_LEAF; + else + new_class_mode_state = class_mode_state; + + /* Tidy up the other class before starting the nested class. */ + /* -[ beginning a nested class is a literal '-' */ - else if (c != CHAR_BACKSLASH) - { - CLASS_LITERAL: if (class_range_state == RANGE_STARTED) + parsed_pattern[-1] = CHAR_MINUS; + + /* Disallow implicit union in Perl extended classes. */ + + if (class_op_state == CLASS_OP_OPERAND && + class_mode_state == CLASS_MODE_PERL_EXT) { - if (c == parsed_pattern[-2]) /* Optimize one-char range */ - parsed_pattern--; - else if (parsed_pattern[-2] > c) /* Check range is in order */ + errorcode = ERR113; + goto FAILED; + } + + /* Validate nesting depth */ + if (class_depth_m1 >= ECLASS_NEST_LIMIT - 1) + { + errorcode = ERR107; + goto FAILED; /* Classes too deeply nested */ + } + + /* Process the character class start. If the first character is '^', set + the negation flag. If the first few characters (either before or after ^) + are \Q\E or \E or space or tab in extended-more mode, we skip them too. + This makes for compatibility with Perl. */ + + negate_class = FALSE; + for (;;) + { + if (ptr >= ptrend) { - errorcode = ERR8; - goto FAILED_BACK; + if (start_c == CHAR_LEFT_PARENTHESIS) + errorcode = ERR14; /* Missing terminating ')' */ + else + errorcode = ERR6; /* Missing terminating ']' */ + goto FAILED; } - else + + GETCHARINCTEST(c, ptr); + if (new_class_mode_state == CLASS_MODE_PERL_EXT) break; + else if (c == CHAR_BACKSLASH) { - if (!char_is_literal && parsed_pattern[-1] == META_RANGE_LITERAL) - parsed_pattern[-1] = META_RANGE_ESCAPED; - PARSED_LITERAL(c, parsed_pattern); + if (ptr < ptrend && *ptr == CHAR_E) ptr++; + else if (ptrend - ptr >= 3 && + PRIV(strncmp_c8)(ptr, STR_Q STR_BACKSLASH STR_E, 3) == 0) + ptr += 3; + else + break; } - class_range_state = RANGE_NO; + else if ((c == CHAR_SPACE || c == CHAR_HT) && /* Note: just these two */ + ((options & PCRE2_EXTENDED_MORE) != 0 || + new_class_mode_state >= CLASS_MODE_PERL_EXT)) + continue; + else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) + negate_class = TRUE; + else break; } - else /* Potential start of range */ + + /* Now the real contents of the class; c has the first "real" character. + Empty classes are permitted only if the option is set, and if it's not + a Perl-extended class. */ + + if (c == CHAR_RIGHT_SQUARE_BRACKET && + (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0 && + new_class_mode_state < CLASS_MODE_PERL_EXT) { - class_range_state = char_is_literal? - RANGE_OK_LITERAL : RANGE_OK_ESCAPED; + PCRE2_ASSERT(start_c == CHAR_LEFT_SQUARE_BRACKET); + + if (class_start != NULL) + { + PCRE2_ASSERT(class_depth_m1 >= 0); + /* Represents that the class is an extended class. */ + *class_start |= CLASS_IS_ECLASS; + class_start = NULL; + } + + *parsed_pattern++ = negate_class? META_CLASS_EMPTY_NOT : META_CLASS_EMPTY; + + /* Leave nesting depth unchanged; but check for zero depth to handle the + very first (top-level) class being empty. */ + if (class_depth_m1 < 0) break; + + class_range_state = RANGE_NO; /* for processing the containing class */ + class_op_state = CLASS_OP_OPERAND; + goto CLASS_CONTINUE; + } + + /* Enter a non-empty class. */ + + if (class_start != NULL) + { + PCRE2_ASSERT(class_depth_m1 >= 0); + /* Represents that the class is an extended class. */ + *class_start |= CLASS_IS_ECLASS; + class_start = NULL; + } + + class_start = parsed_pattern; + *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS; + class_range_state = RANGE_NO; + class_op_state = CLASS_OP_EMPTY; + class_mode_state = new_class_mode_state; + ++class_depth_m1; + if (class_maxdepth_m1 < class_depth_m1) + class_maxdepth_m1 = class_depth_m1; + /* Reset; no op seen yet at new depth. */ + cb->class_op_used[class_depth_m1] = 0; + + /* Implement the special start-of-class literal meaning of ']'. */ + if (c == CHAR_RIGHT_SQUARE_BRACKET && + new_class_mode_state != CLASS_MODE_PERL_EXT) + { + class_range_state = RANGE_OK_LITERAL; + class_op_state = CLASS_OP_OPERAND; PARSED_LITERAL(c, parsed_pattern); + goto CLASS_CONTINUE; + } + + continue; /* We have already loaded c with the next character */ + } + + /* Check for the end of the class. */ + + else if (c == CHAR_RIGHT_SQUARE_BRACKET || + (c == CHAR_RIGHT_PARENTHESIS && class_mode_state == CLASS_MODE_PERL_EXT)) + { + /* In Perl extended mode, the ']' can only be used to match the + opening '[', and ')' must match an opening parenthesis. */ + if (class_mode_state == CLASS_MODE_PERL_EXT) + { + if (c == CHAR_RIGHT_SQUARE_BRACKET && class_depth_m1 != 0) + { + errorcode = ERR14; + goto FAILED_BACK; + } + if (c == CHAR_RIGHT_PARENTHESIS && class_depth_m1 < 1) + { + errorcode = ERR22; + goto FAILED; + } + } + + /* Check no trailing operator. */ + if (class_op_state == CLASS_OP_OPERATOR) + { + errorcode = ERR110; + goto FAILED; + } + + /* Check no empty expression for Perl extended expressions. */ + if (class_mode_state == CLASS_MODE_PERL_EXT && + class_op_state == CLASS_OP_EMPTY) + { + errorcode = ERR114; + goto FAILED; + } + + /* -] at the end of a class is a literal '-' */ + if (class_range_state == RANGE_STARTED) + parsed_pattern[-1] = CHAR_MINUS; + + *parsed_pattern++ = META_CLASS_END; + + if (--class_depth_m1 < 0) + { + /* Check for and consume ')' after '(?[...]'. */ + PCRE2_ASSERT(class_mode_state != CLASS_MODE_PERL_EXT_LEAF); + if (class_mode_state == CLASS_MODE_PERL_EXT) + { + if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS) + { + errorcode = ERR115; + goto FAILED; + } + + ptr++; + } + + break; + } + + class_range_state = RANGE_NO; /* for processing the containing class */ + class_op_state = CLASS_OP_OPERAND; + if (class_mode_state == CLASS_MODE_PERL_EXT_LEAF) + class_mode_state = CLASS_MODE_PERL_EXT; + /* The extended class flag has already + been set for the parent class. */ + class_start = NULL; + } + + /* Handle a Perl set binary operator */ + + else if (class_mode_state == CLASS_MODE_PERL_EXT && + (c == CHAR_PLUS || c == CHAR_VERTICAL_LINE || c == CHAR_MINUS || + c == CHAR_AMPERSAND || c == CHAR_CIRCUMFLEX_ACCENT)) + { + /* Check that there was a preceding operand. */ + if (class_op_state != CLASS_OP_OPERAND) + { + errorcode = ERR109; + goto FAILED; + } + + if (class_start != NULL) + { + PCRE2_ASSERT(class_depth_m1 >= 0); + /* Represents that the class is an extended class. */ + *class_start |= CLASS_IS_ECLASS; + class_start = NULL; + } + + PCRE2_ASSERT(class_range_state != RANGE_STARTED && + class_range_state != RANGE_FORBID_STARTED); + + *parsed_pattern++ = c == CHAR_PLUS? META_ECLASS_OR : + c == CHAR_VERTICAL_LINE? META_ECLASS_OR : + c == CHAR_MINUS? META_ECLASS_SUB : + c == CHAR_AMPERSAND? META_ECLASS_AND : + META_ECLASS_XOR; + class_range_state = RANGE_NO; + class_op_state = CLASS_OP_OPERATOR; + } + + /* Handle a Perl set unary operator */ + + else if (class_mode_state == CLASS_MODE_PERL_EXT && + c == CHAR_EXCLAMATION_MARK) + { + /* Check that the "!" has not got a preceding operand (i.e. it's the + start of the class, or follows an operator). */ + if (class_op_state == CLASS_OP_OPERAND) + { + errorcode = ERR113; + goto FAILED; + } + + if (class_start != NULL) + { + PCRE2_ASSERT(class_depth_m1 >= 0); + /* Represents that the class is an extended class. */ + *class_start |= CLASS_IS_ECLASS; + class_start = NULL; + } + + PCRE2_ASSERT(class_range_state != RANGE_STARTED && + class_range_state != RANGE_FORBID_STARTED); + + *parsed_pattern++ = META_ECLASS_NOT; + class_range_state = RANGE_NO; + class_op_state = CLASS_OP_OPERATOR; + } + + /* Handle a UTS#18 set operator */ + + else if (class_mode_state == CLASS_MODE_ALT_EXT && + (c == CHAR_VERTICAL_LINE || c == CHAR_MINUS || + c == CHAR_AMPERSAND || c == CHAR_TILDE) && + ptr < ptrend && *ptr == c) + { + ++ptr; + + /* Check there isn't a triple-repetition. */ + if (ptr < ptrend && *ptr == c) + { + while (ptr < ptrend && *ptr == c) ++ptr; /* Improve error offset. */ + errorcode = ERR108; + goto FAILED; + } + + /* Check for a preceding operand. */ + if (class_op_state != CLASS_OP_OPERAND) + { + errorcode = ERR109; + goto FAILED; + } + + /* Check for mixed precedence. Forbid [A--B&&C]. */ + if (cb->class_op_used[class_depth_m1] != 0 && + cb->class_op_used[class_depth_m1] != (uint8_t)c) + { + errorcode = ERR111; + goto FAILED; } + + if (class_start != NULL) + { + PCRE2_ASSERT(class_depth_m1 >= 0); + /* Represents that the class is an extended class. */ + *class_start |= CLASS_IS_ECLASS; + class_start = NULL; + } + + /* Dangling '-' before an operator is a literal */ + if (class_range_state == RANGE_STARTED) + parsed_pattern[-1] = CHAR_MINUS; + + *parsed_pattern++ = c == CHAR_VERTICAL_LINE? META_ECLASS_OR : + c == CHAR_MINUS? META_ECLASS_SUB : + c == CHAR_AMPERSAND? META_ECLASS_AND : + META_ECLASS_XOR; + class_range_state = RANGE_NO; + class_op_state = CLASS_OP_OPERATOR; + cb->class_op_used[class_depth_m1] = (uint8_t)c; } /* Handle escapes in a class */ - else + else if (c == CHAR_BACKSLASH) { tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - xoptions, TRUE, cb); + xoptions, cb->bracount, TRUE, cb); if (errorcode != 0) { - if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) + if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0 || + class_mode_state >= CLASS_MODE_PERL_EXT) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -3797,6 +4285,11 @@ while (ptr < ptrend) char_is_literal = FALSE; goto CLASS_LITERAL; + case ESC_k: + c = CHAR_k; /* \k is not special in a class, just like \g */ + char_is_literal = FALSE; + goto CLASS_LITERAL; + case ESC_Q: inescq = TRUE; /* Enter literal mode */ goto CLASS_CONTINUE; @@ -3808,29 +4301,10 @@ while (ptr < ptrend) case ESC_R: case ESC_X: errorcode = ERR7; - ptr--; + ptr--; // TODO https://github.com/PCRE2Project/pcre2/issues/549 goto FAILED; - } - - /* The second part of a range can be a single-character escape - sequence (detected above), but not any of the other escapes. Perl - treats a hyphen as a literal in such circumstances. However, in Perl's - warning mode, a warning is given, so PCRE now faults it, as it is - almost certainly a mistake on the user's part. */ - - if (class_range_state == RANGE_STARTED) - { - errorcode = ERR50; - goto FAILED; /* Not CLASS_ESCAPE_FAILED; always an error */ - } - - /* Of the remaining escapes, only those that define characters are - allowed in a class. None may start a range. */ - class_range_state = RANGE_NO; - switch(escape) - { - case ESC_N: + case ESC_N: /* Not permitted by Perl either */ errorcode = ERR71; goto FAILED; @@ -3864,6 +4338,18 @@ while (ptr < ptrend) uint16_t ptype = 0, pdata = 0; if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb)) goto FAILED; + + /* In caseless matching, particular characteristics Lu, Ll, and Lt + get converted to the general characteristic L&. That is, upper, + lower, and title case letters are all conflated. */ + + if ((options & PCRE2_CASELESS) != 0 && ptype == PT_PC && + (pdata == ucp_Lu || pdata == ucp_Ll || pdata == ucp_Lt)) + { + ptype = PT_LAMP; + pdata = 0; + } + if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P; *parsed_pattern++ = META_ESCAPE + escape; *parsed_pattern++ = (ptype << 16) | pdata; @@ -3874,21 +4360,134 @@ while (ptr < ptrend) #endif break; /* End \P and \p */ - default: /* All others are not allowed in a class */ + /* All others are not allowed in a class */ + + default: + PCRE2_DEBUG_UNREACHABLE(); + /* Fall through */ + + case ESC_A: + case ESC_Z: + case ESC_z: + case ESC_G: + case ESC_K: + case ESC_C: errorcode = ERR7; - ptr--; + ptr--; // TODO https://github.com/PCRE2Project/pcre2/issues/549 + goto FAILED; + } + + /* All the switch-cases above which end in "break" describe a set + of characters. None may start a range. */ + + /* The second part of a range can be a single-character escape + sequence (detected above), but not any of the other escapes. Perl + treats a hyphen as a literal in such circumstances. However, in Perl's + warning mode, a warning is given, so PCRE now faults it, as it is + almost certainly a mistake on the user's part. */ + + if (class_range_state == RANGE_STARTED) + { + errorcode = ERR50; + goto FAILED; + } + + /* Perl gives a warning unless the hyphen following a multi-character + escape is the last character in the class. PCRE throws an error. */ + + if (class_range_state == RANGE_FORBID_STARTED) + { + ptr = class_range_forbid_ptr; + errorcode = ERR50; + goto FAILED; + } + + /* Disallow implicit union in Perl extended classes. */ + + if (class_op_state == CLASS_OP_OPERAND && + class_mode_state == CLASS_MODE_PERL_EXT) + { + errorcode = ERR113; goto FAILED; } - /* Perl gives a warning unless a following hyphen is the last character - in the class. PCRE throws an error. */ + class_range_state = RANGE_FORBID_NO; + class_op_state = CLASS_OP_OPERAND; + } + + /* Forbid unescaped literals, and the special meaning of '-', inside a + Perl extended class. */ + + else if (class_mode_state == CLASS_MODE_PERL_EXT) + { + errorcode = ERR116; + goto FAILED; + } + + /* Handle potential start of range */ + + else if (c == CHAR_MINUS && class_range_state >= RANGE_OK_ESCAPED) + { + *parsed_pattern++ = (class_range_state == RANGE_OK_LITERAL)? + META_RANGE_LITERAL : META_RANGE_ESCAPED; + class_range_state = RANGE_STARTED; + } + + /* Handle forbidden start of range */ + + else if (c == CHAR_MINUS && class_range_state == RANGE_FORBID_NO) + { + *parsed_pattern++ = CHAR_MINUS; + class_range_state = RANGE_FORBID_STARTED; + class_range_forbid_ptr = ptr; + } + + /* Handle a literal character */ + + else + { + CLASS_LITERAL: + + /* Disallow implicit union in Perl extended classes. */ - if (ptr < ptrend - 1 && *ptr == CHAR_MINUS && - ptr[1] != CHAR_RIGHT_SQUARE_BRACKET) + if (class_op_state == CLASS_OP_OPERAND && + class_mode_state == CLASS_MODE_PERL_EXT) + { + errorcode = ERR113; + goto FAILED; + } + + if (class_range_state == RANGE_STARTED) + { + if (c == parsed_pattern[-2]) /* Optimize one-char range */ + parsed_pattern--; + else if (parsed_pattern[-2] > c) /* Check range is in order */ + { + errorcode = ERR8; + goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549 + } + else + { + if (!char_is_literal && parsed_pattern[-1] == META_RANGE_LITERAL) + parsed_pattern[-1] = META_RANGE_ESCAPED; + PARSED_LITERAL(c, parsed_pattern); + } + class_range_state = RANGE_NO; + class_op_state = CLASS_OP_OPERAND; + } + else if (class_range_state == RANGE_FORBID_STARTED) { + ptr = class_range_forbid_ptr; errorcode = ERR50; goto FAILED; } + else /* Potential start of range */ + { + class_range_state = char_is_literal? + RANGE_OK_LITERAL : RANGE_OK_ESCAPED; + class_op_state = CLASS_OP_OPERAND; + PARSED_LITERAL(c, parsed_pattern); + } } /* Proceed to next thing in the class. */ @@ -3896,22 +4495,18 @@ while (ptr < ptrend) CLASS_CONTINUE: if (ptr >= ptrend) { - errorcode = ERR6; /* Missing terminating ']' */ + if (class_mode_state == CLASS_MODE_PERL_EXT && class_depth_m1 > 0) + errorcode = ERR14; /* Missing terminating ')' */ + if (class_mode_state == CLASS_MODE_ALT_EXT && + class_depth_m1 == 0 && class_maxdepth_m1 == 1) + errorcode = ERR112; /* Missing terminating ']', but we saw '[ [ ]...' */ + else + errorcode = ERR6; /* Missing terminating ']' */ goto FAILED; } GETCHARINCTEST(c, ptr); - if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break; } /* End of class-processing loop */ - /* -] at the end of a class is a literal '-' */ - - if (class_range_state == RANGE_STARTED) - { - parsed_pattern[-1] = CHAR_MINUS; - class_range_state = RANGE_NO; - } - - *parsed_pattern++ = META_CLASS_END; break; /* End of character class */ @@ -3994,8 +4589,7 @@ while (ptr < ptrend) if (prev_expect_cond_assert > 0 && (meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT)) { - errorcode = (meta == META_LOOKAHEAD_NA || meta == META_LOOKBEHIND_NA)? - ERR98 : ERR28; /* (Atomic) assertion expected */ + errorcode = ERR28; /* Atomic assertion expected */ goto FAILED; } @@ -4005,6 +4599,7 @@ while (ptr < ptrend) switch(meta) { default: + PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR89; /* Unknown code; should never occur because */ goto FAILED; /* the meta values come from a table above. */ @@ -4020,6 +4615,90 @@ while (ptr < ptrend) case META_LOOKAHEADNOT: goto NEGATIVE_LOOK_AHEAD; + case META_SCS: + if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS; + + if (*ptr != CHAR_LEFT_PARENTHESIS) + { + errorcode = ERR15; + goto FAILED; + } + + ptr++; + *parsed_pattern++ = META_SCS; + /* Temporary variable, zero in the first iteration. */ + offset = 0; + + for (;;) + { + PCRE2_SIZE next_offset = (PCRE2_SIZE)(ptr - cb->start_pattern); + + /* Handle (scan_substring:([+-]number)... */ + if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, + &i, &errorcode)) + { + PCRE2_ASSERT(i >= 0); + if (i <= 0) + { + errorcode = ERR15; + goto FAILED; + } + meta = META_SCS_NUMBER; + namelen = (uint32_t)i; + } + else if (errorcode != 0) goto FAILED; /* Number too big */ + else + { + if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS; + + /* Handle (*scan_substring:('name') or (*scan_substring:() */ + if (*ptr == CHAR_LESS_THAN_SIGN) + terminator = CHAR_GREATER_THAN_SIGN; + else if (*ptr == CHAR_APOSTROPHE) + terminator = CHAR_APOSTROPHE; + else + { + errorcode = ERR15; + goto FAILED; + } + + if (!read_name(&ptr, ptrend, utf, terminator, &next_offset, + &name, &namelen, &errorcode, cb)) goto FAILED; + + meta = META_SCS_NAME; + } + + PCRE2_ASSERT(next_offset > 0); + if (offset == 0 || (next_offset - offset) >= 0x10000) + { + *parsed_pattern++ = META_OFFSET; + PUTOFFSET(next_offset, parsed_pattern); + offset = next_offset; + } + + /* The offset is encoded as a relative offset, because for some + inputs such as ",2" in (*scs:(1,2,3)...), we only have space for + two uint32_t values, and an opcode and absolute offset may require + three uint32_t values. */ + *parsed_pattern++ = meta | (uint32_t)(next_offset - offset); + *parsed_pattern++ = namelen; + offset = next_offset; + + if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS; + + if (*ptr == CHAR_RIGHT_PARENTHESIS) break; + + if (*ptr != CHAR_COMMA) + { + errorcode = ERR24; + goto FAILED; + } + + ptr++; + } + ptr++; + goto POST_ASSERTION; + case META_LOOKBEHIND: case META_LOOKBEHINDNOT: case META_LOOKBEHIND_NA: @@ -4051,6 +4730,12 @@ while (ptr < ptrend) top_nest->flags = NSF_ATOMICSR; top_nest->options = options & PARSE_TRACKED_OPTIONS; top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; + +#ifdef PCRE2_DEBUG + /* We'll write out two META_KETs for a single ")" in the input + pattern, so we reserve space for that in our bounds check. */ + parsed_pattern_extra++; +#endif } break; #else /* SUPPORT_UNICODE */ @@ -4110,6 +4795,11 @@ while (ptr < ptrend) verbstartptr = parsed_pattern; okquantifier = (verbs[i].meta == META_ACCEPT); +#ifdef PCRE2_DEBUG + /* Reserve space in our bounds check for optionally wrapping the (*ACCEPT) + with a non-capturing bracket, if there is a following quantifier. */ + if (okquantifier) parsed_pattern_extra += 2; +#endif /* It appears that Perl allows any characters whatsoever, other than a closing parenthesis, to appear in arguments ("names"), so we no longer @@ -4417,11 +5107,7 @@ while (ptr < ptrend) (IS_DIGIT(*ptr))? -1:(int)(cb->bracount), /* + and - are relative */ MAX_GROUP_NUMBER, ERR61, &i, &errorcode)) goto FAILED; - if (i < 0) /* NB (?0) is permitted */ - { - errorcode = ERR15; /* Unknown group */ - goto FAILED_BACK; - } + PCRE2_ASSERT(i >= 0); /* NB (?0) is permitted, represented by i=0 */ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS) goto UNCLOSED_PARENTHESIS; @@ -4449,6 +5135,12 @@ while (ptr < ptrend) /* ---- Callout with numerical or string argument ---- */ case CHAR_C: + if ((xoptions & PCRE2_EXTRA_NEVER_CALLOUT) != 0) + { + errorcode = ERR103; + goto FAILED; + } + if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS; /* If the previous item was a condition starting (?(? an assertion, @@ -4536,7 +5228,7 @@ while (ptr < ptrend) parsed_pattern += 3; /* Skip pattern info */ while (ptr < ptrend && IS_DIGIT(*ptr)) { - n = n * 10 + *ptr++ - CHAR_0; + n = n * 10 + (*ptr++ - CHAR_0); if (n > 255) { errorcode = ERR38; @@ -4607,6 +5299,7 @@ while (ptr < ptrend) if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i, &errorcode)) { + PCRE2_ASSERT(i >= 0); if (i <= 0) { errorcode = ERR15; @@ -4757,7 +5450,7 @@ while (ptr < ptrend) goto POST_ASSERTION; case CHAR_ASTERISK: - POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (?* */ + POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (*napla: */ *parsed_pattern++ = META_LOOKAHEAD_NA; ptr++; goto POST_ASSERTION; @@ -4922,6 +5615,18 @@ while (ptr < ptrend) cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname; cb->names_found++; break; + + + /* ---- Perl extended character class ---- */ + + /* These are of the form '(?[...])'. We handle these via the same parser + that consumes ordinary '[...]' classes, but with a flag set to activate + the extended behaviour. */ + + case CHAR_LEFT_SQUARE_BRACKET: + class_mode_state = CLASS_MODE_PERL_EXT; + c = *ptr++; + goto FROM_PERL_EXTENDED_CLASS; } /* End of (? switch */ break; /* End of ( handling */ @@ -4960,6 +5665,11 @@ while (ptr < ptrend) if ((top_nest->flags & NSF_ATOMICSR) != 0) { *parsed_pattern++ = META_KET; + +#ifdef PCRE2_DEBUG + PCRE2_ASSERT(parsed_pattern_extra > 0); + parsed_pattern_extra--; +#endif } if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL; @@ -4968,7 +5678,7 @@ while (ptr < ptrend) if (nest_depth == 0) /* Unmatched closing parenthesis */ { errorcode = ERR22; - goto FAILED_BACK; + goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549 } nest_depth--; *parsed_pattern++ = META_KET; @@ -4984,9 +5694,15 @@ if (inverbname && ptr >= ptrend) goto FAILED; } -/* Manage callout for the final item */ PARSED_END: + +PCRE2_ASSERT((parsed_pattern - parsed_pattern_check) + + (parsed_pattern_extra - parsed_pattern_extra_check) <= + max_parsed_pattern(ptr_check, ptr, utf, options)); + +/* Manage callout for the final item */ + parsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout, parsed_pattern, cb); @@ -5009,6 +5725,7 @@ Otherwise we have unclosed parentheses. */ if (parsed_pattern >= parsed_pattern_end) { + PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR63; /* Internal error (parsed pattern overflow) */ goto FAILED; } @@ -5114,419 +5831,12 @@ for (;;) code += code[1] + PRIV(OP_lengths)[*code]; break; - default: - return code; - } - } -/* Control never reaches here */ -} - - - -#ifdef SUPPORT_UNICODE -/************************************************* -* Get othercase range * -*************************************************/ - -/* This function is passed the start and end of a class range in UCP mode. For -single characters the range may be just one character long. The function -searches up the characters, looking for ranges of characters in the "other" -case. Each call returns the next one, updating the start address. A character -with multiple other cases is returned on its own with a special return value. - -Arguments: - cptr points to starting character value; updated - d end value - ocptr where to put start of othercase range - odptr where to put end of othercase range - restricted TRUE if caseless restriction applies - -Yield: -1 when no more - 0 when a range is returned - >0 the CASESET offset for char with multiple other cases; - for this return, *ocptr contains the original -*/ - -static int -get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr, - uint32_t *odptr, BOOL restricted) -{ -uint32_t c, othercase, next; -unsigned int co; - -/* Find the first character that has an other case. If it has multiple other -cases, return its case offset value. When CASELESS_RESTRICT is set, ignore the -multi-case entries that begin with ASCII values. In 32-bit mode, a value -greater than the Unicode maximum ends the range. */ - -for (c = *cptr; c <= d; c++) - { -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (c > MAX_UTF_CODE_POINT) return -1; -#endif - if ((co = UCD_CASESET(c)) != 0 && - (!restricted || PRIV(ucd_caseless_sets)[co] > 127)) - { - *ocptr = c++; /* Character that has the set */ - *cptr = c; /* Rest of input range */ - return (int)co; - } - - /* This is not a valid multiple-case character. Check that the single other - case is different to the original. We don't need to check "restricted" here - because the non-ASCII characters with multiple cases that include an ASCII - character don't have a different "othercase". */ - - if ((othercase = UCD_OTHERCASE(c)) != c) break; - } - -if (c > d) return -1; /* Reached end of range */ - -/* Found a character that has a single other case. Search for the end of the -range, which is either the end of the input range, or a character that has zero -or more than one other cases. */ - -*ocptr = othercase; -next = othercase + 1; - -for (++c; c <= d; c++) - { - if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break; - next++; - } - -*odptr = next - 1; /* End of othercase range */ -*cptr = c; /* Rest of input range */ -return 0; -} -#endif /* SUPPORT_UNICODE */ - - - -/************************************************* -* Add a character or range to a class (internal) * -*************************************************/ - -/* This function packages up the logic of adding a character or range of -characters to a class. The character values in the arguments will be within the -valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is -called only from within the "add to class" group of functions, some of which -are recursive and mutually recursive. The external entry point is -add_to_class(). - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options bits - xoptions the extra options bits - cb compile data - start start of range character - end end of range character - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static unsigned int -add_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, uint32_t xoptions, compile_block *cb, uint32_t start, - uint32_t end) -{ -uint32_t c; -uint32_t classbits_end = (end <= 0xff ? end : 0xff); -unsigned int n8 = 0; - -/* If caseless matching is required, scan the range and process alternate -cases. In Unicode, there are 8-bit characters that have alternate cases that -are greater than 255 and vice-versa (though these may be ignored if caseless -restriction is in force). Sometimes we can just extend the original range. */ - -if ((options & PCRE2_CASELESS) != 0) - { -#ifdef SUPPORT_UNICODE - if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0) - { - int rc; - uint32_t oc, od; - - options &= ~PCRE2_CASELESS; /* Remove for recursive calls */ - c = start; - - while ((rc = get_othercase_range(&c, end, &oc, &od, - (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)) >= 0) - { - /* Handle a single character that has more than one other case. */ - - if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, - options, xoptions, cb, PRIV(ucd_caseless_sets) + rc, oc); - - /* Do nothing if the other case range is within the original range. */ - - else if (oc >= cb->class_range_start && od <= cb->class_range_end) - continue; - - /* Extend the original range if there is overlap, noting that if oc < c, - we can't have od > end because a subrange is always shorter than the - basic range. Otherwise, use a recursive call to add the additional range. - */ - - else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ - else if (od > end && oc <= end + 1) - { - end = od; /* Extend upwards */ - if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff); - } - else n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, - cb, oc, od); - } - } - else -#else - (void)xoptions; /* Avoid compiler warning */ -#endif /* SUPPORT_UNICODE */ - - /* Not UTF mode */ - - for (c = start; c <= classbits_end; c++) - { - SETBIT(classbits, cb->fcc[c]); - n8++; - } - } - -/* Now handle the originally supplied range. Adjust the final value according -to the bit length - this means that the same lists of (e.g.) horizontal spaces -can be used in all cases. */ - -if ((options & PCRE2_UTF) == 0 && end > MAX_NON_UTF_CHAR) - end = MAX_NON_UTF_CHAR; - -if (start > cb->class_range_start && end < cb->class_range_end) return n8; - -/* Use the bitmap for characters < 256. Otherwise use extra data.*/ - -for (c = start; c <= classbits_end; c++) - { - /* Regardless of start, c will always be <= 255. */ - SETBIT(classbits, c); - n8++; - } - -#ifdef SUPPORT_WIDE_CHARS -if (start <= 0xff) start = 0xff + 1; - -if (end >= start) - { - PCRE2_UCHAR *uchardata = *uchardptr; - -#ifdef SUPPORT_UNICODE - if ((options & PCRE2_UTF) != 0) - { - if (start < end) - { - *uchardata++ = XCL_RANGE; - uchardata += PRIV(ord2utf)(start, uchardata); - uchardata += PRIV(ord2utf)(end, uchardata); - } - else if (start == end) - { - *uchardata++ = XCL_SINGLE; - uchardata += PRIV(ord2utf)(start, uchardata); - } - } - else -#endif /* SUPPORT_UNICODE */ - - /* Without UTF support, character values are constrained by the bit length, - and can only be > 256 for 16-bit and 32-bit libraries. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 - {} -#else - if (start < end) - { - *uchardata++ = XCL_RANGE; - *uchardata++ = start; - *uchardata++ = end; - } - else if (start == end) - { - *uchardata++ = XCL_SINGLE; - *uchardata++ = start; - } -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - *uchardptr = uchardata; /* Updata extra data pointer */ - } -#else /* SUPPORT_WIDE_CHARS */ - (void)uchardptr; /* Avoid compiler warning */ -#endif /* SUPPORT_WIDE_CHARS */ - -return n8; /* Number of 8-bit characters */ -} - - - -#ifdef SUPPORT_UNICODE -/************************************************* -* Add a list of characters to a class (internal) * -*************************************************/ - -/* This function is used for adding a list of case-equivalent characters to a -class when in UTF mode. This function is called only from within -add_to_class_internal(), with which it is mutually recursive. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options bits - xoptions the extra options bits - cb contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - except character to omit; this is used when adding lists of - case-equivalent characters to avoid including the one we - already know about - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static unsigned int -add_list_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p, - unsigned int except) -{ -unsigned int n8 = 0; -while (p[0] < NOTACHAR) - { - unsigned int n = 0; - if (p[0] != except) - { - while(p[n+1] == p[0] + n + 1) n++; - n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, - p[0], p[n]); - } - p += n + 1; - } -return n8; -} -#endif - - - -/************************************************* -* External entry point for add range to class * -*************************************************/ - -/* This function sets the overall range so that the internal functions can try -to avoid duplication when handling case-independence. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options bits - xoptions the extra options bits - cb compile data - start start of range character - end end of range character - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static unsigned int -add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - uint32_t xoptions, compile_block *cb, uint32_t start, uint32_t end) -{ -cb->class_range_start = start; -cb->class_range_end = end; -return add_to_class_internal(classbits, uchardptr, options, xoptions, cb, - start, end); -} - - -/************************************************* -* External entry point for add list to class * -*************************************************/ - -/* This function is used for adding a list of horizontal or vertical whitespace -characters to a class. The list must be in order so that ranges of characters -can be detected and handled appropriately. This function sets the overall range -so that the internal functions can try to avoid duplication when handling -case-independence. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options bits - xoptions the extra options bits - cb contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - except character to omit; this is used when adding lists of - case-equivalent characters to avoid including the one we - already know about - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static unsigned int -add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - uint32_t xoptions, compile_block *cb, const uint32_t *p, unsigned int except) -{ -unsigned int n8 = 0; -while (p[0] < NOTACHAR) - { - unsigned int n = 0; - if (p[0] != except) - { - while(p[n+1] == p[0] + n + 1) n++; - cb->class_range_start = p[0]; - cb->class_range_end = p[n]; - n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, - p[0], p[n]); + default: + return code; } - p += n + 1; } -return n8; -} - - -/************************************************* -* Add characters not in a list to a class * -*************************************************/ - -/* This function is used for adding the complement of a list of horizontal or -vertical whitespace to a class. The list must be in order. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options bits - xoptions the extra options bits - cb contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static unsigned int -add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p) -{ -BOOL utf = (options & PCRE2_UTF) != 0; -unsigned int n8 = 0; -if (p[0] > 0) - n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, 0, p[0] - 1); -while (p[0] < NOTACHAR) - { - while (p[1] == p[0] + 1) p++; - n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, p[0] + 1, - (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); - p++; - } -return n8; +PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ } @@ -5572,6 +5882,7 @@ have duplicate names. Give an internal error. */ if (i >= cb->names_found) { + PCRE2_DEBUG_UNREACHABLE(); *errorcodeptr = ERR53; cb->erroroffset = name - cb->start_pattern; return FALSE; @@ -5649,12 +5960,13 @@ uint32_t options = *optionsptr; /* May change dynamically */ uint32_t xoptions = *xoptionsptr; /* May change dynamically */ uint32_t firstcu, reqcu; uint32_t zeroreqcu, zerofirstcu; -uint32_t escape; uint32_t *pptr = *pptrptr; uint32_t meta, meta_arg; uint32_t firstcuflags, reqcuflags; uint32_t zeroreqcuflags, zerofirstcuflags; uint32_t req_caseopt, reqvary, tempreqvary; +/* Some opcodes, such as META_SCS_NUMBER or META_SCS_NAME, +depends on the previous value of offset. */ PCRE2_SIZE offset = 0; PCRE2_SIZE length_prevgroup = 0; PCRE2_UCHAR *code = *codeptr; @@ -5668,8 +5980,6 @@ BOOL had_accept = FALSE; BOOL matched_char = FALSE; BOOL previous_matched_char = FALSE; BOOL reset_caseful = FALSE; -const uint8_t *cbits = cb->cbits; -uint8_t classbits[32]; /* We can fish out the UTF setting once and for all into a BOOL, but we must not do this for other options (e.g. PCRE2_EXTENDED) that may change dynamically @@ -5682,17 +5992,6 @@ BOOL ucp = (options & PCRE2_UCP) != 0; BOOL utf = FALSE; #endif -/* Helper variables for OP_XCLASS opcode (for characters > 255). We define -class_uchardata always so that it can be passed to add_to_class() always, -though it will not be used in non-UTF 8-bit cases. This avoids having to supply -alternative calls for the different cases. */ - -PCRE2_UCHAR *class_uchardata; -#ifdef SUPPORT_WIDE_CHARS -BOOL xclass; -PCRE2_UCHAR *class_uchardata_base; -#endif - /* Set up the default and non-default settings for greediness */ greedy_default = ((options & PCRE2_UNGREEDY) != 0); @@ -5722,15 +6021,8 @@ req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0; for (;; pptr++) { -#ifdef SUPPORT_WIDE_CHARS - BOOL xclass_has_prop; -#endif - BOOL negate_class; - BOOL should_flip_negation; - BOOL match_all_or_no_wide_chars; BOOL possessive_quantifier; BOOL note_group_empty; - int class_has_8bitchar; uint32_t mclength; uint32_t skipunits; uint32_t subreqcu, subfirstcu; @@ -5753,8 +6045,13 @@ for (;; pptr++) if (code > cb->start_workspace + cb->workspace_size - WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ { - *errorcodeptr = (code >= cb->start_workspace + cb->workspace_size)? - ERR52 : ERR86; + if (code >= cb->start_workspace + cb->workspace_size) + { + PCRE2_DEBUG_UNREACHABLE(); + *errorcodeptr = ERR52; /* Over-ran workspace - internal error */ + } + else + *errorcodeptr = ERR86; return 0; } @@ -5860,13 +6157,24 @@ for (;; pptr++) /* ===================================================================*/ /* Empty character classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set. Otherwise, an initial ']' is taken as a data character. When empty classes - are allowed, [] must always fail, so generate OP_FAIL, whereas [^] must - match any character, so generate OP_ALLANY. */ + are allowed, [] must generate an empty class - we have no dedicated opcode + to optimise the representation, but it's a rare case (the '(*FAIL)' + construct would be a clearer way for a pattern author to represent a + non-matching branch, but it does have different semantics to '[]' if both + are followed by a quantifier). The empty-negated [^] matches any character, + so is useful: generate OP_ALLANY for this. */ case META_CLASS_EMPTY: case META_CLASS_EMPTY_NOT: matched_char = TRUE; - *code++ = (meta == META_CLASS_EMPTY_NOT)? OP_ALLANY : OP_FAIL; + if (meta == META_CLASS_EMPTY_NOT) *code++ = OP_ALLANY; + else + { + *code++ = OP_CLASS; + memset(code, 0, 32); + code += 32 / sizeof(PCRE2_UCHAR); + } + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; zerofirstcu = firstcu; zerofirstcuflags = firstcuflags; @@ -5889,7 +6197,16 @@ for (;; pptr++) case META_CLASS_NOT: case META_CLASS: matched_char = TRUE; - negate_class = meta == META_CLASS_NOT; + + /* Check for complex extended classes and handle them separately. */ + + if ((*pptr & CLASS_IS_ECLASS) != 0) + { + if (!PRIV(compile_class_nested)(options, xoptions, &pptr, &code, + errorcodeptr, cb, lengthptr)) + return 0; + goto CLASS_END_PROCESSING; + } /* We can optimize the case of a single character in a class by generating OP_CHAR or OP_CHARI if it's positive, or OP_NOT or OP_NOTI if it's @@ -5902,585 +6219,132 @@ for (;; pptr++) if (pptr[1] < META_END && pptr[2] == META_CLASS_END) { -#ifdef SUPPORT_UNICODE - uint32_t d; -#endif uint32_t c = pptr[1]; pptr += 2; /* Move on to class end */ if (meta == META_CLASS) /* A positive one-char class can be */ - { /* handled as a normal literal character. */ - meta = c; /* Set up the character */ - goto NORMAL_CHAR_SET; - } - - /* Handle a negative one-character class */ - - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - - /* For caseless UTF or UCP mode, check whether this character has more - than one other case. If so, generate a special OP_NOTPROP item instead of - OP_NOTI. When restricted by PCRE2_EXTRA_CASELESS_RESTRICT, ignore any - caseless set that starts with an ASCII character. */ - -#ifdef SUPPORT_UNICODE - if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 && - (d = UCD_CASESET(c)) != 0 && - ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || - PRIV(ucd_caseless_sets)[d] > 127)) - { - *code++ = OP_NOTPROP; - *code++ = PT_CLIST; - *code++ = d; - break; /* We are finished with this class */ - } -#endif - /* Char has only one other (usable) case, or UCP not available */ - - *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; - code += PUTCHAR(c, code); - break; /* We are finished with this class */ - } /* End of 1-char optimization */ - - /* Handle character classes that contain more than just one literal - character. If there are exactly two characters in a positive class, see if - they are case partners. This can be optimized to generate a caseless single - character match (which also sets first/required code units if relevant). - When casing restrictions apply, ignore a caseless set if both characters - are ASCII. */ - - if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END && - pptr[3] == META_CLASS_END) - { - uint32_t c = pptr[1]; - -#ifdef SUPPORT_UNICODE - if (UCD_CASESET(c) == 0 || - ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && - c < 128 && pptr[2] < 128)) -#endif - { - uint32_t d; - -#ifdef SUPPORT_UNICODE - if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else -#endif - { -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (c > 255) d = c; else -#endif - d = TABLE_GET(c, cb->fcc, c); - } - - if (c != d && pptr[2] == d) - { - pptr += 3; /* Move on to class end */ - meta = c; - if ((options & PCRE2_CASELESS) == 0) - { - reset_caseful = TRUE; - options |= PCRE2_CASELESS; - req_caseopt = REQ_CASELESS; - } - goto CLASS_CASELESS_CHAR; - } - } - } - - /* If a non-extended class contains a negative special such as \S, we need - to flip the negation flag at the end, so that support for characters > 255 - works correctly (they are all included in the class). An extended class may - need to insert specific matching or non-matching code for wide characters. - */ - - should_flip_negation = match_all_or_no_wide_chars = FALSE; - - /* Extended class (xclass) will be used when characters > 255 - might match. */ - -#ifdef SUPPORT_WIDE_CHARS - xclass = FALSE; - class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ - class_uchardata_base = class_uchardata; /* Save the start */ -#endif - - /* For optimization purposes, we track some properties of the class: - class_has_8bitchar will be non-zero if the class contains at least one - character with a code point less than 256; xclass_has_prop will be TRUE if - Unicode property checks are present in the class. */ - - class_has_8bitchar = 0; -#ifdef SUPPORT_WIDE_CHARS - xclass_has_prop = FALSE; -#endif - - /* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map - in a temporary bit of memory, in case the class contains fewer than two - 8-bit characters because in that case the compiled code doesn't use the bit - map. */ - - memset(classbits, 0, 32 * sizeof(uint8_t)); - - /* Process items until META_CLASS_END is reached. */ - - while ((meta = *(++pptr)) != META_CLASS_END) - { - /* Handle POSIX classes such as [:alpha:] etc. */ - - if (meta == META_POSIX || meta == META_POSIX_NEG) - { - BOOL local_negate = (meta == META_POSIX_NEG); - int posix_class = *(++pptr); - int taboffset, tabopt; - uint8_t pbits[32]; - - should_flip_negation = local_negate; /* Note negative special */ - - /* If matching is caseless, upper and lower are converted to alpha. - This relies on the fact that the class table starts with alpha, - lower, upper as the first 3 entries. */ - - if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2) - posix_class = 0; - - /* When PCRE2_UCP is set, some of the POSIX classes are converted to - different escape sequences that use Unicode properties \p or \P. - Others that are not available via \p or \P have to generate - XCL_PROP/XCL_NOTPROP directly, which is done here. */ - -#ifdef SUPPORT_UNICODE - if ((options & PCRE2_UCP) != 0 && - (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0) - { - switch(posix_class) - { - case PC_GRAPH: - case PC_PRINT: - case PC_PUNCT: - *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; - *class_uchardata++ = (PCRE2_UCHAR) - ((posix_class == PC_GRAPH)? PT_PXGRAPH : - (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT); - *class_uchardata++ = 0; - xclass_has_prop = TRUE; - goto CONTINUE_CLASS; - - /* For the other POSIX classes (ex: ascii) we are going to - fall through to the non-UCP case and build a bit map for - characters with code points less than 256. However, if we are in - a negated POSIX class, characters with code points greater than - 255 must either all match or all not match, depending on whether - the whole class is not or is negated. For example, for - [[:^ascii:]... they must all match, whereas for [^[:^ascii:]... - they must not. - - In the special case where there are no xclass items, this is - automatically handled by the use of OP_CLASS or OP_NCLASS, but an - explicit range is needed for OP_XCLASS. Setting a flag here - causes the range to be generated later when it is known that - OP_XCLASS is required. In the 8-bit library this is relevant only in - utf mode, since no wide characters can exist otherwise. */ - - default: -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (utf) -#endif - match_all_or_no_wide_chars |= local_negate; - break; - } - } -#endif /* SUPPORT_UNICODE */ - - /* In the non-UCP case, or when UCP makes no difference, we build the - bit map for the POSIX class in a chunk of local store because we may - be adding and subtracting from it, and we don't want to subtract bits - that may be in the main map already. At the end we or the result into - the bit map that is being built. */ - - posix_class *= 3; - - /* Copy in the first table (always present) */ - - memcpy(pbits, cbits + posix_class_maps[posix_class], - 32 * sizeof(uint8_t)); - - /* If there is a second table, add or remove it as required. */ - - taboffset = posix_class_maps[posix_class + 1]; - tabopt = posix_class_maps[posix_class + 2]; - - if (taboffset >= 0) - { - if (tabopt >= 0) - for (int i = 0; i < 32; i++) pbits[i] |= cbits[(int)i + taboffset]; - else - for (int i = 0; i < 32; i++) pbits[i] &= ~cbits[(int)i + taboffset]; - } - - /* Now see if we need to remove any special characters. An option - value of 1 removes vertical space and 2 removes underscore. */ - - if (tabopt < 0) tabopt = -tabopt; - if (tabopt == 1) pbits[1] &= ~0x3c; - else if (tabopt == 2) pbits[11] &= 0x7f; - - /* Add the POSIX table or its complement into the main table that is - being built and we are done. */ - - if (local_negate) - for (int i = 0; i < 32; i++) classbits[i] |= (uint8_t)(~pbits[i]); - else - for (int i = 0; i < 32; i++) classbits[i] |= pbits[i]; - - /* Every class contains at least one < 256 character. */ - - class_has_8bitchar = 1; - goto CONTINUE_CLASS; /* End of POSIX handling */ - } - - /* Other than POSIX classes, the only items we should encounter are - \d-type escapes and literal characters (possibly as ranges). */ - - if (meta == META_BIGVALUE) - { - meta = *(++pptr); - goto CLASS_LITERAL; - } - - /* Any other non-literal must be an escape */ - - if (meta >= META_END) - { - if (META_CODE(meta) != META_ESCAPE) - { -#ifdef DEBUG_SHOW_PARSED - fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x " - "in character class\n", meta); -#endif - *errorcodeptr = ERR89; /* Internal error - unrecognized. */ - return 0; - } - escape = META_DATA(meta); - - /* Every class contains at least one < 256 character. */ - - class_has_8bitchar++; - - switch(escape) - { - case ESC_d: - for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit]; - break; - - case ESC_D: - should_flip_negation = TRUE; - for (int i = 0; i < 32; i++) - classbits[i] |= (uint8_t)(~cbits[i+cbit_digit]); - break; - - case ESC_w: - for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word]; - break; - - case ESC_W: - should_flip_negation = TRUE; - for (int i = 0; i < 32; i++) - classbits[i] |= (uint8_t)(~cbits[i+cbit_word]); - break; - - /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl - 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was - previously set by something earlier in the character class. - Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so - we could just adjust the appropriate bit. From PCRE 8.34 we no - longer treat \s and \S specially. */ - - case ESC_s: - for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space]; - break; - - case ESC_S: - should_flip_negation = TRUE; - for (int i = 0; i < 32; i++) - classbits[i] |= (uint8_t)(~cbits[i+cbit_space]); - break; - - /* When adding the horizontal or vertical space lists to a class, or - their complements, disable PCRE2_CASELESS, because it justs wastes - time, and in the "not-x" UTF cases can create unwanted duplicates in - the XCLASS list (provoked by characters that have more than one other - case and by both cases being in the same "not-x" sublist). */ - - case ESC_h: - (void)add_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list), - NOTACHAR); - break; - - case ESC_H: - (void)add_not_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list)); - break; - - case ESC_v: - (void)add_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list), - NOTACHAR); - break; - - case ESC_V: - (void)add_not_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list)); - break; - - /* If Unicode is not supported, \P and \p are not allowed and are - faulted at parse time, so will never appear here. */ - -#ifdef SUPPORT_UNICODE - case ESC_p: - case ESC_P: - { - uint32_t ptype = *(++pptr) >> 16; - uint32_t pdata = *pptr & 0xffff; - *class_uchardata++ = (escape == ESC_p)? XCL_PROP : XCL_NOTPROP; - *class_uchardata++ = ptype; - *class_uchardata++ = pdata; - xclass_has_prop = TRUE; - class_has_8bitchar--; /* Undo! */ - } - break; -#endif - } - - goto CONTINUE_CLASS; - } /* End handling \d-type escapes */ - - /* A literal character may be followed by a range meta. At parse time - there are checks for out-of-order characters, for ranges where the two - characters are equal, and for hyphens that cannot indicate a range. At - this point, therefore, no checking is needed. */ - - else - { - uint32_t c, d; - - CLASS_LITERAL: - c = d = meta; - - /* Remember if \r or \n were explicitly used */ - - if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; - - /* Process a character range */ - - if (pptr[1] == META_RANGE_LITERAL || pptr[1] == META_RANGE_ESCAPED) - { -#ifdef EBCDIC - BOOL range_is_literal = (pptr[1] == META_RANGE_LITERAL); -#endif - pptr += 2; - d = *pptr; - if (d == META_BIGVALUE) d = *(++pptr); - - /* Remember an explicit \r or \n, and add the range to the class. */ - - if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; - - /* In an EBCDIC environment, Perl treats alphabetic ranges specially - because there are holes in the encoding, and simply using the range - A-Z (for example) would include the characters in the holes. This - applies only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */ - -#ifdef EBCDIC - if (range_is_literal && - (cb->ctypes[c] & ctype_letter) != 0 && - (cb->ctypes[d] & ctype_letter) != 0 && - (c <= CHAR_z) == (d <= CHAR_z)) - { - uint32_t uc = (d <= CHAR_z)? 0 : 64; - uint32_t C = c - uc; - uint32_t D = d - uc; - - if (C <= CHAR_i) - { - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, xoptions, - cb, C + uc, ((D < CHAR_i)? D : CHAR_i) + uc); - C = CHAR_j; - } - - if (C <= D && C <= CHAR_r) - { - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, xoptions, - cb, C + uc, ((D < CHAR_r)? D : CHAR_r) + uc); - C = CHAR_s; - } - - if (C <= D) - { - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, xoptions, - cb, C + uc, D + uc); - } - } - else -#endif - /* Not an EBCDIC special range */ - - class_has_8bitchar += add_to_class(classbits, &class_uchardata, - options, xoptions, cb, c, d); - goto CONTINUE_CLASS; /* Go get the next char in the class */ - } /* End of range handling */ - - - /* Handle a single character. */ - - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, xoptions, cb, - meta, meta); + { /* handled as a normal literal character. */ + meta = c; /* Set up the character */ + goto NORMAL_CHAR_SET; } - /* Continue to the next item in the class. */ + /* Handle a negative one-character class */ - CONTINUE_CLASS: + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; -#ifdef SUPPORT_WIDE_CHARS - /* If any wide characters or Unicode properties have been encountered, - set xclass = TRUE. Then, in the pre-compile phase, accumulate the length - of the extra data and reset the pointer. This is so that very large - classes that contain a zillion wide characters or Unicode property tests - do not overwrite the workspace (which is on the stack). */ + /* For caseless UTF or UCP mode, check whether this character has more + than one other case. If so, generate a special OP_NOTPROP item instead of + OP_NOTI. When restricted by PCRE2_EXTRA_CASELESS_RESTRICT, ignore any + caseless set that starts with an ASCII character. If the character is + affected by the special Turkish rules, hardcode the not-matching + characters using a caseset. */ - if (class_uchardata > class_uchardata_base) +#ifdef SUPPORT_UNICODE + if ((utf||ucp) && (options & PCRE2_CASELESS) != 0) { - xclass = TRUE; - if (lengthptr != NULL) + uint32_t caseset; + + if ((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == + PCRE2_EXTRA_TURKISH_CASING && + UCD_ANY_I(c)) { - *lengthptr += class_uchardata - class_uchardata_base; - class_uchardata = class_uchardata_base; + caseset = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(c)? 0 : 3); + } + else if ((caseset = UCD_CASESET(c)) != 0 && + (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && + PRIV(ucd_caseless_sets)[caseset] < 128) + { + caseset = 0; /* Ignore the caseless set if it's restricted. */ + } + + if (caseset != 0) + { + *code++ = OP_NOTPROP; + *code++ = PT_CLIST; + *code++ = caseset; + break; /* We are finished with this class */ } } #endif + /* Char has only one other (usable) case, or UCP not available */ - continue; /* Needed to avoid error when not supporting wide chars */ - } /* End of main class-processing loop */ + *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; + code += PUTCHAR(c, code); + break; /* We are finished with this class */ + } /* End of 1-char optimization */ - /* If this class is the first thing in the branch, there can be no first - char setting, whatever the repeat count. Any reqcu setting must remain - unchanged after any kind of repeat. */ + /* Handle character classes that contain more than just one literal + character. If there are exactly two characters in a positive class, see if + they are case partners. This can be optimized to generate a caseless single + character match (which also sets first/required code units if relevant). + When casing restrictions apply, ignore a caseless set if both characters + are ASCII. When Turkish casing applies, an 'i' does not match its normal + Unicode "othercase". */ - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; + if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END && + pptr[3] == META_CLASS_END) + { + uint32_t c = pptr[1]; - /* If there are characters with values > 255, or Unicode property settings - (\p or \P), we have to compile an extended class, with its own opcode, - unless there were no property settings and there was a negated special such - as \S in the class, and PCRE2_UCP is not set, because in that case all - characters > 255 are in or not in the class, so any that were explicitly - given as well can be ignored. - - In the UCP case, if certain negated POSIX classes (ex: [:^ascii:]) were - were present in a class, we either have to match or not match all wide - characters (depending on whether the whole class is or is not negated). - This requirement is indicated by match_all_or_no_wide_chars being true. - We do this by including an explicit range, which works in both cases. - This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there - cannot be any wide characters in 8-bit non-UTF mode. - - When there *are* properties in a positive UTF-8 or any 16-bit or 32_bit - class where \S etc is present without PCRE2_UCP, causing an extended class - to be compiled, we make sure that all characters > 255 are included by - forcing match_all_or_no_wide_chars to be true. - - If, when generating an xclass, there are no characters < 256, we can omit - the bitmap in the actual compiled code. */ - -#ifdef SUPPORT_WIDE_CHARS /* Defined for 16/32 bits, or 8-bit with Unicode */ - if (xclass && ( #ifdef SUPPORT_UNICODE - (options & PCRE2_UCP) != 0 || -#endif - xclass_has_prop || !should_flip_negation)) - { - if (match_all_or_no_wide_chars || ( -#if PCRE2_CODE_UNIT_WIDTH == 8 - utf && + if ((UCD_CASESET(c) == 0 || + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && + c < 128 && pptr[2] < 128)) && + !((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == + PCRE2_EXTRA_TURKISH_CASING && + UCD_ANY_I(c))) #endif - should_flip_negation && !negate_class && (options & PCRE2_UCP) == 0)) { - *class_uchardata++ = XCL_RANGE; - if (utf) /* Will always be utf in the 8-bit library */ - { - class_uchardata += PRIV(ord2utf)(0x100, class_uchardata); - class_uchardata += PRIV(ord2utf)(MAX_UTF_CODE_POINT, class_uchardata); - } - else /* Can only happen for the 16-bit & 32-bit libraries */ + uint32_t d; + +#ifdef SUPPORT_UNICODE + if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else +#endif { -#if PCRE2_CODE_UNIT_WIDTH == 16 - *class_uchardata++ = 0x100; - *class_uchardata++ = 0xffffu; -#elif PCRE2_CODE_UNIT_WIDTH == 32 - *class_uchardata++ = 0x100; - *class_uchardata++ = 0xffffffffu; +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) d = c; else #endif + d = TABLE_GET(c, cb->fcc, c); } - } - *class_uchardata++ = XCL_END; /* Marks the end of extra data */ - *code++ = OP_XCLASS; - code += LINK_SIZE; - *code = negate_class? XCL_NOT:0; - if (xclass_has_prop) *code |= XCL_HASPROP; - - /* If the map is required, move up the extra data to make room for it; - otherwise just move the code pointer to the end of the extra data. */ - if (class_has_8bitchar > 0) - { - *code++ |= XCL_MAP; - (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, - CU2BYTES(class_uchardata - code)); - if (negate_class && !xclass_has_prop) + if (c != d && pptr[2] == d) { - /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ - for (int i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i]; + pptr += 3; /* Move on to class end */ + meta = c; + if ((options & PCRE2_CASELESS) == 0) + { + reset_caseful = TRUE; + options |= PCRE2_CASELESS; + req_caseopt = REQ_CASELESS; + } + goto CLASS_CASELESS_CHAR; } - memcpy(code, classbits, 32); - code = class_uchardata + (32 / sizeof(PCRE2_UCHAR)); } - else code = class_uchardata; + } - /* Now fill in the complete length of the item */ + /* Now emit the OP_CLASS/OP_NCLASS/OP_XCLASS/OP_ALLANY opcode. */ - PUT(previous, 1, (int)(code - previous)); - break; /* End of class handling */ - } -#endif /* SUPPORT_WIDE_CHARS */ + pptr = PRIV(compile_class_not_nested)(options, xoptions, pptr + 1, + &code, meta == META_CLASS_NOT, NULL, + errorcodeptr, cb, lengthptr); + if (pptr == NULL) return 0; + PCRE2_ASSERT(*pptr == META_CLASS_END); - /* If there are no characters > 255, or they are all to be included or - excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the - whole class was negated and whether there were negative specials such as \S - (non-UCP) in the class. Then copy the 32-byte map into the code vector, - negating it if necessary. */ + CLASS_END_PROCESSING: - *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; - if (lengthptr == NULL) /* Save time in the pre-compile phase */ - { - if (negate_class) - { - /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ - for (int i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i]; - } - memcpy(code, classbits, 32); - } - code += 32 / sizeof(PCRE2_UCHAR); + /* If this class is the first thing in the branch, there can be no first + char setting, whatever the repeat count. Any reqcu setting must remain + unchanged after any kind of repeat. */ + + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; break; /* End of class processing */ @@ -6586,6 +6450,15 @@ for (;; pptr++) req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0; break; + case META_OFFSET: + GETPLUSOFFSET(offset, pptr); + break; + + case META_SCS: + bravalue = OP_ASSERT_SCS; + cb->assert_depth += 1; + goto GROUP_PROCESS; + /* ===================================================================*/ /* Handle conditional subpatterns. The case of (?(Rdigits) is ambiguous @@ -6597,6 +6470,7 @@ for (;; pptr++) case META_COND_RNUMBER: /* (?(Rdigits) */ case META_COND_NAME: /* (?(name) or (?'name') or ?() */ case META_COND_RNAME: /* (?(R&name) - test for recursion */ + case META_SCS_NAME: /* Name of scan substring */ bravalue = OP_COND; { int count, index; @@ -6605,7 +6479,10 @@ for (;; pptr++) named_group *ng = cb->named_groups; uint32_t length = *(++pptr); - GETPLUSOFFSET(offset, pptr); + if (meta == META_SCS_NAME) + offset += meta_arg; + else + GETPLUSOFFSET(offset, pptr); name = cb->start_pattern + offset; /* In the first pass, the names generated in the pre-pass are available, @@ -6615,34 +6492,21 @@ for (;; pptr++) numerical group. */ for (i = 0; i < cb->names_found; i++, ng++) - { if (length == ng->length && - PRIV(strncmp)(name, ng->name, length) == 0) - { - if (!ng->isdup) - { - code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF; - PUT2(code, 2+LINK_SIZE, ng->number); - if (ng->number > cb->top_backref) cb->top_backref = ng->number; - skipunits = 1+IMM2_SIZE; - goto GROUP_PROCESS_NOTE_EMPTY; - } - break; /* Found a duplicated name */ - } - } - - /* If the name was not found we have a bad reference, unless we are - dealing with R, which is treated as a recursion test by number. - */ + PRIV(strncmp)(name, ng->name, length) == 0) break; if (i >= cb->names_found) { + /* If the name was not found we have a bad reference, unless we are + dealing with R, which is treated as a recursion test by + number. */ + groupnumber = 0; if (meta == META_COND_RNUMBER) { for (i = 1; i < length; i++) { - groupnumber = groupnumber * 10 + name[i] - CHAR_0; + groupnumber = groupnumber * 10 + (name[i] - CHAR_0); if (groupnumber > MAX_GROUP_NUMBER) { *errorcodeptr = ERR61; @@ -6669,11 +6533,26 @@ for (;; pptr++) skipunits = 1+IMM2_SIZE; goto GROUP_PROCESS_NOTE_EMPTY; } + else if (!ng->isdup) + { + /* Otherwise found a duplicated name */ + if (ng->number > cb->top_backref) cb->top_backref = ng->number; - /* A duplicated name was found. Note that if an R name is found - (META_COND_RNUMBER), it is a reference test, not a recursion test. */ + if (meta == META_SCS_NAME) + { + code[0] = OP_CREF; + PUT2(code, 1, ng->number); + code += 1+IMM2_SIZE; + break; + } - code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF; + code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF; + PUT2(code, 2+LINK_SIZE, ng->number); + skipunits = 1+IMM2_SIZE; + if (meta != META_SCS_NAME) goto GROUP_PROCESS_NOTE_EMPTY; + cb->assert_depth += 1; + goto GROUP_PROCESS; + } /* We have a duplicated name. In the compile pass we have to search the main table in order to get the index and count values. */ @@ -6683,14 +6562,27 @@ for (;; pptr++) if (lengthptr == NULL && !find_dupname_details(name, length, &index, &count, errorcodeptr, cb)) return 0; - /* Add one to the opcode to change CREF/RREF into DNCREF/DNRREF and - insert appropriate data values. */ + if (meta == META_SCS_NAME) + { + code[0] = OP_DNCREF; + PUT2(code, 1, index); + PUT2(code, 1+IMM2_SIZE, count); + code += 1+2*IMM2_SIZE; + break; + } + + /* A duplicated name was found. Note that if an R name is found + (META_COND_RNUMBER), it is a reference test, not a recursion test. */ + + code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_DNRREF : OP_DNCREF; - code[1+LINK_SIZE]++; + /* Insert appropriate data values. */ skipunits = 1+2*IMM2_SIZE; PUT2(code, 2+LINK_SIZE, index); PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count); } + + PCRE2_ASSERT(meta != META_SCS_NAME); goto GROUP_PROCESS_NOTE_EMPTY; /* The DEFINE condition is always false. Its internal groups may never @@ -6707,8 +6599,13 @@ for (;; pptr++) /* Conditional test of a group's being set. */ case META_COND_NUMBER: + case META_SCS_NUMBER: bravalue = OP_COND; - GETPLUSOFFSET(offset, pptr); + if (meta == META_SCS_NUMBER) + offset += meta_arg; + else + GETPLUSOFFSET(offset, pptr); + groupnumber = *(++pptr); if (groupnumber > cb->bracount) { @@ -6717,7 +6614,17 @@ for (;; pptr++) return 0; } if (groupnumber > cb->top_backref) cb->top_backref = groupnumber; - offset -= 2; /* Point at initial ( for too many branches error */ + + if (meta == META_SCS_NUMBER) + { + code[0] = OP_CREF; + PUT2(code, 1, groupnumber); + code += 1+IMM2_SIZE; + break; + } + + /* Point at initial ( for too many branches error */ + offset -= 2; code[1+LINK_SIZE] = OP_CREF; skipunits = 1+IMM2_SIZE; PUT2(code, 2+LINK_SIZE, groupnumber); @@ -6855,7 +6762,7 @@ for (;; pptr++) /* If we've just compiled an assertion, pop the assert depth. */ - if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NA) + if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERT_SCS) cb->assert_depth -= 1; /* At the end of compiling, code is still pointing to the start of the @@ -7094,6 +7001,11 @@ for (;; pptr++) *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF; PUT2INC(code, 0, index); PUT2INC(code, 0, count); + if ((options & PCRE2_CASELESS) != 0) + *code++ = (((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)? + REFI_FLAG_CASELESS_RESTRICT : 0) | + (((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0)? + REFI_FLAG_TURKISH_CASING : 0); } break; @@ -7213,7 +7125,6 @@ for (;; pptr++) single-char opcodes. */ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; - op_type = 0; /* Adjust first and required code units for a zero repeat. */ @@ -7254,6 +7165,7 @@ for (;; pptr++) /* Save start of previous item, in case we have to move it up in order to insert something before it, and remember what it was. */ + PCRE2_ASSERT(previous != NULL); tempcode = previous; op_previous = *previous; @@ -7313,6 +7225,7 @@ for (;; pptr++) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: + case OP_ECLASS: #endif case OP_CLASS: case OP_NCLASS: @@ -7343,14 +7256,6 @@ for (;; pptr++) } break; - /* If previous is OP_FAIL, it was generated by an empty class [] - (PCRE2_ALLOW_EMPTY_CLASS is set). The other ways in which OP_FAIL can be - generated, that is by (*FAIL) or (?!), disallow a quantifier at parse - time. We can just ignore this repeat. */ - - case OP_FAIL: - goto END_REPEAT; - /* Prior to 10.30, repeated recursions were wrapped in OP_ONCE brackets because pcre2_match() could not handle backtracking into recursively called groups. Now that this backtracking is available, we no longer need @@ -7434,6 +7339,7 @@ for (;; pptr++) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -7758,9 +7664,10 @@ for (;; pptr++) here because it just makes it horribly messy. */ default: - if (op_previous >= OP_EODN) /* Not a character type - internal error */ + if (op_previous >= OP_EODN || op_previous <= OP_WORD_BOUNDARY) { - *errorcodeptr = ERR10; + PCRE2_DEBUG_UNREACHABLE(); + *errorcodeptr = ERR10; /* Not a character type - internal error */ return 0; } else @@ -7780,7 +7687,8 @@ for (;; pptr++) } else { - /* Come here from just above with a character in mcbuffer/mclength. */ + /* Come here from just above with a character in mcbuffer/mclength. + You must also set op_type before the jump. */ OUTPUT_SINGLE_REPEAT: prop_type = prop_value = -1; } @@ -7963,6 +7871,7 @@ for (;; pptr++) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: + case OP_ECLASS: tempcode += GET(tempcode, 1); break; #endif @@ -8047,6 +7956,11 @@ for (;; pptr++) if (firstcuflags == REQ_UNSET) zerofirstcuflags = firstcuflags = REQ_NONE; *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF; PUT2INC(code, 0, meta_arg); + if ((options & PCRE2_CASELESS) != 0) + *code++ = (((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)? + REFI_FLAG_CASELESS_RESTRICT : 0) | + (((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0)? + REFI_FLAG_TURKISH_CASING : 0); /* Update the map of back references, and keep the highest one. We could do this in parse_regex() for numerical back references, but not @@ -8139,12 +8053,30 @@ for (;; pptr++) uint32_t ptype = *(++pptr) >> 16; uint32_t pdata = *pptr & 0xffff; - /* The special case of \p{Any} is compiled to OP_ALLANY so as to benefit - from the auto-anchoring code. */ + /* In caseless matching, particular characteristics Lu, Ll, and Lt get + converted to the general characteristic L&. That is, upper, lower, and + title case letters are all conflated. */ + + if ((options & PCRE2_CASELESS) != 0 && ptype == PT_PC && + (pdata == ucp_Lu || pdata == ucp_Ll || pdata == ucp_Lt)) + { + ptype = PT_LAMP; + pdata = 0; + } + + /* The special case of \p{Any} is compiled to OP_ALLANY and \P{Any} + is compiled to [] so as to benefit from the auto-anchoring code. */ - if (meta_arg == ESC_p && ptype == PT_ANY) + if (ptype == PT_ANY) { - *code++ = OP_ALLANY; + if (meta_arg == ESC_P) + { + *code++ = OP_CLASS; + memset(code, 0, 32); + code += 32 / sizeof(PCRE2_UCHAR); + } + else + *code++ = OP_ALLANY; } else { @@ -8213,9 +8145,7 @@ for (;; pptr++) default: if (meta >= META_END) { -#ifdef DEBUG_SHOW_PARSED - fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x\n", *pptr); -#endif + PCRE2_DEBUG_UNREACHABLE(); *errorcodeptr = ERR89; /* Internal error - unrecognized. */ return 0; } @@ -8231,15 +8161,28 @@ for (;; pptr++) /* For caseless UTF or UCP mode, check whether this character has more than one other case. If so, generate a special OP_PROP item instead of OP_CHARI. When casing restrictions apply, ignore caseless sets that start with an - ASCII character. */ + ASCII character. If the character is affected by the special Turkish rules, + hardcode the matching characters using a caseset. */ #ifdef SUPPORT_UNICODE if ((utf||ucp) && (options & PCRE2_CASELESS) != 0) { - uint32_t caseset = UCD_CASESET(meta); - if (caseset != 0 && - ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || - PRIV(ucd_caseless_sets)[caseset] > 127)) + uint32_t caseset; + + if ((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == + PCRE2_EXTRA_TURKISH_CASING && + UCD_ANY_I(meta)) + { + caseset = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(meta)? 0 : 3); + } + else if ((caseset = UCD_CASESET(meta)) != 0 && + (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && + PRIV(ucd_caseless_sets)[caseset] < 128) + { + caseset = 0; /* Ignore the caseless set if it's restricted. */ + } + + if (caseset != 0) { *code++ = OP_PROP; *code++ = PT_CLIST; @@ -8337,7 +8280,8 @@ for (;; pptr++) } /* End of big switch */ } /* End of big loop */ -/* Control never reaches here. */ +PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ +return 0; /* Avoid compiler warnings */ } @@ -8393,8 +8337,6 @@ uint32_t firstcu, reqcu; uint32_t lookbehindlength; uint32_t lookbehindminlength; uint32_t firstcuflags, reqcuflags; -uint32_t branchfirstcu, branchreqcu; -uint32_t branchfirstcuflags, branchreqcuflags; PCRE2_SIZE length; branch_chain bc; @@ -8463,9 +8405,11 @@ code += 1 + LINK_SIZE + skipunits; for (;;) { int branch_return; + uint32_t branchfirstcu = 0, branchreqcu = 0; + uint32_t branchfirstcuflags = REQ_UNSET, branchreqcuflags = REQ_UNSET; /* Insert OP_REVERSE or OP_VREVERSE if this is a lookbehind assertion. There - is only a single mimimum length for the whole assertion. When the mimimum + is only a single minimum length for the whole assertion. When the minimum length is LOOKBEHIND_MAX it means that all branches are of fixed length, though not necessarily the same length. In this case, the original OP_REVERSE can be used. It can also be used if a branch in a variable length lookbehind @@ -8577,10 +8521,10 @@ for (;;) { if (lengthptr == NULL) { - PCRE2_SIZE branch_length = code - last_branch; + uint32_t branch_length = (uint32_t)(code - last_branch); do { - PCRE2_SIZE prev_length = GET(last_branch, 1); + uint32_t prev_length = GET(last_branch, 1); PUT(last_branch, 1, branch_length); branch_length = prev_length; last_branch -= branch_length; @@ -8591,7 +8535,7 @@ for (;;) /* Fill in the ket */ *code = OP_KET; - PUT(code, 1, (int)(code - start_bracket)); + PUT(code, 1, (uint32_t)(code - start_bracket)); code += 1 + LINK_SIZE; /* Set values to pass back */ @@ -8642,7 +8586,9 @@ for (;;) lookbehindlength = META_DATA(*pptr); pptr++; } -/* Control never reaches here */ + +PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ +return 0; /* Avoid compiler warnings */ } @@ -8685,13 +8631,14 @@ this prevents the number of characters it matches from being adjusted. cb points to the compile data block atomcount atomic group level inassert TRUE if in an assertion + dotstar_anchor TRUE if automatic anchoring optimization is enabled Returns: TRUE or FALSE */ static BOOL is_anchored(PCRE2_SPTR code, uint32_t bracket_map, compile_block *cb, - int atomcount, BOOL inassert) + int atomcount, BOOL inassert, BOOL dotstar_anchor) { do { PCRE2_SPTR scode = first_significant_code( @@ -8703,7 +8650,7 @@ do { if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_anchored(scode, bracket_map, cb, atomcount, inassert)) + if (!is_anchored(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor)) return FALSE; } @@ -8714,14 +8661,14 @@ do { { int n = GET2(scode, 1+LINK_SIZE); uint32_t new_map = bracket_map | ((n < 32)? (1u << n) : 1); - if (!is_anchored(scode, new_map, cb, atomcount, inassert)) return FALSE; + if (!is_anchored(scode, new_map, cb, atomcount, inassert, dotstar_anchor)) return FALSE; } /* Positive forward assertion */ else if (op == OP_ASSERT || op == OP_ASSERT_NA) { - if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; + if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor)) return FALSE; } /* Condition. If there is no second branch, it can't be anchored. */ @@ -8729,7 +8676,7 @@ do { else if (op == OP_COND || op == OP_SCOND) { if (scode[GET(scode,1)] != OP_ALT) return FALSE; - if (!is_anchored(scode, bracket_map, cb, atomcount, inassert)) + if (!is_anchored(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor)) return FALSE; } @@ -8737,7 +8684,7 @@ do { else if (op == OP_ONCE) { - if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert)) + if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert, dotstar_anchor)) return FALSE; } @@ -8752,8 +8699,7 @@ do { op == OP_TYPEPOSSTAR)) { if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 || - atomcount > 0 || cb->had_pruneorskip || inassert || - (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) + atomcount > 0 || cb->had_pruneorskip || inassert || !dotstar_anchor) return FALSE; } @@ -8790,13 +8736,14 @@ or *SKIP does not count, because once again the assumption no longer holds. cb points to the compile data atomcount atomic group level inassert TRUE if in an assertion + dotstar_anchor TRUE if automatic anchoring optimization is enabled Returns: TRUE or FALSE */ static BOOL is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb, - int atomcount, BOOL inassert) + int atomcount, BOOL inassert, BOOL dotstar_anchor) { do { PCRE2_SPTR scode = first_significant_code( @@ -8827,7 +8774,8 @@ do { return FALSE; default: /* Assertion */ - if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; + if (!is_startline(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor)) + return FALSE; do scode += GET(scode, 1); while (*scode == OP_ALT); scode += 1 + LINK_SIZE; break; @@ -8841,7 +8789,7 @@ do { if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_startline(scode, bracket_map, cb, atomcount, inassert)) + if (!is_startline(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor)) return FALSE; } @@ -8852,14 +8800,15 @@ do { { int n = GET2(scode, 1+LINK_SIZE); unsigned int new_map = bracket_map | ((n < 32)? (1u << n) : 1); - if (!is_startline(scode, new_map, cb, atomcount, inassert)) return FALSE; + if (!is_startline(scode, new_map, cb, atomcount, inassert, dotstar_anchor)) + return FALSE; } /* Positive forward assertions */ else if (op == OP_ASSERT || op == OP_ASSERT_NA) { - if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) + if (!is_startline(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor)) return FALSE; } @@ -8867,7 +8816,7 @@ do { else if (op == OP_ONCE) { - if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert)) + if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert, dotstar_anchor)) return FALSE; } @@ -8881,8 +8830,7 @@ do { else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) { if (scode[1] != OP_ANY || (bracket_map & cb->backref_map) != 0 || - atomcount > 0 || cb->had_pruneorskip || inassert || - (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) + atomcount > 0 || cb->had_pruneorskip || inassert || !dotstar_anchor) return FALSE; } @@ -8916,8 +8864,8 @@ OP_RECURSE. Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ -static PCRE2_SPTR -find_recurse(PCRE2_SPTR code, BOOL utf) +static PCRE2_UCHAR * +find_recurse(PCRE2_UCHAR *code, BOOL utf) { for (;;) { @@ -8926,12 +8874,13 @@ for (;;) if (c == OP_RECURSE) return code; /* XCLASS is used for classes that cannot be represented just by a bit map. - This includes negated single high-valued characters. CALLOUT_STR is used for - callouts with string arguments. In both cases the length in the table is + This includes negated single high-valued characters. ECLASS is used for + classes that use set operations internally. CALLOUT_STR is used for + callouts with string arguments. In each case the length in the table is zero; the actual length is stored in the compiled code. */ - if (c == OP_XCLASS) code += GET(code, 1); - else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); + if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1); + else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); /* Otherwise, we can get the item's length from the table, except that for repeated character types, we have to test for \p and \P, which have an extra @@ -9261,9 +9210,12 @@ for (;; pptr++) if (meta < META_END) continue; /* Literal */ break; - /* This should never occur. */ - case META_END: + + /* The parsed regex is malformed; we have reached the end and did + not find the end of the construct which we are skipping over. */ + + PCRE2_DEBUG_UNREACHABLE(); return NULL; /* The data for these items is variable in length. */ @@ -9272,19 +9224,9 @@ for (;; pptr++) if (META_DATA(*pptr) >= 10) pptr += SIZEOFFSET; break; - case META_ESCAPE: /* A few escapes are followed by data items. */ - switch (META_DATA(*pptr)) - { - case ESC_P: - case ESC_p: - pptr += 1; - break; - - case ESC_g: - case ESC_k: - pptr += 1 + SIZEOFFSET; - break; - } + case META_ESCAPE: + if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p) + pptr += 1; /* Skip prop data */ break; case META_MARK: /* Add the length of the name. */ @@ -9310,6 +9252,7 @@ for (;; pptr++) case META_COND_RNAME: case META_COND_RNUMBER: case META_COND_VERSION: + case META_SCS: case META_LOOKAHEAD: case META_LOOKAHEADNOT: case META_LOOKAHEAD_NA: @@ -9337,8 +9280,8 @@ for (;; pptr++) if (meta >= sizeof(meta_extra_lengths)) return NULL; pptr += meta_extra_lengths[meta]; } -/* Control never reaches here */ -return pptr; + +PCRE2_UNREACHABLE(); /* Control never reaches here */ } @@ -9469,10 +9412,10 @@ for (;; pptr++) parsed_recurse_check *r; uint32_t *gptr, *gptrend; uint32_t escape; + uint32_t min, max; uint32_t group = 0; uint32_t itemlength = 0; uint32_t itemminlength = 0; - uint32_t min, max; if (*pptr < META_END) { @@ -9571,6 +9514,7 @@ for (;; pptr++) case META_LOOKAHEAD: case META_LOOKAHEADNOT: case META_LOOKAHEAD_NA: + case META_SCS: *errcodeptr = check_lookbehinds(pptr + 1, &pptr, recurses, cb, lcptr); if (*errcodeptr != 0) return -1; @@ -9602,7 +9546,9 @@ for (;; pptr++) break; /* A nested lookbehind does not contribute any length to this lookbehind, - but must itself be checked and have its lengths set. */ + but must itself be checked and have its lengths set. Note that + set_lookbehind_lengths() updates pptr, leaving it pointing to the final ket + of the group, so no need to update it here. */ case META_LOOKBEHIND: case META_LOOKBEHINDNOT: @@ -9838,7 +9784,8 @@ for (;; pptr++) return branchlength; PARSED_SKIP_FAILED: -*errcodeptr = ERR90; +PCRE2_DEBUG_UNREACHABLE(); +*errcodeptr = ERR90; /* Unhandled META code - internal error */ return -1; } @@ -9922,7 +9869,7 @@ possibly different) length. */ if (variable) { gbptr[1] = minlength; - if ((uint32_t)maxlength > cb->max_varlookbehind) + if ((PCRE2_SIZE)maxlength > cb->max_varlookbehind) { *errcodeptr = ERR100; cb->erroroffset = offset; @@ -9931,8 +9878,6 @@ if (variable) } else gbptr[1] = LOOKBEHIND_MAX; - -gbptr[1] = variable? minlength : LOOKBEHIND_MAX; return TRUE; } @@ -9978,11 +9923,18 @@ for (; *pptr != META_END; pptr++) switch (META_CODE(*pptr)) { default: + + /* The following erroroffset is a bogus but safe value. This branch should + be avoided by providing a proper implementation for all supported cases + below. */ + + PCRE2_DEBUG_UNREACHABLE(); + cb->erroroffset = 0; return ERR70; /* Unrecognized meta code */ case META_ESCAPE: if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p) - pptr += 1; + pptr += 1; /* Skip prop data */ break; case META_KET: @@ -9996,6 +9948,7 @@ for (; *pptr != META_END; pptr++) case META_ATOMIC: case META_CAPTURE: case META_COND_ASSERT: + case META_SCS: case META_LOOKAHEAD: case META_LOOKAHEADNOT: case META_LOOKAHEAD_NA: @@ -10033,6 +9986,7 @@ for (; *pptr != META_END; pptr++) case META_THEN: break; + case META_OFFSET: case META_RECURSE: pptr += SIZEOFFSET; break; @@ -10067,6 +10021,8 @@ for (; *pptr != META_END; pptr++) case META_BIGVALUE: case META_POSIX: case META_POSIX_NEG: + case META_SCS_NAME: + case META_SCS_NUMBER: pptr += 1; break; @@ -10089,6 +10045,9 @@ for (; *pptr != META_END; pptr++) pptr += 1 + pptr[1]; break; + /* Note that set_lookbehind_lengths() updates pptr, leaving it pointing to + the final ket of the group, so no need to update it here. */ + case META_LOOKBEHIND: case META_LOOKBEHINDNOT: case META_LOOKBEHIND_NA: @@ -10135,19 +10094,19 @@ compile_block cb; /* "Static" compile-time data */ const uint8_t *tables; /* Char tables base pointer */ PCRE2_UCHAR *code; /* Current pointer in compiled code */ -PCRE2_SPTR codestart; /* Start of compiled code */ +PCRE2_UCHAR * codestart; /* Start of compiled code */ PCRE2_SPTR ptr; /* Current pointer in pattern */ uint32_t *pptr; /* Current pointer in parsed pattern */ PCRE2_SIZE length = 1; /* Allow for final END opcode */ PCRE2_SIZE usedlength; /* Actual length used */ PCRE2_SIZE re_blocksize; /* Size of memory block */ -PCRE2_SIZE big32count = 0; /* 32-bit literals >= 0x80000000 */ PCRE2_SIZE parsed_size_needed; /* Needed for parsed pattern */ uint32_t firstcuflags, reqcuflags; /* Type of first/req code unit */ uint32_t firstcu, reqcu; /* Value of first/req code unit */ uint32_t setflags = 0; /* NL and BSR set flags */ +uint32_t xoptions; /* Flags from context, modified */ uint32_t skipatstart; /* When checking (*UTF) etc */ uint32_t limit_heap = UINT32_MAX; @@ -10161,6 +10120,10 @@ int regexrc; /* Return from compile */ uint32_t i; /* Local loop counter */ +/* Enable all optimizations by default. */ +uint32_t optim_flags = ccontext != NULL ? ccontext->optimization_flags : + PCRE2_OPTIMIZATION_ALL; + /* Comments at the head of this file explain about these variables. */ uint32_t stack_groupinfo[GROUPINFO_DEFAULT_SIZE]; @@ -10224,6 +10187,7 @@ PCRE2_ZERO_TERMINATED. Check for an overlong pattern. */ if ((zero_terminated = (patlen == PCRE2_ZERO_TERMINATED))) patlen = PRIV(strlen)(pattern); +(void)zero_terminated; /* Silence compiler; only used if Valgrind enabled */ if (patlen > ccontext->max_pattern_length) { @@ -10231,6 +10195,18 @@ if (patlen > ccontext->max_pattern_length) return NULL; } +/* Optimization flags in 'options' can override those in the compile context. +This is because some options to disable optimizations were added before the +optimization flags word existed, and we need to continue supporting them +for backwards compatibility. */ + +if ((options & PCRE2_NO_AUTO_POSSESS) != 0) + optim_flags &= ~PCRE2_OPTIM_AUTO_POSSESS; +if ((options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) + optim_flags &= ~PCRE2_OPTIM_DOTSTAR_ANCHOR; +if ((options & PCRE2_NO_START_OPTIMIZE) != 0) + optim_flags &= ~PCRE2_OPTIM_START_OPTIMIZE; + /* From here on, all returns from this function should end up going via the EXIT label. */ @@ -10269,6 +10245,11 @@ cb.start_code = cworkspace; cb.start_pattern = pattern; cb.start_workspace = cworkspace; cb.workspace_size = COMPILE_WORK_SIZE; +#ifdef SUPPORT_WIDE_CHARS +cb.cranges = NULL; +cb.next_cranges = NULL; +cb.char_lists_size = 0; +#endif /* Maximum back reference and backref bitmap. The bitmap records up to 31 back references to help in deciding whether (.*) can be treated as anchored or not. @@ -10302,6 +10283,7 @@ non-zero-terminated patterns. */ if (zero_terminated) VALGRIND_MAKE_MEM_NOACCESS(pattern + patlen, CU2BYTES(1)); #endif +xoptions = ccontext->extra_options; ptr = pattern; skipatstart = 0; @@ -10313,13 +10295,13 @@ if ((options & PCRE2_LITERAL) == 0) { for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++) { - uint32_t c, pp; const pso *p = pso_list + i; if (patlen - skipatstart - 2 >= p->length && - PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name), - p->length) == 0) + PRIV(strncmp_c8)(ptr + skipatstart + 2, p->name, p->length) == 0) { + uint32_t c, pp; + skipatstart += p->length + 2; switch(p->type) { @@ -10327,6 +10309,10 @@ if ((options & PCRE2_LITERAL) == 0) cb.external_options |= p->value; break; + case PSO_XOPT: + xoptions |= p->value; + break; + case PSO_FLG: setflags |= p->value; break; @@ -10346,18 +10332,12 @@ if ((options & PCRE2_LITERAL) == 0) case PSO_LIMH: c = 0; pp = skipatstart; - if (!IS_DIGIT(ptr[pp])) - { - errorcode = ERR60; - ptr += pp; - goto HAD_EARLY_ERROR; - } - while (IS_DIGIT(ptr[pp])) + while (pp < patlen && IS_DIGIT(ptr[pp])) { if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */ c = c*10 + (ptr[pp++] - CHAR_0); } - if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS) + if (pp >= patlen || pp == skipatstart || ptr[pp] != CHAR_RIGHT_PARENTHESIS) { errorcode = ERR60; ptr += pp; @@ -10366,14 +10346,45 @@ if ((options & PCRE2_LITERAL) == 0) if (p->type == PSO_LIMH) limit_heap = c; else if (p->type == PSO_LIMM) limit_match = c; else limit_depth = c; - skipatstart += pp - skipatstart; + skipatstart = ++pp; + break; + + case PSO_OPTMZ: + optim_flags &= ~(p->value); + + /* For backward compatibility the three original VERBs to disable + optimizations need to also update the corresponding bit in the + external options. */ + + switch(p->value) + { + case PCRE2_OPTIM_AUTO_POSSESS: + cb.external_options |= PCRE2_NO_AUTO_POSSESS; + break; + + case PCRE2_OPTIM_DOTSTAR_ANCHOR: + cb.external_options |= PCRE2_NO_DOTSTAR_ANCHOR; + break; + + case PCRE2_OPTIM_START_OPTIMIZE: + cb.external_options |= PCRE2_NO_START_OPTIMIZE; + break; + } + break; + + default: + /* All values in the enum need an explicit entry for this switch + but until a better way to prevent coding mistakes is invented keep + a catch all that triggers a debug build assert as a failsafe */ + PCRE2_DEBUG_UNREACHABLE(); } break; /* Out of the table scan loop */ } } if (i >= sizeof(pso_list)/sizeof(pso)) break; /* Out of pso loop */ } + PCRE2_ASSERT(skipatstart <= patlen); } /* End of pattern-start options; advance to start of real regex. */ @@ -10425,6 +10436,31 @@ if (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0) goto HAD_EARLY_ERROR; } +/* PCRE2_EXTRA_TURKISH_CASING checks */ + +if ((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0) + { + if (!utf && !ucp) + { + errorcode = ERR104; + goto HAD_EARLY_ERROR; + } + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (!utf) + { + errorcode = ERR105; + goto HAD_EARLY_ERROR; + } +#endif + + if ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0) + { + errorcode = ERR106; + goto HAD_EARLY_ERROR; + } + } + /* Process the BSR setting. */ if (bsr == 0) bsr = ccontext->bsr_convention; @@ -10465,6 +10501,7 @@ switch(newline) break; default: + PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR56; goto HAD_EARLY_ERROR; } @@ -10473,42 +10510,31 @@ switch(newline) their numerical equivalents, so that this information is always available for the remaining processing. (2) At the same time, parse the pattern and put a processed version into the parsed_pattern vector. This has escapes interpreted -and comments removed (amongst other things). +and comments removed (amongst other things). */ -In all but one case, when PCRE2_AUTO_CALLOUT is not set, the number of unsigned -32-bit ints in the parsed pattern is bounded by the length of the pattern plus -one (for the terminator) plus four if PCRE2_EXTRA_WORD or PCRE2_EXTRA_LINE is -set. The exceptional case is when running in 32-bit, non-UTF mode, when literal -characters greater than META_END (0x80000000) have to be coded as two units. In -this case, therefore, we scan the pattern to check for such values. */ - -#if PCRE2_CODE_UNIT_WIDTH == 32 -if (!utf) - { - PCRE2_SPTR p; - for (p = ptr; p < cb.end_pattern; p++) if (*p >= META_END) big32count++; - } -#endif +/* Ensure that the parsed pattern buffer is big enough. For many smaller +patterns the vector on the stack (which was set up above) can be used. */ -/* Ensure that the parsed pattern buffer is big enough. When PCRE2_AUTO_CALLOUT -is set we have to assume a numerical callout (4 elements) for each character -plus one at the end. This is overkill, but memory is plentiful these days. For -many smaller patterns the vector on the stack (which was set up above) can be -used. */ +parsed_size_needed = max_parsed_pattern(ptr, cb.end_pattern, utf, options); -parsed_size_needed = patlen - skipatstart + big32count; +/* Allow for 2x uint32_t at the start and 2 at the end, for +PCRE2_EXTRA_MATCH_WORD or PCRE2_EXTRA_MATCH_LINE (which are exclusive). */ if ((ccontext->extra_options & (PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_MATCH_LINE)) != 0) parsed_size_needed += 4; +/* When PCRE2_AUTO_CALLOUT is set we allow for one callout at the end. */ + if ((options & PCRE2_AUTO_CALLOUT) != 0) - parsed_size_needed = (parsed_size_needed + 1) * 5; + parsed_size_needed += 4; + +parsed_size_needed += 1; /* For the final META_END */ -if (parsed_size_needed >= PARSED_PATTERN_DEFAULT_SIZE) +if (parsed_size_needed > PARSED_PATTERN_DEFAULT_SIZE) { uint32_t *heap_parsed_pattern = ccontext->memctl.malloc( - (parsed_size_needed + 1) * sizeof(uint32_t), ccontext->memctl.memory_data); + parsed_size_needed * sizeof(uint32_t), ccontext->memctl.memory_data); if (heap_parsed_pattern == NULL) { *errorptr = ERR21; @@ -10516,11 +10542,11 @@ if (parsed_size_needed >= PARSED_PATTERN_DEFAULT_SIZE) } cb.parsed_pattern = heap_parsed_pattern; } -cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1; +cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed; /* Do the parsing scan. */ -errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb); +errorcode = parse_regex(ptr, cb.external_options, xoptions, &has_lookbehind, &cb); if (errorcode != 0) goto HAD_CB_ERROR; /* If there are any lookbehinds, scan the parsed pattern to figure out their @@ -10589,7 +10615,7 @@ pptr = cb.parsed_pattern; code = cworkspace; *code = OP_BRA; -(void)compile_regex(cb.external_options, ccontext->extra_options, &code, &pptr, +(void)compile_regex(cb.external_options, xoptions, &code, &pptr, &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, NULL, &cb, &length); @@ -10597,7 +10623,13 @@ if (errorcode != 0) goto HAD_CB_ERROR; /* Offset is in cb.erroroffset */ /* This should be caught in compile_regex(), but just in case... */ +#if defined SUPPORT_WIDE_CHARS +PCRE2_ASSERT((cb.char_lists_size & 0x3) == 0); +if (length > MAX_PATTERN_SIZE || + MAX_PATTERN_SIZE - length < (cb.char_lists_size / sizeof(PCRE2_UCHAR))) +#else if (length > MAX_PATTERN_SIZE) +#endif { errorcode = ERR20; goto HAD_CB_ERROR; @@ -10608,9 +10640,22 @@ block for storing the compiled pattern and names table. Integer overflow should no longer be possible because nowadays we limit the maximum value of cb.names_found and cb.name_entry_size. */ -re_blocksize = sizeof(pcre2_real_code) + - CU2BYTES(length + - (PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size); +re_blocksize = + CU2BYTES((PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size); + +#if defined SUPPORT_WIDE_CHARS +if (cb.char_lists_size != 0) + { +#if PCRE2_CODE_UNIT_WIDTH != 32 + /* Align to 32 bit first. This ensures the + allocated area will also be 32 bit aligned. */ + re_blocksize = (PCRE2_SIZE)CLIST_ALIGN_TO(re_blocksize, sizeof(uint32_t)); +#endif + re_blocksize += cb.char_lists_size; + } +#endif + +re_blocksize += CU2BYTES(length); if (re_blocksize > ccontext->max_pattern_compiled_length) { @@ -10618,6 +10663,7 @@ if (re_blocksize > ccontext->max_pattern_compiled_length) goto HAD_CB_ERROR; } +re_blocksize += sizeof(pcre2_real_code); re = (pcre2_real_code *) ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data); if (re == NULL) @@ -10638,10 +10684,11 @@ re->tables = tables; re->executable_jit = NULL; memset(re->start_bitmap, 0, 32 * sizeof(uint8_t)); re->blocksize = re_blocksize; +re->code_start = re_blocksize - CU2BYTES(length); re->magic_number = MAGIC_NUMBER; re->compile_options = options; re->overall_options = cb.external_options; -re->extra_options = ccontext->extra_options; +re->extra_options = xoptions; re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags; re->limit_heap = limit_heap; re->limit_match = limit_match; @@ -10656,12 +10703,12 @@ re->top_bracket = 0; re->top_backref = 0; re->name_entry_size = cb.name_entry_size; re->name_count = cb.names_found; +re->optimization_flags = optim_flags; /* The basic block is immediately followed by the name table, and the compiled code follows after that. */ -codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) + - re->name_entry_size * re->name_count; +codestart = (PCRE2_UCHAR *)((uint8_t *)re + re->code_start); /* Update the compile data block for the actual compile. The starting points of the name/number translation table and of the code are passed around in the @@ -10676,6 +10723,10 @@ cb.start_code = codestart; cb.req_varyopt = 0; cb.had_accept = FALSE; cb.had_pruneorskip = FALSE; +#ifdef SUPPORT_WIDE_CHARS +cb.char_lists_size = 0; +#endif + /* If any named groups were found, create the name/number table from the list created in the pre-pass. */ @@ -10694,7 +10745,7 @@ of the function here. */ pptr = cb.parsed_pattern; code = (PCRE2_UCHAR *)codestart; *code = OP_BRA; -regexrc = compile_regex(re->overall_options, ccontext->extra_options, &code, +regexrc = compile_regex(re->overall_options, re->extra_options, &code, &pptr, &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, NULL, &cb, NULL); if (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY; @@ -10716,7 +10767,12 @@ memory as unaddressable, so that any out-of-bound reads can be detected. */ *code++ = OP_END; usedlength = code - codestart; -if (usedlength > length) errorcode = ERR23; else +if (usedlength > length) + { + PCRE2_DEBUG_UNREACHABLE(); + errorcode = ERR23; /* Overflow of code block - internal error */ + } +else { re->blocksize -= CU2BYTES(length - usedlength); #ifdef SUPPORT_VALGRIND @@ -10738,9 +10794,9 @@ if (errorcode == 0 && cb.had_recurse) int start = RSCAN_CACHE_SIZE; recurse_cache rc[RSCAN_CACHE_SIZE]; - for (rcode = (PCRE2_UCHAR *)find_recurse(codestart, utf); + for (rcode = find_recurse(codestart, utf); rcode != NULL; - rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf)) + rcode = find_recurse(rcode + 1 + LINK_SIZE, utf)) { int p, groupnumber; @@ -10769,6 +10825,7 @@ if (errorcode == 0 && cb.had_recurse) rgroup = PRIV(find_bracket)(search_from, utf, groupnumber); if (rgroup == NULL) { + PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR53; break; } @@ -10779,7 +10836,7 @@ if (errorcode == 0 && cb.had_recurse) } } - PUT(rcode, 1, rgroup - codestart); + PUT(rcode, 1, (uint32_t)(rgroup - codestart)); } } @@ -10798,10 +10855,14 @@ used in this code because at least one compiler gives a warning about loss of "const" attribute if the cast (PCRE2_UCHAR *)codestart is used directly in the function call. */ -if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0) +if (errorcode == 0 && (optim_flags & PCRE2_OPTIM_AUTO_POSSESS) != 0) { PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart; - if (PRIV(auto_possessify)(temp, &cb) != 0) errorcode = ERR80; + if (PRIV(auto_possessify)(temp, &cb) != 0) + { + PCRE2_DEBUG_UNREACHABLE(); + errorcode = ERR80; + } } /* Failed to compile, or error while post-processing. */ @@ -10814,18 +10875,21 @@ or anything else, such as starting with non-atomic .* when DOTALL is set and there are no occurrences of *PRUNE or *SKIP (though there is an option to disable this case). */ -if ((re->overall_options & PCRE2_ANCHORED) == 0 && - is_anchored(codestart, 0, &cb, 0, FALSE)) - re->overall_options |= PCRE2_ANCHORED; +if ((re->overall_options & PCRE2_ANCHORED) == 0) + { + BOOL dotstar_anchor = ((optim_flags & PCRE2_OPTIM_DOTSTAR_ANCHOR) != 0); + if (is_anchored(codestart, 0, &cb, 0, FALSE, dotstar_anchor)) + re->overall_options |= PCRE2_ANCHORED; + } /* Set up the first code unit or startline flag, the required code unit, and -then study the pattern. This code need not be obeyed if PCRE2_NO_START_OPTIMIZE -is set, as the data it would create will not be used. Note that a first code +then study the pattern. This code need not be obeyed if PCRE2_OPTIM_START_OPTIMIZE +is disabled, as the data it would create will not be used. Note that a first code unit (but not the startline flag) is useful for anchored patterns because it can still give a quick "no match" and also avoid searching for a last code unit. */ -if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) +if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) { int minminlength = 0; /* For minimal minlength from first/required CU */ @@ -10833,8 +10897,19 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) (these are not saved during the compile because they can cause conflicts with actual literals that follow). */ - if (firstcuflags >= REQ_NONE) - firstcu = find_firstassertedcu(codestart, &firstcuflags, 0); + if (firstcuflags >= REQ_NONE) { + uint32_t assertedcuflags = 0; + uint32_t assertedcu = find_firstassertedcu(codestart, &assertedcuflags, 0); + /* It would be wrong to use the asserted first code unit as `firstcu` for + * regexes which are able to match a 1-character string (e.g. /(?=a)b?a/) + * For that example, if we set both firstcu and reqcu to 'a', it would mean + * the subject string needs to be at least 2 characters long, which is wrong. + * With more analysis, we would be able to set firstcu in more cases. */ + if (assertedcuflags < REQ_NONE && assertedcu != reqcu) { + firstcu = assertedcu; + firstcuflags = assertedcuflags; + } + } /* Save the data for a first code unit. The existence of one means the minimum length must be at least 1. */ @@ -10855,8 +10930,8 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) } /* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise. - In 8-bit UTF mode, codepoints in the range 128-255 are introductory code - points and cannot have another case, but if UCP is set they may do. */ + In 8-bit UTF mode, code units in the range 128-255 are introductory code + units and cannot have another case, but if UCP is set they may do. */ #ifdef SUPPORT_UNICODE #if PCRE2_CODE_UNIT_WIDTH == 8 @@ -10877,9 +10952,12 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) non-DOTALL matches when *PRUNE and SKIP are not present. (There is an option that disables this case.) */ - else if ((re->overall_options & PCRE2_ANCHORED) == 0 && - is_startline(codestart, 0, &cb, 0, FALSE)) - re->flags |= PCRE2_STARTLINE; + else if ((re->overall_options & PCRE2_ANCHORED) == 0) + { + BOOL dotstar_anchor = ((optim_flags & PCRE2_OPTIM_DOTSTAR_ANCHOR) != 0); + if (is_startline(codestart, 0, &cb, 0, FALSE, dotstar_anchor)) + re->flags |= PCRE2_STARTLINE; + } /* Handle the "required code unit", if one is set. In the UTF case we can increment the minimum minimum length only if we are sure this really is a @@ -10939,6 +11017,7 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) if (PRIV(study)(re) != 0) { + PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR31; goto HAD_CB_ERROR; } @@ -10961,6 +11040,10 @@ version of the pattern, free it before returning. Also free the list of named groups if a larger one had to be obtained, and likewise the group information vector. */ +#ifdef SUPPORT_UNICODE +PCRE2_ASSERT(cb.cranges == NULL); +#endif + EXIT: #ifdef SUPPORT_VALGRIND if (zero_terminated) VALGRIND_MAKE_MEM_DEFINED(pattern + patlen, CU2BYTES(1)); @@ -10971,6 +11054,7 @@ if (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE) ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data); if (cb.groupinfo != stack_groupinfo) ccontext->memctl.free((void *)cb.groupinfo, ccontext->memctl.memory_data); + return re; /* Will be NULL after an error */ /* Errors discovered in parse_regex() set the offset value in the compile @@ -10983,12 +11067,28 @@ an offset is available in the parsed pattern. */ ptr = pattern + cb.erroroffset; HAD_EARLY_ERROR: +PCRE2_ASSERT(ptr >= pattern); /* Ensure we don't return invalid erroroffset */ +PCRE2_ASSERT(ptr <= (pattern + patlen)); *erroroffset = ptr - pattern; HAD_ERROR: *errorptr = errorcode; pcre2_code_free(re); re = NULL; + +#ifdef SUPPORT_WIDE_CHARS +if (cb.cranges != NULL) + { + class_ranges* cranges = cb.cranges; + do + { + class_ranges* next_cranges = cranges->next; + cb.cx->memctl.free(cranges, cb.cx->memctl.memory_data); + cranges = next_cranges; + } + while (cranges != NULL); + } +#endif goto EXIT; } diff --git a/ext/pcre/pcre2lib/pcre2_compile.h b/ext/pcre/pcre2lib/pcre2_compile.h new file mode 100644 index 0000000000000..c8bf610bed547 --- /dev/null +++ b/ext/pcre/pcre2lib/pcre2_compile.h @@ -0,0 +1,280 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE2 is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifndef PCRE2_COMPILE_H_IDEMPOTENT_GUARD +#define PCRE2_COMPILE_H_IDEMPOTENT_GUARD + +#include "pcre2_internal.h" + +/* Compile time error code numbers. They are given names so that they can more +easily be tracked. When a new number is added, the tables called eint1 and +eint2 in pcre2posix.c may need to be updated, and a new error text must be +added to compile_error_texts in pcre2_error.c. Also, the error codes in +pcre2.h.in must be updated - their values are exactly 100 greater than these +values. */ + +enum { ERR0 = COMPILE_ERROR_BASE, + ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, + ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, + ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, + ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, + ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, + ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, + ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, + ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, + ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, + ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100, + ERR101,ERR102,ERR103,ERR104,ERR105,ERR106,ERR107,ERR108,ERR109,ERR110, + ERR111,ERR112,ERR113,ERR114,ERR115,ERR116 }; + +/* Code values for parsed patterns, which are stored in a vector of 32-bit +unsigned ints. Values less than META_END are literal data values. The coding +for identifying the item is in the top 16-bits, leaving 16 bits for the +additional data that some of them need. The META_CODE, META_DATA, and META_DIFF +macros are used to manipulate parsed pattern elements. + +NOTE: When these definitions are changed, the table of extra lengths for each +code (meta_extra_lengths) must be updated to remain in step. */ + +#define META_END 0x80000000u /* End of pattern */ + +#define META_ALT 0x80010000u /* alternation */ +#define META_ATOMIC 0x80020000u /* atomic group */ +#define META_BACKREF 0x80030000u /* Back ref */ +#define META_BACKREF_BYNAME 0x80040000u /* \k'name' */ +#define META_BIGVALUE 0x80050000u /* Next is a literal > META_END */ +#define META_CALLOUT_NUMBER 0x80060000u /* (?C with numerical argument */ +#define META_CALLOUT_STRING 0x80070000u /* (?C with string argument */ +#define META_CAPTURE 0x80080000u /* Capturing parenthesis */ +#define META_CIRCUMFLEX 0x80090000u /* ^ metacharacter */ +#define META_CLASS 0x800a0000u /* start non-empty class */ +#define META_CLASS_EMPTY 0x800b0000u /* empty class */ +#define META_CLASS_EMPTY_NOT 0x800c0000u /* negative empty class */ +#define META_CLASS_END 0x800d0000u /* end of non-empty class */ +#define META_CLASS_NOT 0x800e0000u /* start non-empty negative class */ +#define META_COND_ASSERT 0x800f0000u /* (?(?assertion)... */ +#define META_COND_DEFINE 0x80100000u /* (?(DEFINE)... */ +#define META_COND_NAME 0x80110000u /* (?()... */ +#define META_COND_NUMBER 0x80120000u /* (?(digits)... */ +#define META_COND_RNAME 0x80130000u /* (?(R&name)... */ +#define META_COND_RNUMBER 0x80140000u /* (?(Rdigits)... */ +#define META_COND_VERSION 0x80150000u /* (?(VERSIONx.y)... */ +#define META_OFFSET 0x80160000u /* Setting offset for various + META codes (e.g. META_SCS_NAME) */ +#define META_SCS 0x80170000u /* (*scan_substring:... */ +#define META_SCS_NAME 0x80180000u /* Next of scan_substring */ +#define META_SCS_NUMBER 0x80190000u /* Next digits of scan_substring */ +#define META_DOLLAR 0x801a0000u /* $ metacharacter */ +#define META_DOT 0x801b0000u /* . metacharacter */ +#define META_ESCAPE 0x801c0000u /* \d and friends */ +#define META_KET 0x801d0000u /* closing parenthesis */ +#define META_NOCAPTURE 0x801e0000u /* no capture parens */ +#define META_OPTIONS 0x801f0000u /* (?i) and friends */ +#define META_POSIX 0x80200000u /* POSIX class item */ +#define META_POSIX_NEG 0x80210000u /* negative POSIX class item */ +#define META_RANGE_ESCAPED 0x80220000u /* range with at least one escape */ +#define META_RANGE_LITERAL 0x80230000u /* range defined literally */ +#define META_RECURSE 0x80240000u /* Recursion */ +#define META_RECURSE_BYNAME 0x80250000u /* (?&name) */ +#define META_SCRIPT_RUN 0x80260000u /* (*script_run:...) */ + +/* These must be kept together to make it easy to check that an assertion +is present where expected in a conditional group. */ + +#define META_LOOKAHEAD 0x80270000u /* (?= */ +#define META_LOOKAHEADNOT 0x80280000u /* (?! */ +#define META_LOOKBEHIND 0x80290000u /* (?<= */ +#define META_LOOKBEHINDNOT 0x802a0000u /* (?>16) + +/* Extended class management flags. */ + +#define CLASS_IS_ECLASS 0x1 + +/* Macro for the highest character value. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define MAX_UCHAR_VALUE 0xffu +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#define MAX_UCHAR_VALUE 0xffffu +#else +#define MAX_UCHAR_VALUE 0xffffffffu +#endif + +#define GET_MAX_CHAR_VALUE(utf) \ + ((utf) ? MAX_UTF_CODE_POINT : MAX_UCHAR_VALUE) + +/* Macro for setting individual bits in class bitmaps. */ + +#define SETBIT(a,b) a[(b) >> 3] |= (uint8_t)(1u << ((b) & 0x7)) + +/* Macro for 8 bit specific checks. */ +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define SELECT_VALUE8(value8, value) (value8) +#else +#define SELECT_VALUE8(value8, value) (value) +#endif + +/* Macro for aligning data. */ +#define CLIST_ALIGN_TO(base, align) \ + ((base + ((size_t)(align) - 1)) & ~((size_t)(align) - 1)) + +/* Structure for holding information about an OP_ECLASS internal operand. +An "operand" here could be just a single OP_[X]CLASS, or it could be some +complex expression; but it's some sequence of ECL_* codes which pushes one +value to the stack. */ +typedef struct { + /* The position of the operand - or NULL if (lengthptr != NULL). */ + PCRE2_UCHAR *code_start; + PCRE2_SIZE length; + /* The operand's type if it is a single code (ECL_XCLASS, ECL_ANY, ECL_NONE); + otherwise zero if the operand is not atomic. */ + uint8_t op_single_type; + /* Regardless of whether it's a single code or not, we fully constant-fold + the bitmap for code points < 256. */ + class_bits_storage bits; +} eclass_op_info; + +/* Macros for the definitions below, to prevent name collisions. */ + +#define _pcre2_posix_class_maps PCRE2_SUFFIX(_pcre2_posix_class_maps) +#define _pcre2_update_classbits PCRE2_SUFFIX(_pcre2_update_classbits_) +#define _pcre2_compile_class_nested PCRE2_SUFFIX(_pcre2_compile_class_nested_) +#define _pcre2_compile_class_not_nested PCRE2_SUFFIX(_pcre2_compile_class_not_nested_) + + +/* Indices of the POSIX classes in posix_names, posix_name_lengths, +posix_class_maps, and posix_substitutes. They must be kept in sync. */ + +#define PC_DIGIT 7 +#define PC_GRAPH 8 +#define PC_PRINT 9 +#define PC_PUNCT 10 +#define PC_XDIGIT 13 + +extern const int PRIV(posix_class_maps)[]; + + +/* Set bits in classbits according to the property type */ + +void PRIV(update_classbits)(uint32_t ptype, uint32_t pdata, BOOL negated, + uint8_t *classbits); + +/* Compile the META codes from start_ptr...end_ptr, writing a single OP_CLASS +OP_CLASS, OP_NCLASS, OP_XCLASS, or OP_ALLANY into pcode. */ + +uint32_t *PRIV(compile_class_not_nested)(uint32_t options, uint32_t xoptions, + uint32_t *start_ptr, PCRE2_UCHAR **pcode, BOOL negate_class, BOOL* has_bitmap, + int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr); + +/* Compile the META codes in pptr into opcodes written to pcode. The pptr must +start at a META_CLASS or META_CLASS_NOT. + +The pptr will be left pointing at the matching META_CLASS_END. */ + +BOOL PRIV(compile_class_nested)(uint32_t options, uint32_t xoptions, + uint32_t **pptr, PCRE2_UCHAR **pcode, int *errorcodeptr, + compile_block *cb, PCRE2_SIZE *lengthptr); + +#endif /* PCRE2_COMPILE_H_IDEMPOTENT_GUARD */ + +/* End of pcre2_compile.h */ diff --git a/ext/pcre/pcre2lib/pcre2_compile_class.c b/ext/pcre/pcre2lib/pcre2_compile_class.c new file mode 100644 index 0000000000000..6a73bb9a71b9e --- /dev/null +++ b/ext/pcre/pcre2lib/pcre2_compile_class.c @@ -0,0 +1,2737 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_compile.h" + +typedef struct { + /* Option bits for eclass. */ + uint32_t options; + uint32_t xoptions; + /* Rarely used members. */ + int *errorcodeptr; + compile_block *cb; + /* Bitmap is needed. */ + BOOL needs_bitmap; +} eclass_context; + +/* Checks the allowed tokens at the end of a class structure in debug mode. +When a new token is not processed by all loops, and the token is equals to +a) one of the cases here: + the compiler will complain about a duplicated case value. +b) none of the cases here: + the loop without the handler will stop with an assertion failure. */ + +#ifdef PCRE2_DEBUG +#define CLASS_END_CASES(meta) \ + default: \ + PCRE2_ASSERT((meta) <= META_END); \ + /* Fall through */ \ + case META_CLASS: \ + case META_CLASS_NOT: \ + case META_CLASS_EMPTY: \ + case META_CLASS_EMPTY_NOT: \ + case META_CLASS_END: \ + case META_ECLASS_AND: \ + case META_ECLASS_OR: \ + case META_ECLASS_SUB: \ + case META_ECLASS_XOR: \ + case META_ECLASS_NOT: +#else +#define CLASS_END_CASES(meta) \ + default: +#endif + +#ifdef SUPPORT_WIDE_CHARS + +/* Heapsort algorithm. */ + +static void do_heapify(uint32_t *buffer, size_t size, size_t i) +{ +size_t max; +size_t left; +size_t right; +uint32_t tmp1, tmp2; + +while (TRUE) + { + max = i; + left = (i << 1) + 2; + right = left + 2; + + if (left < size && buffer[left] > buffer[max]) max = left; + if (right < size && buffer[right] > buffer[max]) max = right; + if (i == max) return; + + /* Swap items. */ + tmp1 = buffer[i]; + tmp2 = buffer[i + 1]; + buffer[i] = buffer[max]; + buffer[i + 1] = buffer[max + 1]; + buffer[max] = tmp1; + buffer[max + 1] = tmp2; + i = max; + } +} + +#ifdef SUPPORT_UNICODE + +#define PARSE_CLASS_UTF 0x1 +#define PARSE_CLASS_CASELESS_UTF 0x2 +#define PARSE_CLASS_RESTRICTED_UTF 0x4 +#define PARSE_CLASS_TURKISH_UTF 0x8 + +/* Get the range of nocase characters which includes the +'c' character passed as argument, or directly follows 'c'. */ + +static const uint32_t* +get_nocase_range(uint32_t c) +{ +uint32_t left = 0; +uint32_t right = PRIV(ucd_nocase_ranges_size); +uint32_t middle; + +if (c > MAX_UTF_CODE_POINT) return PRIV(ucd_nocase_ranges) + right; + +while (TRUE) + { + /* Range end of the middle element. */ + middle = ((left + right) >> 1) | 0x1; + + if (PRIV(ucd_nocase_ranges)[middle] <= c) + left = middle + 1; + else if (middle > 1 && PRIV(ucd_nocase_ranges)[middle - 2] > c) + right = middle - 1; + else + return PRIV(ucd_nocase_ranges) + (middle - 1); + } +} + +/* Get the list of othercase characters, which belongs to the passed range. +Create ranges from these characters, and append them to the buffer argument. */ + +static size_t +utf_caseless_extend(uint32_t start, uint32_t end, uint32_t options, + uint32_t *buffer) +{ +uint32_t new_start = start; +uint32_t new_end = end; +uint32_t c = start; +const uint32_t *list; +uint32_t tmp[3]; +size_t result = 2; +const uint32_t *skip_range = get_nocase_range(c); +uint32_t skip_start = skip_range[0]; + +#if PCRE2_CODE_UNIT_WIDTH == 8 +PCRE2_ASSERT(options & PARSE_CLASS_UTF); +#endif + +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (end > MAX_UTF_CODE_POINT) end = MAX_UTF_CODE_POINT; +#endif + +while (c <= end) + { + uint32_t co; + + if (c > skip_start) + { + c = skip_range[1]; + skip_range += 2; + skip_start = skip_range[0]; + continue; + } + + /* Compute caseless set. */ + + if ((options & (PARSE_CLASS_TURKISH_UTF|PARSE_CLASS_RESTRICTED_UTF)) == + PARSE_CLASS_TURKISH_UTF && + UCD_ANY_I(c)) + { + co = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(c)? 0 : 3); + } + else if ((co = UCD_CASESET(c)) != 0 && + (options & PARSE_CLASS_RESTRICTED_UTF) != 0 && + PRIV(ucd_caseless_sets)[co] < 128) + { + co = 0; /* Ignore the caseless set if it's restricted. */ + } + + if (co != 0) + list = PRIV(ucd_caseless_sets) + co; + else + { + co = UCD_OTHERCASE(c); + list = tmp; + tmp[0] = c; + tmp[1] = NOTACHAR; + + if (co != c) + { + tmp[1] = co; + tmp[2] = NOTACHAR; + } + } + c++; + + /* Add characters. */ + do + { +#if PCRE2_CODE_UNIT_WIDTH == 16 + if (!(options & PARSE_CLASS_UTF) && *list > 0xffff) continue; +#endif + + if (*list < new_start) + { + if (*list + 1 == new_start) + { + new_start--; + continue; + } + } + else if (*list > new_end) + { + if (*list - 1 == new_end) + { + new_end++; + continue; + } + } + else continue; + + result += 2; + if (buffer != NULL) + { + buffer[0] = *list; + buffer[1] = *list; + buffer += 2; + } + } + while (*(++list) != NOTACHAR); + } + + if (buffer != NULL) + { + buffer[0] = new_start; + buffer[1] = new_end; + buffer += 2; + (void)buffer; + } + return result; +} + +#endif + +/* Add a character list to a buffer. */ + +static size_t +append_char_list(const uint32_t *p, uint32_t *buffer) +{ +const uint32_t *n; +size_t result = 0; + +while (*p != NOTACHAR) + { + n = p; + while (n[0] == n[1] - 1) n++; + + PCRE2_ASSERT(*p < 0xffff); + + if (buffer != NULL) + { + buffer[0] = *p; + buffer[1] = *n; + buffer += 2; + } + + result += 2; + p = n + 1; + } + + return result; +} + +static uint32_t +get_highest_char(uint32_t options) +{ +(void)options; /* Avoid compiler warning. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +return MAX_UTF_CODE_POINT; +#else +#ifdef SUPPORT_UNICODE +return GET_MAX_CHAR_VALUE((options & PARSE_CLASS_UTF) != 0); +#else +return MAX_UCHAR_VALUE; +#endif +#endif +} + +/* Add a negated character list to a buffer. */ +static size_t +append_negated_char_list(const uint32_t *p, uint32_t options, uint32_t *buffer) +{ +const uint32_t *n; +uint32_t start = 0; +size_t result = 2; + +PCRE2_ASSERT(*p > 0); + +while (*p != NOTACHAR) + { + n = p; + while (n[0] == n[1] - 1) n++; + + PCRE2_ASSERT(*p < 0xffff); + + if (buffer != NULL) + { + buffer[0] = start; + buffer[1] = *p - 1; + buffer += 2; + } + + result += 2; + start = *n + 1; + p = n + 1; + } + + if (buffer != NULL) + { + buffer[0] = start; + buffer[1] = get_highest_char(options); + buffer += 2; + (void)buffer; + } + + return result; +} + +static uint32_t * +append_non_ascii_range(uint32_t options, uint32_t *buffer) +{ + if (buffer == NULL) return NULL; + + buffer[0] = 0x100; + buffer[1] = get_highest_char(options); + return buffer + 2; +} + +static size_t +parse_class(uint32_t *ptr, uint32_t options, uint32_t *buffer) +{ +size_t total_size = 0; +size_t size; +uint32_t meta_arg; +uint32_t start_char; + +while (TRUE) + { + switch (META_CODE(*ptr)) + { + case META_ESCAPE: + meta_arg = META_DATA(*ptr); + switch (meta_arg) + { + case ESC_D: + case ESC_W: + case ESC_S: + buffer = append_non_ascii_range(options, buffer); + total_size += 2; + break; + + case ESC_h: + size = append_char_list(PRIV(hspace_list), buffer); + total_size += size; + if (buffer != NULL) buffer += size; + break; + + case ESC_H: + size = append_negated_char_list(PRIV(hspace_list), options, buffer); + total_size += size; + if (buffer != NULL) buffer += size; + break; + + case ESC_v: + size = append_char_list(PRIV(vspace_list), buffer); + total_size += size; + if (buffer != NULL) buffer += size; + break; + + case ESC_V: + size = append_negated_char_list(PRIV(vspace_list), options, buffer); + total_size += size; + if (buffer != NULL) buffer += size; + break; + + case ESC_p: + case ESC_P: + ptr++; + if (meta_arg == ESC_p && (*ptr >> 16) == PT_ANY) + { + if (buffer != NULL) + { + buffer[0] = 0; + buffer[1] = get_highest_char(options); + buffer += 2; + } + total_size += 2; + } + break; + } + ptr++; + continue; + case META_POSIX_NEG: + buffer = append_non_ascii_range(options, buffer); + total_size += 2; + ptr += 2; + continue; + case META_POSIX: + ptr += 2; + continue; + case META_BIGVALUE: + /* Character literal */ + ptr++; + break; + CLASS_END_CASES(*ptr) + if (*ptr >= META_END) return total_size; + break; + } + + start_char = *ptr; + + if (ptr[1] == META_RANGE_LITERAL || ptr[1] == META_RANGE_ESCAPED) + { + ptr += 2; + PCRE2_ASSERT(*ptr < META_END || *ptr == META_BIGVALUE); + + if (*ptr == META_BIGVALUE) ptr++; + +#ifdef EBCDIC +#error "Missing EBCDIC support" +#endif + } + +#ifdef SUPPORT_UNICODE + if (options & PARSE_CLASS_CASELESS_UTF) + { + size = utf_caseless_extend(start_char, *ptr++, options, buffer); + if (buffer != NULL) buffer += size; + total_size += size; + continue; + } +#endif + + if (buffer != NULL) + { + buffer[0] = start_char; + buffer[1] = *ptr; + buffer += 2; + } + + ptr++; + total_size += 2; + } + + return total_size; +} + +/* Extra uint32_t values for storing the lengths of range lists in +the worst case. Two uint32_t lengths and a range end for a range +starting before 255 */ +#define CHAR_LIST_EXTRA_SIZE 3 + +/* Starting character values for each character list. */ + +static const uint32_t char_list_starts[] = { +#if PCRE2_CODE_UNIT_WIDTH == 32 + XCL_CHAR_LIST_HIGH_32_START, +#endif +#if PCRE2_CODE_UNIT_WIDTH == 32 || defined SUPPORT_UNICODE + XCL_CHAR_LIST_LOW_32_START, +#endif + XCL_CHAR_LIST_HIGH_16_START, + /* Must be terminated by XCL_CHAR_LIST_LOW_16_START, + which also represents the end of the bitset. */ + XCL_CHAR_LIST_LOW_16_START, +}; + +static class_ranges * +compile_optimize_class(uint32_t *start_ptr, uint32_t options, + uint32_t xoptions, compile_block *cb) +{ +class_ranges* cranges; +uint32_t *ptr; +uint32_t *buffer; +uint32_t *dst; +uint32_t class_options = 0; +size_t range_list_size = 0, total_size, i; +uint32_t tmp1, tmp2; +const uint32_t *char_list_next; +uint16_t *next_char; +uint32_t char_list_start, char_list_end; +uint32_t range_start, range_end; + +#ifdef SUPPORT_UNICODE +if (options & PCRE2_UTF) + class_options |= PARSE_CLASS_UTF; + +if ((options & PCRE2_CASELESS) && (options & (PCRE2_UTF|PCRE2_UCP))) + class_options |= PARSE_CLASS_CASELESS_UTF; + +if (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) + class_options |= PARSE_CLASS_RESTRICTED_UTF; + +if (xoptions & PCRE2_EXTRA_TURKISH_CASING) + class_options |= PARSE_CLASS_TURKISH_UTF; +#endif + +/* Compute required space for the range. */ + +range_list_size = parse_class(start_ptr, class_options, NULL); +PCRE2_ASSERT((range_list_size & 0x1) == 0); + +/* Allocate buffer. The total_size also represents the end of the buffer. */ + +total_size = range_list_size + + ((range_list_size >= 2) ? CHAR_LIST_EXTRA_SIZE : 0); + +cranges = cb->cx->memctl.malloc( + sizeof(class_ranges) + total_size * sizeof(uint32_t), + cb->cx->memctl.memory_data); + +if (cranges == NULL) return NULL; + +cranges->next = NULL; +cranges->range_list_size = (uint16_t)range_list_size; +cranges->char_lists_types = 0; +cranges->char_lists_size = 0; +cranges->char_lists_start = 0; + +if (range_list_size == 0) return cranges; + +buffer = (uint32_t*)(cranges + 1); +parse_class(start_ptr, class_options, buffer); + +/* Using <= instead of == to help static analysis. */ +if (range_list_size <= 2) return cranges; + +/* In-place sorting of ranges. */ + +i = (((range_list_size >> 2) - 1) << 1); +while (TRUE) + { + do_heapify(buffer, range_list_size, i); + if (i == 0) break; + i -= 2; + } + +i = range_list_size - 2; +while (TRUE) + { + tmp1 = buffer[i]; + tmp2 = buffer[i + 1]; + buffer[i] = buffer[0]; + buffer[i + 1] = buffer[1]; + buffer[0] = tmp1; + buffer[1] = tmp2; + + do_heapify(buffer, i, 0); + if (i == 0) break; + i -= 2; + } + +/* Merge ranges whenever possible. */ +dst = buffer; +ptr = buffer + 2; +range_list_size -= 2; + +/* The second condition is a very rare corner case, where the end of the last +range is the maximum character. This range cannot be extended further. */ + +while (range_list_size > 0 && dst[1] != ~(uint32_t)0) + { + if (dst[1] + 1 < ptr[0]) + { + dst += 2; + dst[0] = ptr[0]; + dst[1] = ptr[1]; + } + else if (dst[1] < ptr[1]) dst[1] = ptr[1]; + + ptr += 2; + range_list_size -= 2; + } + +PCRE2_ASSERT(dst[1] <= get_highest_char(class_options)); + +/* When the number of ranges are less than six, +they are not converted to range lists. */ + +ptr = buffer; +while (ptr < dst && ptr[1] < 0x100) ptr += 2; +if (dst - ptr < (2 * (6 - 1))) + { + cranges->range_list_size = (uint16_t)(dst + 2 - buffer); + return cranges; + } + +/* Compute character lists structures. */ + +char_list_next = char_list_starts; +char_list_start = *char_list_next++; +#if PCRE2_CODE_UNIT_WIDTH == 32 +char_list_end = XCL_CHAR_LIST_HIGH_32_END; +#elif defined SUPPORT_UNICODE +char_list_end = XCL_CHAR_LIST_LOW_32_END; +#else +char_list_end = XCL_CHAR_LIST_HIGH_16_END; +#endif +next_char = (uint16_t*)(buffer + total_size); + +tmp1 = 0; +tmp2 = ((sizeof(char_list_starts) / sizeof(uint32_t)) - 1) * XCL_TYPE_BIT_LEN; +PCRE2_ASSERT(tmp2 <= 3 * XCL_TYPE_BIT_LEN && tmp2 >= XCL_TYPE_BIT_LEN); +range_start = dst[0]; +range_end = dst[1]; + +while (TRUE) + { + if (range_start >= char_list_start) + { + if (range_start == range_end || range_end < char_list_end) + { + tmp1++; + next_char--; + + if (char_list_start < XCL_CHAR_LIST_LOW_32_START) + *next_char = (uint16_t)((range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END); + else + *(uint32_t*)(--next_char) = + (range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END; + } + + if (range_start < range_end) + { + if (range_start > char_list_start) + { + tmp1++; + next_char--; + + if (char_list_start < XCL_CHAR_LIST_LOW_32_START) + *next_char = (uint16_t)(range_start << XCL_CHAR_SHIFT); + else + *(uint32_t*)(--next_char) = (range_start << XCL_CHAR_SHIFT); + } + else + cranges->char_lists_types |= XCL_BEGIN_WITH_RANGE << tmp2; + } + + PCRE2_ASSERT((uint32_t*)next_char >= dst + 2); + + if (dst > buffer) + { + dst -= 2; + range_start = dst[0]; + range_end = dst[1]; + continue; + } + + range_start = 0; + range_end = 0; + } + + if (range_end >= char_list_start) + { + PCRE2_ASSERT(range_start < char_list_start); + + if (range_end < char_list_end) + { + tmp1++; + next_char--; + + if (char_list_start < XCL_CHAR_LIST_LOW_32_START) + *next_char = (uint16_t)((range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END); + else + *(uint32_t*)(--next_char) = + (range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END; + + PCRE2_ASSERT((uint32_t*)next_char >= dst + 2); + } + + cranges->char_lists_types |= XCL_BEGIN_WITH_RANGE << tmp2; + } + + if (tmp1 >= XCL_ITEM_COUNT_MASK) + { + cranges->char_lists_types |= XCL_ITEM_COUNT_MASK << tmp2; + next_char--; + + if (char_list_start < XCL_CHAR_LIST_LOW_32_START) + *next_char = (uint16_t)tmp1; + else + *(uint32_t*)(--next_char) = tmp1; + } + else + cranges->char_lists_types |= tmp1 << tmp2; + + if (range_start < XCL_CHAR_LIST_LOW_16_START) break; + + PCRE2_ASSERT(tmp2 >= XCL_TYPE_BIT_LEN); + char_list_end = char_list_start - 1; + char_list_start = *char_list_next++; + tmp1 = 0; + tmp2 -= XCL_TYPE_BIT_LEN; + } + +if (dst[0] < XCL_CHAR_LIST_LOW_16_START) dst += 2; +PCRE2_ASSERT((uint16_t*)dst <= next_char); + +cranges->char_lists_size = + (size_t)((uint8_t*)(buffer + total_size) - (uint8_t*)next_char); +cranges->char_lists_start = (size_t)((uint8_t*)next_char - (uint8_t*)buffer); +cranges->range_list_size = (uint16_t)(dst - buffer); +return cranges; +} + +#endif /* SUPPORT_WIDE_CHARS */ + +#ifdef SUPPORT_UNICODE + +void PRIV(update_classbits)(uint32_t ptype, uint32_t pdata, BOOL negated, + uint8_t *classbits) +{ +/* Update PRIV(xclass) when this function is changed. */ +int c, chartype; +const ucd_record *prop; +uint32_t gentype; +BOOL set_bit; + +if (ptype == PT_ANY) + { + if (!negated) memset(classbits, 0xff, 32); + return; + } + +for (c = 0; c < 256; c++) + { + prop = GET_UCD(c); + set_bit = FALSE; + (void)set_bit; + + switch (ptype) + { + case PT_LAMP: + chartype = prop->chartype; + set_bit = (chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt); + break; + + case PT_GC: + set_bit = (PRIV(ucp_gentype)[prop->chartype] == pdata); + break; + + case PT_PC: + set_bit = (prop->chartype == pdata); + break; + + case PT_SC: + set_bit = (prop->script == pdata); + break; + + case PT_SCX: + set_bit = (prop->script == pdata || + MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), pdata) != 0); + break; + + case PT_ALNUM: + gentype = PRIV(ucp_gentype)[prop->chartype]; + set_bit = (gentype == ucp_L || gentype == ucp_N); + break; + + case PT_SPACE: /* Perl space */ + case PT_PXSPACE: /* POSIX space */ + switch(c) + { + HSPACE_BYTE_CASES: + VSPACE_BYTE_CASES: + set_bit = TRUE; + break; + + default: + set_bit = (PRIV(ucp_gentype)[prop->chartype] == ucp_Z); + break; + } + break; + + case PT_WORD: + chartype = prop->chartype; + gentype = PRIV(ucp_gentype)[chartype]; + set_bit = (gentype == ucp_L || gentype == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); + break; + + case PT_UCNC: + set_bit = (c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || + c == CHAR_GRAVE_ACCENT || c >= 0xa0); + break; + + case PT_BIDICL: + set_bit = (UCD_BIDICLASS_PROP(prop) == pdata); + break; + + case PT_BOOL: + set_bit = MAPBIT(PRIV(ucd_boolprop_sets) + + UCD_BPROPS_PROP(prop), pdata) != 0; + break; + + case PT_PXGRAPH: + chartype = prop->chartype; + gentype = PRIV(ucp_gentype)[chartype]; + set_bit = (gentype != ucp_Z && (gentype != ucp_C || chartype == ucp_Cf)); + break; + + case PT_PXPRINT: + chartype = prop->chartype; + set_bit = (chartype != ucp_Zl && chartype != ucp_Zp && + (PRIV(ucp_gentype)[chartype] != ucp_C || chartype == ucp_Cf)); + break; + + case PT_PXPUNCT: + gentype = PRIV(ucp_gentype)[prop->chartype]; + set_bit = (gentype == ucp_P || (c < 128 && gentype == ucp_S)); + break; + + default: + PCRE2_ASSERT(ptype == PT_PXXDIGIT); + set_bit = (c >= CHAR_0 && c <= CHAR_9) || + (c >= CHAR_A && c <= CHAR_F) || + (c >= CHAR_a && c <= CHAR_f); + break; + } + + if (negated) set_bit = !set_bit; + if (set_bit) *classbits |= (uint8_t)(1 << (c & 0x7)); + if ((c & 0x7) == 0x7) classbits++; + } +} + +#endif /* SUPPORT_UNICODE */ + + + +#ifdef SUPPORT_WIDE_CHARS + +/************************************************* +* XClass related properties * +*************************************************/ + +/* XClass needs to be generated. */ +#define XCLASS_REQUIRED 0x1 +/* XClass has 8 bit character. */ +#define XCLASS_HAS_8BIT_CHARS 0x2 +/* XClass has properties. */ +#define XCLASS_HAS_PROPS 0x4 +/* XClass has character lists. */ +#define XCLASS_HAS_CHAR_LISTS 0x8 +/* XClass matches to all >= 256 characters. */ +#define XCLASS_HIGH_ANY 0x10 + +#endif + + +/************************************************* +* Internal entry point for add range to class * +*************************************************/ + +/* This function sets the overall range for characters < 256. +It also handles non-utf case folding. + +Arguments: + options the options bits + xoptions the extra options bits + cb compile data + start start of range character + end end of range character + +Returns: cb->classbits is updated +*/ + +static void +add_to_class(uint32_t options, uint32_t xoptions, compile_block *cb, + uint32_t start, uint32_t end) +{ +uint8_t *classbits = cb->classbits.classbits; +uint32_t c, byte_start, byte_end; +uint32_t classbits_end = (end <= 0xff ? end : 0xff); + +/* If caseless matching is required, scan the range and process alternate +cases. In Unicode, there are 8-bit characters that have alternate cases that +are greater than 255 and vice-versa (though these may be ignored if caseless +restriction is in force). Sometimes we can just extend the original range. */ + +if ((options & PCRE2_CASELESS) != 0) + { +#ifdef SUPPORT_UNICODE + /* UTF mode. This branch is taken if we don't support wide characters (e.g. + 8-bit library, without UTF), but we do treat those characters as Unicode + (if UCP flag is set). In this case, we only need to expand the character class + set to include the case pairs which are in the 0-255 codepoint range. */ + if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0) + { + BOOL turkish_i = (xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == + PCRE2_EXTRA_TURKISH_CASING; + if (start < 128) + { + uint32_t lo_end = (classbits_end < 127 ? classbits_end : 127); + for (c = start; c <= lo_end; c++) + { + if (turkish_i && UCD_ANY_I(c)) continue; + SETBIT(classbits, cb->fcc[c]); + } + } + if (classbits_end >= 128) + { + uint32_t hi_start = (start > 128 ? start : 128); + for (c = hi_start; c <= classbits_end; c++) + { + uint32_t co = UCD_OTHERCASE(c); + if (co <= 0xff) SETBIT(classbits, co); + } + } + } + + else +#endif /* SUPPORT_UNICODE */ + + /* Not UTF mode */ + { + for (c = start; c <= classbits_end; c++) + SETBIT(classbits, cb->fcc[c]); + } + } + +/* Use the bitmap for characters < 256. Otherwise use extra data. */ + +byte_start = (start + 7) >> 3; +byte_end = (classbits_end + 1) >> 3; + +if (byte_start >= byte_end) + { + for (c = start; c <= classbits_end; c++) + /* Regardless of start, c will always be <= 255. */ + SETBIT(classbits, c); + return; + } + +for (c = byte_start; c < byte_end; c++) + classbits[c] = 0xff; + +byte_start <<= 3; +byte_end <<= 3; + +for (c = start; c < byte_start; c++) + SETBIT(classbits, c); + +for (c = byte_end; c <= classbits_end; c++) + SETBIT(classbits, c); +} + + +#if PCRE2_CODE_UNIT_WIDTH == 8 +/************************************************* +* Internal entry point for add list to class * +*************************************************/ + +/* This function is used for adding a list of horizontal or vertical whitespace +characters to a class. The list must be in order so that ranges of characters +can be detected and handled appropriately. This function sets the overall range +so that the internal functions can try to avoid duplication when handling +case-independence. + +Arguments: + options the options bits + xoptions the extra options bits + cb contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + +Returns: cb->classbits is updated +*/ + +static void +add_list_to_class(uint32_t options, uint32_t xoptions, compile_block *cb, + const uint32_t *p) +{ +while (p[0] < 256) + { + unsigned int n = 0; + + while(p[n+1] == p[0] + n + 1) n++; + add_to_class(options, xoptions, cb, p[0], p[n]); + + p += n + 1; + } +} + + + +/************************************************* +* Add characters not in a list to a class * +*************************************************/ + +/* This function is used for adding the complement of a list of horizontal or +vertical whitespace to a class. The list must be in order. + +Arguments: + options the options bits + xoptions the extra options bits + cb contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + +Returns: cb->classbits is updated +*/ + +static void +add_not_list_to_class(uint32_t options, uint32_t xoptions, compile_block *cb, + const uint32_t *p) +{ +if (p[0] > 0) + add_to_class(options, xoptions, cb, 0, p[0] - 1); +while (p[0] < 256) + { + while (p[1] == p[0] + 1) p++; + add_to_class(options, xoptions, cb, p[0] + 1, (p[1] > 255) ? 255 : p[1] - 1); + p++; + } +} +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + + + +/************************************************* +* Main entry-point to compile a character class * +*************************************************/ + +/* This function consumes a "leaf", which is a set of characters that will +become a single OP_CLASS OP_NCLASS, OP_XCLASS, or OP_ALLANY. */ + +uint32_t * +PRIV(compile_class_not_nested)(uint32_t options, uint32_t xoptions, + uint32_t *start_ptr, PCRE2_UCHAR **pcode, BOOL negate_class, BOOL* has_bitmap, + int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr) +{ +uint32_t *pptr = start_ptr; +PCRE2_UCHAR *code = *pcode; +BOOL should_flip_negation; +const uint8_t *cbits = cb->cbits; +/* Some functions such as add_to_class() or eclass processing +expects that the bitset is stored in cb->classbits.classbits. */ +uint8_t *const classbits = cb->classbits.classbits; + +#ifdef SUPPORT_UNICODE +BOOL utf = (options & PCRE2_UTF) != 0; +#else /* No Unicode support */ +BOOL utf = FALSE; +#endif + +/* Helper variables for OP_XCLASS opcode (for characters > 255). */ + +#ifdef SUPPORT_WIDE_CHARS +uint32_t xclass_props; +PCRE2_UCHAR *class_uchardata; +class_ranges* cranges; +#endif + +/* If an XClass contains a negative special such as \S, we need to flip the +negation flag at the end, so that support for characters > 255 works correctly +(they are all included in the class). An XClass may need to insert specific +matching or non-matching code for wide characters. +*/ + +should_flip_negation = FALSE; + +/* XClass will be used when characters > 255 might match. */ + +#ifdef SUPPORT_WIDE_CHARS +xclass_props = 0; + +#if PCRE2_CODE_UNIT_WIDTH == 8 +cranges = NULL; + +if (utf) +#endif + { + if (lengthptr != NULL) + { + cranges = compile_optimize_class(pptr, options, xoptions, cb); + + if (cranges == NULL) + { + *errorcodeptr = ERR21; + return NULL; + } + + /* Caching the pre-processed character ranges. */ + if (cb->next_cranges != NULL) + cb->next_cranges->next = cranges; + else + cb->cranges = cranges; + + cb->next_cranges = cranges; + } + else + { + /* Reuse the pre-processed character ranges. */ + cranges = cb->cranges; + PCRE2_ASSERT(cranges != NULL); + cb->cranges = cranges->next; + } + + if (cranges->range_list_size > 0) + { + const uint32_t *ranges = (const uint32_t*)(cranges + 1); + + if (ranges[0] <= 255) + xclass_props |= XCLASS_HAS_8BIT_CHARS; + + if (ranges[cranges->range_list_size - 1] == GET_MAX_CHAR_VALUE(utf) && + ranges[cranges->range_list_size - 2] <= 256) + xclass_props |= XCLASS_HIGH_ANY; + } + } + +class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ +#endif /* SUPPORT_WIDE_CHARS */ + +/* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map +in a temporary bit of memory, in case the class contains fewer than two +8-bit characters because in that case the compiled code doesn't use the bit +map. */ + +memset(classbits, 0, 32); + +/* Process items until end_ptr is reached. */ + +while (TRUE) + { + uint32_t meta = *(pptr++); + BOOL local_negate; + int posix_class; + int taboffset, tabopt; + class_bits_storage pbits; + uint32_t escape, c; + + /* Handle POSIX classes such as [:alpha:] etc. */ + switch (META_CODE(meta)) + { + case META_POSIX: + case META_POSIX_NEG: + + local_negate = (meta == META_POSIX_NEG); + posix_class = *(pptr++); + + if (local_negate) should_flip_negation = TRUE; /* Note negative special */ + + /* If matching is caseless, upper and lower are converted to alpha. + This relies on the fact that the class table starts with alpha, + lower, upper as the first 3 entries. */ + + if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2) + posix_class = 0; + + /* When PCRE2_UCP is set, some of the POSIX classes are converted to + different escape sequences that use Unicode properties \p or \P. + Others that are not available via \p or \P have to generate + XCL_PROP/XCL_NOTPROP directly, which is done here. */ + +#ifdef SUPPORT_UNICODE + /* TODO This entire block of code here appears to be unreachable!? I simply + can't see how it can be hit, given that the frontend parser doesn't emit + META_POSIX for GRAPH/PRINT/PUNCT when UCP is set. */ + if ((options & PCRE2_UCP) != 0 && + (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0) + { + uint32_t ptype; + + switch(posix_class) + { + case PC_GRAPH: + case PC_PRINT: + case PC_PUNCT: + ptype = (posix_class == PC_GRAPH)? PT_PXGRAPH : + (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT; + + PRIV(update_classbits)(ptype, 0, local_negate, classbits); + + if ((xclass_props & XCLASS_HIGH_ANY) == 0) + { + if (lengthptr != NULL) + *lengthptr += 3; + else + { + *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; + *class_uchardata++ = (PCRE2_UCHAR)ptype; + *class_uchardata++ = 0; + } + xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_PROPS; + } + continue; + + /* For the other POSIX classes (ex: ascii) we are going to + fall through to the non-UCP case and build a bit map for + characters with code points less than 256. However, if we are in + a negated POSIX class, characters with code points greater than + 255 must either all match or all not match, depending on whether + the whole class is not or is negated. For example, for + [[:^ascii:]... they must all match, whereas for [^[:^ascii:]... + they must not. + + In the special case where there are no xclass items, this is + automatically handled by the use of OP_CLASS or OP_NCLASS, but an + explicit range is needed for OP_XCLASS. Setting a flag here + causes the range to be generated later when it is known that + OP_XCLASS is required. In the 8-bit library this is relevant only in + utf mode, since no wide characters can exist otherwise. */ + + default: + break; + } + } +#endif /* SUPPORT_UNICODE */ + + /* In the non-UCP case, or when UCP makes no difference, we build the + bit map for the POSIX class in a chunk of local store because we may + be adding and subtracting from it, and we don't want to subtract bits + that may be in the main map already. At the end we or the result into + the bit map that is being built. */ + + posix_class *= 3; + + /* Copy in the first table (always present) */ + + memcpy(pbits.classbits, cbits + PRIV(posix_class_maps)[posix_class], 32); + + /* If there is a second table, add or remove it as required. */ + + taboffset = PRIV(posix_class_maps)[posix_class + 1]; + tabopt = PRIV(posix_class_maps)[posix_class + 2]; + + if (taboffset >= 0) + { + if (tabopt >= 0) + for (int i = 0; i < 32; i++) + pbits.classbits[i] |= cbits[i + taboffset]; + else + for (int i = 0; i < 32; i++) + pbits.classbits[i] &= (uint8_t)(~cbits[i + taboffset]); + } + + /* Now see if we need to remove any special characters. An option + value of 1 removes vertical space and 2 removes underscore. */ + + if (tabopt < 0) tabopt = -tabopt; + if (tabopt == 1) pbits.classbits[1] &= ~0x3c; + else if (tabopt == 2) pbits.classbits[11] &= 0x7f; + + /* Add the POSIX table or its complement into the main table that is + being built and we are done. */ + + { + uint32_t *classwords = cb->classbits.classwords; + + if (local_negate) + for (int i = 0; i < 8; i++) + classwords[i] |= (uint32_t)(~pbits.classwords[i]); + else + for (int i = 0; i < 8; i++) + classwords[i] |= pbits.classwords[i]; + } + +#ifdef SUPPORT_WIDE_CHARS + /* Every class contains at least one < 256 character. */ + xclass_props |= XCLASS_HAS_8BIT_CHARS; +#endif + continue; /* End of POSIX handling */ + + /* Other than POSIX classes, the only items we should encounter are + \d-type escapes and literal characters (possibly as ranges). */ + case META_BIGVALUE: + meta = *(pptr++); + break; + + case META_ESCAPE: + escape = META_DATA(meta); + + switch(escape) + { + case ESC_d: + for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit]; + break; + + case ESC_D: + should_flip_negation = TRUE; + for (int i = 0; i < 32; i++) + classbits[i] |= (uint8_t)(~cbits[i+cbit_digit]); + break; + + case ESC_w: + for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word]; + break; + + case ESC_W: + should_flip_negation = TRUE; + for (int i = 0; i < 32; i++) + classbits[i] |= (uint8_t)(~cbits[i+cbit_word]); + break; + + /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl + 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was + previously set by something earlier in the character class. + Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so + we could just adjust the appropriate bit. From PCRE 8.34 we no + longer treat \s and \S specially. */ + + case ESC_s: + for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space]; + break; + + case ESC_S: + should_flip_negation = TRUE; + for (int i = 0; i < 32; i++) + classbits[i] |= (uint8_t)(~cbits[i+cbit_space]); + break; + + /* When adding the horizontal or vertical space lists to a class, or + their complements, disable PCRE2_CASELESS, because it justs wastes + time, and in the "not-x" UTF cases can create unwanted duplicates in + the XCLASS list (provoked by characters that have more than one other + case and by both cases being in the same "not-x" sublist). */ + + case ESC_h: +#if PCRE2_CODE_UNIT_WIDTH == 8 +#ifdef SUPPORT_UNICODE + if (cranges != NULL) break; +#endif + add_list_to_class(options & ~PCRE2_CASELESS, xoptions, + cb, PRIV(hspace_list)); +#else + PCRE2_ASSERT(cranges != NULL); +#endif + break; + + case ESC_H: +#if PCRE2_CODE_UNIT_WIDTH == 8 +#ifdef SUPPORT_UNICODE + if (cranges != NULL) break; +#endif + add_not_list_to_class(options & ~PCRE2_CASELESS, xoptions, + cb, PRIV(hspace_list)); +#else + PCRE2_ASSERT(cranges != NULL); +#endif + break; + + case ESC_v: +#if PCRE2_CODE_UNIT_WIDTH == 8 +#ifdef SUPPORT_UNICODE + if (cranges != NULL) break; +#endif + add_list_to_class(options & ~PCRE2_CASELESS, xoptions, + cb, PRIV(vspace_list)); +#else + PCRE2_ASSERT(cranges != NULL); +#endif + break; + + case ESC_V: +#if PCRE2_CODE_UNIT_WIDTH == 8 +#ifdef SUPPORT_UNICODE + if (cranges != NULL) break; +#endif + add_not_list_to_class(options & ~PCRE2_CASELESS, xoptions, + cb, PRIV(vspace_list)); +#else + PCRE2_ASSERT(cranges != NULL); +#endif + break; + + /* If Unicode is not supported, \P and \p are not allowed and are + faulted at parse time, so will never appear here. */ + +#ifdef SUPPORT_UNICODE + case ESC_p: + case ESC_P: + { + uint32_t ptype = *pptr >> 16; + uint32_t pdata = *(pptr++) & 0xffff; + + /* The "Any" is processed by PRIV(update_classbits)(). */ + if (ptype == PT_ANY) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (!utf && escape == ESC_p) memset(classbits, 0xff, 32); +#endif + continue; + } + + PRIV(update_classbits)(ptype, pdata, (escape == ESC_P), classbits); + + if ((xclass_props & XCLASS_HIGH_ANY) == 0) + { + if (lengthptr != NULL) + *lengthptr += 3; + else + { + *class_uchardata++ = (escape == ESC_p)? XCL_PROP : XCL_NOTPROP; + *class_uchardata++ = ptype; + *class_uchardata++ = pdata; + } + xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_PROPS; + } + } + continue; +#endif + } + +#ifdef SUPPORT_WIDE_CHARS + /* Every non-property class contains at least one < 256 character. */ + xclass_props |= XCLASS_HAS_8BIT_CHARS; +#endif + /* End handling \d-type escapes */ + continue; + + CLASS_END_CASES(meta) + /* Literals. */ + if (meta < META_END) break; + /* Non-literals: end of class contents. */ + goto END_PROCESSING; + } + + /* A literal character may be followed by a range meta. At parse time + there are checks for out-of-order characters, for ranges where the two + characters are equal, and for hyphens that cannot indicate a range. At + this point, therefore, no checking is needed. */ + + c = meta; + + /* Remember if \r or \n were explicitly used */ + + if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; + + /* Process a character range */ + + if (*pptr == META_RANGE_LITERAL || *pptr == META_RANGE_ESCAPED) + { + uint32_t d; + +#ifdef EBCDIC + BOOL range_is_literal = (*pptr == META_RANGE_LITERAL); +#endif + ++pptr; + d = *(pptr++); + if (d == META_BIGVALUE) d = *(pptr++); + + /* Remember an explicit \r or \n, and add the range to the class. */ + + if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#ifdef SUPPORT_UNICODE + if (cranges != NULL) continue; + xclass_props |= XCLASS_HAS_8BIT_CHARS; +#endif + + /* In an EBCDIC environment, Perl treats alphabetic ranges specially + because there are holes in the encoding, and simply using the range + A-Z (for example) would include the characters in the holes. This + applies only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */ + +#ifdef EBCDIC + if (range_is_literal && + (cb->ctypes[c] & ctype_letter) != 0 && + (cb->ctypes[d] & ctype_letter) != 0 && + (c <= CHAR_z) == (d <= CHAR_z)) + { + uint32_t uc = (d <= CHAR_z)? 0 : 64; + uint32_t C = c - uc; + uint32_t D = d - uc; + + if (C <= CHAR_i) + { + add_to_class(options, xoptions, cb, C + uc, + ((D < CHAR_i)? D : CHAR_i) + uc); + C = CHAR_j; + } + + if (C <= D && C <= CHAR_r) + { + add_to_class(options, xoptions, cb, C + uc, + ((D < CHAR_r)? D : CHAR_r) + uc); + C = CHAR_s; + } + + if (C <= D) + add_to_class(options, xoptions, cb, C + uc, D + uc); + } + else +#endif + /* Not an EBCDIC special range */ + + add_to_class(options, xoptions, cb, c, d); +#else + PCRE2_ASSERT(cranges != NULL); +#endif + continue; + } /* End of range handling */ + + /* Character ranges are ignored when class_ranges is present. */ +#if PCRE2_CODE_UNIT_WIDTH == 8 +#ifdef SUPPORT_UNICODE + if (cranges != NULL) continue; + xclass_props |= XCLASS_HAS_8BIT_CHARS; +#endif + /* Handle a single character. */ + + add_to_class(options, xoptions, cb, meta, meta); +#else + PCRE2_ASSERT(cranges != NULL); +#endif + } /* End of main class-processing loop */ + +END_PROCESSING: + +#ifdef SUPPORT_WIDE_CHARS +PCRE2_ASSERT((xclass_props & XCLASS_HAS_PROPS) == 0 || + (xclass_props & XCLASS_HIGH_ANY) == 0); + +if (cranges != NULL) + { + uint32_t *range = (uint32_t*)(cranges + 1); + uint32_t *end = range + cranges->range_list_size; + + while (range < end && range[0] < 256) + { + PCRE2_ASSERT((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0); + /* Add range to bitset. If we are in UTF or UCP mode, then clear the + caseless bit, because the cranges handle caselessness (only) in this + condition; see the condition for PARSE_CLASS_CASELESS_UTF in + compile_optimize_class(). */ + add_to_class(((options & (PCRE2_UTF|PCRE2_UCP)) != 0)? + (options & ~PCRE2_CASELESS) : options, xoptions, cb, range[0], range[1]); + + if (range[1] > 255) break; + range += 2; + } + + if (cranges->char_lists_size > 0) + { + /* The cranges structure is still used and freed later. */ + PCRE2_ASSERT((xclass_props & XCLASS_HIGH_ANY) == 0); + xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_CHAR_LISTS; + } + else + { + if ((xclass_props & XCLASS_HIGH_ANY) != 0) + { + PCRE2_ASSERT(range + 2 == end && range[0] <= 256 && + range[1] >= GET_MAX_CHAR_VALUE(utf)); + should_flip_negation = TRUE; + range = end; + } + + while (range < end) + { + uint32_t range_start = range[0]; + uint32_t range_end = range[1]; + + range += 2; + xclass_props |= XCLASS_REQUIRED; + + if (range_start < 256) range_start = 256; + + if (lengthptr != NULL) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + *lengthptr += 1; + + if (range_start < range_end) + *lengthptr += PRIV(ord2utf)(range_start, class_uchardata); + + *lengthptr += PRIV(ord2utf)(range_end, class_uchardata); + continue; + } +#endif /* SUPPORT_UNICODE */ + + *lengthptr += range_start < range_end ? 3 : 2; + continue; + } + +#ifdef SUPPORT_UNICODE + if (utf) + { + if (range_start < range_end) + { + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(range_start, class_uchardata); + } + else + *class_uchardata++ = XCL_SINGLE; + + class_uchardata += PRIV(ord2utf)(range_end, class_uchardata); + continue; + } +#endif /* SUPPORT_UNICODE */ + + /* Without UTF support, character values are constrained + by the bit length, and can only be > 256 for 16-bit and + 32-bit libraries. */ +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (range_start < range_end) + { + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = range_start; + } + else + *class_uchardata++ = XCL_SINGLE; + + *class_uchardata++ = range_end; +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + } + + if (lengthptr == NULL) + cb->cx->memctl.free(cranges, cb->cx->memctl.memory_data); + } + } +#endif /* SUPPORT_WIDE_CHARS */ + +/* If there are characters with values > 255, or Unicode property settings +(\p or \P), we have to compile an extended class, with its own opcode, +unless there were no property settings and there was a negated special such +as \S in the class, and PCRE2_UCP is not set, because in that case all +characters > 255 are in or not in the class, so any that were explicitly +given as well can be ignored. + +In the UCP case, if certain negated POSIX classes (ex: [:^ascii:]) were +were present in a class, we either have to match or not match all wide +characters (depending on whether the whole class is or is not negated). +This requirement is indicated by match_all_or_no_wide_chars being true. +We do this by including an explicit range, which works in both cases. +This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there +cannot be any wide characters in 8-bit non-UTF mode. + +When there *are* properties in a positive UTF-8 or any 16-bit or 32_bit +class where \S etc is present without PCRE2_UCP, causing an extended class +to be compiled, we make sure that all characters > 255 are included by +forcing match_all_or_no_wide_chars to be true. + +If, when generating an xclass, there are no characters < 256, we can omit +the bitmap in the actual compiled code. */ + +#ifdef SUPPORT_WIDE_CHARS /* Defined for 16/32 bits, or 8-bit with Unicode */ +if ((xclass_props & XCLASS_REQUIRED) != 0) + { + PCRE2_UCHAR *previous = code; + + if ((xclass_props & XCLASS_HAS_CHAR_LISTS) == 0) + *class_uchardata++ = XCL_END; /* Marks the end of extra data */ + *code++ = OP_XCLASS; + code += LINK_SIZE; + *code = negate_class? XCL_NOT:0; + if ((xclass_props & XCLASS_HAS_PROPS) != 0) *code |= XCL_HASPROP; + + /* If the map is required, move up the extra data to make room for it; + otherwise just move the code pointer to the end of the extra data. */ + + if ((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0 || has_bitmap != NULL) + { + if (negate_class) + { + uint32_t *classwords = cb->classbits.classwords; + for (int i = 0; i < 8; i++) classwords[i] = ~classwords[i]; + } + + if (has_bitmap == NULL) + { + *code++ |= XCL_MAP; + (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, + CU2BYTES(class_uchardata - code)); + memcpy(code, classbits, 32); + code = class_uchardata + (32 / sizeof(PCRE2_UCHAR)); + } + else + { + code = class_uchardata; + if ((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0) + *has_bitmap = TRUE; + } + } + else code = class_uchardata; + + if ((xclass_props & XCLASS_HAS_CHAR_LISTS) != 0) + { + /* Char lists size is an even number, because all items are 16 or 32 + bit values. The character list data is always aligned to 32 bits. */ + size_t char_lists_size = cranges->char_lists_size; + PCRE2_ASSERT((char_lists_size & 0x1) == 0 && + (cb->char_lists_size & 0x3) == 0); + + if (lengthptr != NULL) + { + char_lists_size = CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t)); + +#if PCRE2_CODE_UNIT_WIDTH == 8 + *lengthptr += 2 + LINK_SIZE; +#else + *lengthptr += 1 + LINK_SIZE; +#endif + + cb->char_lists_size += char_lists_size; + + char_lists_size /= sizeof(PCRE2_UCHAR); + + /* Storage space for character lists is included + in the maximum pattern size. */ + if (*lengthptr > MAX_PATTERN_SIZE || + MAX_PATTERN_SIZE - *lengthptr < char_lists_size) + { + *errorcodeptr = ERR20; /* Pattern is too large */ + return NULL; + } + } + else + { + uint8_t *data; + + PCRE2_ASSERT(cranges->char_lists_types <= XCL_TYPE_MASK); +#if PCRE2_CODE_UNIT_WIDTH == 8 + /* Encode as high / low bytes. */ + code[0] = (uint8_t)(XCL_LIST | + (cranges->char_lists_types >> 8)); + code[1] = (uint8_t)cranges->char_lists_types; + code += 2; +#else + *code++ = (PCRE2_UCHAR)(XCL_LIST | cranges->char_lists_types); +#endif + + /* Character lists are stored in backwards direction from + byte code start. The non-dfa/dfa matchers can access these + lists using the byte code start stored in match blocks. + Each list is aligned to 32 bit with an optional unused + 16 bit value at the beginning of the character list. */ + + cb->char_lists_size += char_lists_size; + data = (uint8_t*)cb->start_code - cb->char_lists_size; + + memcpy(data, (uint8_t*)(cranges + 1) + cranges->char_lists_start, + char_lists_size); + + /* Since character lists total size is less than MAX_PATTERN_SIZE, + their starting offset fits into a value which size is LINK_SIZE. */ + + char_lists_size = cb->char_lists_size; + PUT(code, 0, (uint32_t)(char_lists_size >> 1)); + code += LINK_SIZE; + +#if defined PCRE2_DEBUG || defined SUPPORT_VALGRIND + if ((char_lists_size & 0x2) != 0) + { + /* In debug the unused 16 bit value is set + to a fixed value and marked unused. */ + ((uint16_t*)data)[-1] = 0x5555; +#ifdef SUPPORT_VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(data - 2, 2); +#endif + } +#endif + + cb->char_lists_size = + CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t)); + + cb->cx->memctl.free(cranges, cb->cx->memctl.memory_data); + } + } + + /* Now fill in the complete length of the item */ + + PUT(previous, 1, (int)(code - previous)); + goto DONE; /* End of class handling */ + } +#endif /* SUPPORT_WIDE_CHARS */ + +/* If there are no characters > 255, or they are all to be included or +excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the +whole class was negated and whether there were negative specials such as \S +(non-UCP) in the class. Then copy the 32-byte map into the code vector, +negating it if necessary. */ + +if (negate_class) + { + uint32_t *classwords = cb->classbits.classwords; + + for (int i = 0; i < 8; i++) classwords[i] = ~classwords[i]; + } + +if ((SELECT_VALUE8(!utf, 0) || negate_class != should_flip_negation) && + cb->classbits.classwords[0] == ~(uint32_t)0) + { + const uint32_t *classwords = cb->classbits.classwords; + int i; + + for (i = 0; i < 8; i++) + if (classwords[i] != ~(uint32_t)0) break; + + if (i == 8) + { + *code++ = OP_ALLANY; + goto DONE; /* End of class handling */ + } + } + +*code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; +memcpy(code, classbits, 32); +code += 32 / sizeof(PCRE2_UCHAR); + +DONE: +*pcode = code; +return pptr - 1; +} + + + +/* ===================================================================*/ +/* Here follows a block of ECLASS-compiling functions. You may well want to +read them from top to bottom; they are ordered from leafmost (at the top) to +outermost parser (at the bottom of the file). */ + +/* This function folds one operand using the negation operator. +The new, combined chunk of stack code is written out to *pop_info. */ + +static void +fold_negation(eclass_op_info *pop_info, PCRE2_SIZE *lengthptr, + BOOL preserve_classbits) +{ +/* If the chunk of stack code is already composed of multiple ops, we won't +descend in and try and propagate the negation down the tree. (That would lead +to O(n^2) compile-time, which could be exploitable with a malicious regex - +although maybe that's not really too much of a worry in a library that offers +an exponential-time matching function!) */ + +if (pop_info->op_single_type == 0) + { + if (lengthptr != NULL) + *lengthptr += 1; + else + pop_info->code_start[pop_info->length] = ECL_NOT; + pop_info->length += 1; + } + +/* Otherwise, it's a nice single-op item, so we can easily fold in the negation +without needing to produce an ECL_NOT. */ + +else if (pop_info->op_single_type == ECL_ANY || + pop_info->op_single_type == ECL_NONE) + { + pop_info->op_single_type = (pop_info->op_single_type == ECL_NONE)? + ECL_ANY : ECL_NONE; + if (lengthptr == NULL) + *(pop_info->code_start) = pop_info->op_single_type; + } +else + { + PCRE2_ASSERT(pop_info->op_single_type == ECL_XCLASS && + pop_info->length >= 1 + LINK_SIZE + 1); + if (lengthptr == NULL) + pop_info->code_start[1 + LINK_SIZE] ^= XCL_NOT; + } + +if (!preserve_classbits) + { + for (int i = 0; i < 8; i++) + pop_info->bits.classwords[i] = ~pop_info->bits.classwords[i]; + } +} + + + +/* This function folds together two operands using a binary operator. +The new, combined chunk of stack code is written out to *lhs_op_info. */ + +static void +fold_binary(int op, eclass_op_info *lhs_op_info, eclass_op_info *rhs_op_info, + PCRE2_SIZE *lengthptr) +{ +switch (op) + { + /* ECL_AND truth table: + + LHS RHS RESULT + ---------------- + ANY * RHS + * ANY LHS + NONE * NONE + * NONE NONE + X Y X & Y + */ + + case ECL_AND: + if (rhs_op_info->op_single_type == ECL_ANY) + { + /* no-op: drop the RHS */ + } + else if (lhs_op_info->op_single_type == ECL_ANY) + { + /* no-op: drop the LHS, and memmove the RHS into its place */ + if (lengthptr == NULL) + memmove(lhs_op_info->code_start, rhs_op_info->code_start, + CU2BYTES(rhs_op_info->length)); + lhs_op_info->length = rhs_op_info->length; + lhs_op_info->op_single_type = rhs_op_info->op_single_type; + } + else if (rhs_op_info->op_single_type == ECL_NONE) + { + /* the result is ECL_NONE: write into the LHS */ + if (lengthptr == NULL) + lhs_op_info->code_start[0] = ECL_NONE; + lhs_op_info->length = 1; + lhs_op_info->op_single_type = ECL_NONE; + } + else if (lhs_op_info->op_single_type == ECL_NONE) + { + /* the result is ECL_NONE: drop the RHS */ + } + else + { + /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */ + if (lengthptr != NULL) + *lengthptr += 1; + else + { + PCRE2_ASSERT(rhs_op_info->code_start == + lhs_op_info->code_start + lhs_op_info->length); + rhs_op_info->code_start[rhs_op_info->length] = ECL_AND; + } + lhs_op_info->length += rhs_op_info->length + 1; + lhs_op_info->op_single_type = 0; + } + + for (int i = 0; i < 8; i++) + lhs_op_info->bits.classwords[i] &= rhs_op_info->bits.classwords[i]; + break; + + /* ECL_OR truth table: + + LHS RHS RESULT + ---------------- + ANY * ANY + * ANY ANY + NONE * RHS + * NONE LHS + X Y X | Y + */ + + case ECL_OR: + if (rhs_op_info->op_single_type == ECL_NONE) + { + /* no-op: drop the RHS */ + } + else if (lhs_op_info->op_single_type == ECL_NONE) + { + /* no-op: drop the LHS, and memmove the RHS into its place */ + if (lengthptr == NULL) + memmove(lhs_op_info->code_start, rhs_op_info->code_start, + CU2BYTES(rhs_op_info->length)); + lhs_op_info->length = rhs_op_info->length; + lhs_op_info->op_single_type = rhs_op_info->op_single_type; + } + else if (rhs_op_info->op_single_type == ECL_ANY) + { + /* the result is ECL_ANY: write into the LHS */ + if (lengthptr == NULL) + lhs_op_info->code_start[0] = ECL_ANY; + lhs_op_info->length = 1; + lhs_op_info->op_single_type = ECL_ANY; + } + else if (lhs_op_info->op_single_type == ECL_ANY) + { + /* the result is ECL_ANY: drop the RHS */ + } + else + { + /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */ + if (lengthptr != NULL) + *lengthptr += 1; + else + { + PCRE2_ASSERT(rhs_op_info->code_start == + lhs_op_info->code_start + lhs_op_info->length); + rhs_op_info->code_start[rhs_op_info->length] = ECL_OR; + } + lhs_op_info->length += rhs_op_info->length + 1; + lhs_op_info->op_single_type = 0; + } + + for (int i = 0; i < 8; i++) + lhs_op_info->bits.classwords[i] |= rhs_op_info->bits.classwords[i]; + break; + + /* ECL_XOR truth table: + + LHS RHS RESULT + ---------------- + ANY * !RHS + * ANY !LHS + NONE * RHS + * NONE LHS + X Y X ^ Y + */ + + case ECL_XOR: + if (rhs_op_info->op_single_type == ECL_NONE) + { + /* no-op: drop the RHS */ + } + else if (lhs_op_info->op_single_type == ECL_NONE) + { + /* no-op: drop the LHS, and memmove the RHS into its place */ + if (lengthptr == NULL) + memmove(lhs_op_info->code_start, rhs_op_info->code_start, + CU2BYTES(rhs_op_info->length)); + lhs_op_info->length = rhs_op_info->length; + lhs_op_info->op_single_type = rhs_op_info->op_single_type; + } + else if (rhs_op_info->op_single_type == ECL_ANY) + { + /* the result is !LHS: fold in the negation, and drop the RHS */ + /* Preserve the classbits, because we promise to deal with them later. */ + fold_negation(lhs_op_info, lengthptr, TRUE); + } + else if (lhs_op_info->op_single_type == ECL_ANY) + { + /* the result is !RHS: drop the LHS, memmove the RHS into its place, and + fold in the negation */ + if (lengthptr == NULL) + memmove(lhs_op_info->code_start, rhs_op_info->code_start, + CU2BYTES(rhs_op_info->length)); + lhs_op_info->length = rhs_op_info->length; + lhs_op_info->op_single_type = rhs_op_info->op_single_type; + + /* Preserve the classbits, because we promise to deal with them later. */ + fold_negation(lhs_op_info, lengthptr, TRUE); + } + else + { + /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */ + if (lengthptr != NULL) + *lengthptr += 1; + else + { + PCRE2_ASSERT(rhs_op_info->code_start == + lhs_op_info->code_start + lhs_op_info->length); + rhs_op_info->code_start[rhs_op_info->length] = ECL_XOR; + } + lhs_op_info->length += rhs_op_info->length + 1; + lhs_op_info->op_single_type = 0; + } + + for (int i = 0; i < 8; i++) + lhs_op_info->bits.classwords[i] ^= rhs_op_info->bits.classwords[i]; + break; + + default: + PCRE2_DEBUG_UNREACHABLE(); + break; + } +} + + + +static BOOL +compile_eclass_nested(eclass_context *context, BOOL negated, + uint32_t **pptr, PCRE2_UCHAR **pcode, + eclass_op_info *pop_info, PCRE2_SIZE *lengthptr); + +/* This function consumes a group of implicitly-unioned class elements. +These can be characters, ranges, properties, or nested classes, as long +as they are all joined by being placed adjacently. */ + +static BOOL +compile_class_operand(eclass_context *context, BOOL negated, + uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, + PCRE2_SIZE *lengthptr) +{ +uint32_t *ptr = *pptr; +uint32_t *prev_ptr; +PCRE2_UCHAR *code = *pcode; +PCRE2_UCHAR *code_start = code; +PCRE2_SIZE prev_length = (lengthptr != NULL)? *lengthptr : 0; +PCRE2_SIZE extra_length; +uint32_t meta = META_CODE(*ptr); + +switch (meta) + { + case META_CLASS_EMPTY_NOT: + case META_CLASS_EMPTY: + ++ptr; + pop_info->length = 1; + if ((meta == META_CLASS_EMPTY) == negated) + { + *code++ = pop_info->op_single_type = ECL_ANY; + memset(pop_info->bits.classbits, 0xff, 32); + } + else + { + *code++ = pop_info->op_single_type = ECL_NONE; + memset(pop_info->bits.classbits, 0, 32); + } + break; + + case META_CLASS: + case META_CLASS_NOT: + if ((*ptr & CLASS_IS_ECLASS) != 0) + { + if (!compile_eclass_nested(context, negated, &ptr, &code, + pop_info, lengthptr)) + return FALSE; + + PCRE2_ASSERT(*ptr == META_CLASS_END); + ptr++; + goto DONE; + } + + ptr++; + /* Fall through */ + + default: + /* Scan forward characters, ranges, and properties. + For example: inside [a-z_ -- m] we don't have brackets around "a-z_" but + we still need to collect that fragment up into a "leaf" OP_CLASS. */ + + prev_ptr = ptr; + ptr = PRIV(compile_class_not_nested)( + context->options, context->xoptions, ptr, &code, + (meta != META_CLASS_NOT) == negated, &context->needs_bitmap, + context->errorcodeptr, context->cb, lengthptr); + if (ptr == NULL) return FALSE; + + /* We must have a 100% guarantee that ptr increases when + compile_class_operand() returns, even on Release builds, so that we can + statically prove our loops terminate. */ + if (ptr <= prev_ptr) + { + PCRE2_DEBUG_UNREACHABLE(); + return FALSE; + } + + /* If we fell through above, consume the closing ']'. */ + if (meta == META_CLASS || meta == META_CLASS_NOT) + { + PCRE2_ASSERT(*ptr == META_CLASS_END); + ptr++; + } + + /* Regardless of whether (lengthptr == NULL), some data will still be written + out to *pcode, which we need: we have to peek at it, to transform the opcode + into the ECLASS version (since we need to hoist up the bitmaps). */ + PCRE2_ASSERT(code > code_start); + extra_length = (lengthptr != NULL)? *lengthptr - prev_length : 0; + + /* Easiest case: convert OP_ALLANY to ECL_ANY */ + + if (*code_start == OP_ALLANY) + { + PCRE2_ASSERT(code - code_start == 1 && extra_length == 0); + pop_info->length = 1; + *code_start = pop_info->op_single_type = ECL_ANY; + memset(pop_info->bits.classbits, 0xff, 32); + } + + /* For OP_CLASS and OP_NCLASS, we hoist out the bitmap and convert to + ECL_NONE / ECL_ANY respectively. */ + + else if (*code_start == OP_CLASS || *code_start == OP_NCLASS) + { + PCRE2_ASSERT(code - code_start == 1 + 32 / sizeof(PCRE2_UCHAR) && + extra_length == 0); + pop_info->length = 1; + *code_start = pop_info->op_single_type = + (*code_start == OP_CLASS)? ECL_NONE : ECL_ANY; + memcpy(pop_info->bits.classbits, code_start + 1, 32); + /* Rewind the code pointer, but make sure we adjust *lengthptr, because we + do need to reserve that space (even though we only use it temporarily). */ + if (lengthptr != NULL) + *lengthptr += code - (code_start + 1); + code = code_start + 1; + + if (!context->needs_bitmap && *code_start == ECL_NONE) + { + uint32_t *classwords = pop_info->bits.classwords; + + for (int i = 0; i < 8; i++) + if (classwords[i] != 0) + { + context->needs_bitmap = TRUE; + break; + } + } + else + context->needs_bitmap = TRUE; + } + + /* Finally, for OP_XCLASS we hoist out the bitmap (if any), and convert to + ECL_XCLASS. */ + + else + { + PCRE2_ASSERT(*code_start == OP_XCLASS); + *code_start = pop_info->op_single_type = ECL_XCLASS; + + PCRE2_ASSERT(code - code_start >= 1 + LINK_SIZE + 1); + + memcpy(pop_info->bits.classbits, context->cb->classbits.classbits, 32); + pop_info->length = (code - code_start) + extra_length; + } + + break; + } /* End of switch(meta) */ + +pop_info->code_start = (lengthptr == NULL)? code_start : NULL; + +if (lengthptr != NULL) + { + *lengthptr += code - code_start; + code = code_start; + } + +DONE: +PCRE2_ASSERT(lengthptr == NULL || (code == code_start)); + +*pptr = ptr; +*pcode = code; +return TRUE; +} + + + +/* This function consumes a group of implicitly-unioned class elements. +These can be characters, ranges, properties, or nested classes, as long +as they are all joined by being placed adjacently. */ + +static BOOL +compile_class_juxtaposition(eclass_context *context, BOOL negated, + uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, + PCRE2_SIZE *lengthptr) +{ +uint32_t *ptr = *pptr; +PCRE2_UCHAR *code = *pcode; +#ifdef PCRE2_DEBUG +PCRE2_UCHAR *start_code = *pcode; +#endif + +/* See compile_class_binary_loose() for comments on compile-time folding of +the "negated" flag. */ + +/* Because it's a non-empty class, there must be an operand at the start. */ +if (!compile_class_operand(context, negated, &ptr, &code, pop_info, lengthptr)) + return FALSE; + +while (*ptr != META_CLASS_END && + !(*ptr >= META_ECLASS_AND && *ptr <= META_ECLASS_NOT)) + { + uint32_t op; + BOOL rhs_negated; + eclass_op_info rhs_op_info; + + if (negated) + { + /* !(A juxtapose B) -> !A && !B */ + op = ECL_AND; + rhs_negated = TRUE; + } + else + { + /* A juxtapose B -> A || B */ + op = ECL_OR; + rhs_negated = FALSE; + } + + /* An operand must follow the operator. */ + if (!compile_class_operand(context, rhs_negated, &ptr, &code, + &rhs_op_info, lengthptr)) + return FALSE; + + /* Convert infix to postfix (RPN). */ + fold_binary(op, pop_info, &rhs_op_info, lengthptr); + if (lengthptr == NULL) + code = pop_info->code_start + pop_info->length; + } + +PCRE2_ASSERT(lengthptr == NULL || code == start_code); + +*pptr = ptr; +*pcode = code; +return TRUE; +} + + + +/* This function consumes unary prefix operators. */ + +static BOOL +compile_class_unary(eclass_context *context, BOOL negated, + uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, + PCRE2_SIZE *lengthptr) +{ +uint32_t *ptr = *pptr; +#ifdef PCRE2_DEBUG +PCRE2_UCHAR *start_code = *pcode; +#endif + +while (*ptr == META_ECLASS_NOT) + { + ++ptr; + negated = !negated; + } + +*pptr = ptr; +/* Because it's a non-empty class, there must be an operand. */ +if (!compile_class_juxtaposition(context, negated, pptr, pcode, + pop_info, lengthptr)) + return FALSE; + +PCRE2_ASSERT(lengthptr == NULL || *pcode == start_code); +return TRUE; +} + + + +/* This function consumes tightly-binding binary operators. */ + +static BOOL +compile_class_binary_tight(eclass_context *context, BOOL negated, + uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, + PCRE2_SIZE *lengthptr) +{ +uint32_t *ptr = *pptr; +PCRE2_UCHAR *code = *pcode; +#ifdef PCRE2_DEBUG +PCRE2_UCHAR *start_code = *pcode; +#endif + +/* See compile_class_binary_loose() for comments on compile-time folding of +the "negated" flag. */ + +/* Because it's a non-empty class, there must be an operand at the start. */ +if (!compile_class_unary(context, negated, &ptr, &code, pop_info, lengthptr)) + return FALSE; + +while (*ptr == META_ECLASS_AND) + { + uint32_t op; + BOOL rhs_negated; + eclass_op_info rhs_op_info; + + if (negated) + { + /* !(A && B) -> !A || !B */ + op = ECL_OR; + rhs_negated = TRUE; + } + else + { + /* A && B -> A && B */ + op = ECL_AND; + rhs_negated = FALSE; + } + + ++ptr; + + /* An operand must follow the operator. */ + if (!compile_class_unary(context, rhs_negated, &ptr, &code, + &rhs_op_info, lengthptr)) + return FALSE; + + /* Convert infix to postfix (RPN). */ + fold_binary(op, pop_info, &rhs_op_info, lengthptr); + if (lengthptr == NULL) + code = pop_info->code_start + pop_info->length; + } + +PCRE2_ASSERT(lengthptr == NULL || code == start_code); + +*pptr = ptr; +*pcode = code; +return TRUE; +} + + + +/* This function consumes loosely-binding binary operators. */ + +static BOOL +compile_class_binary_loose(eclass_context *context, BOOL negated, + uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, + PCRE2_SIZE *lengthptr) +{ +uint32_t *ptr = *pptr; +PCRE2_UCHAR *code = *pcode; +#ifdef PCRE2_DEBUG +PCRE2_UCHAR *start_code = *pcode; +#endif + +/* We really want to fold the negation operator, if at all possible, so that +simple cases can be reduced down. In particular, in 8-bit no-UTF mode, we want +to produce a fully-folded expression, so that we can guarantee not to emit any +OP_ECLASS codes (in the same way that we never emit OP_XCLASS in this mode). + +This has the consequence that with a little ingenuity, we can in fact avoid +emitting (nearly...) all cases of the "NOT" operator. Imagine that we have: + !(A ... +We have parsed the preceding "!", and we are about to parse the "A" operand. We +don't know yet whether there will even be a following binary operand! Both of +these are possibilities for what follows: + !(A && B) + !(A) +However, we can still fold the "!" into the "A" operand, because no matter what +the following binary operator will be, we can produce an expression which is +equivalent. */ + +/* Because it's a non-empty class, there must be an operand at the start. */ +if (!compile_class_binary_tight(context, negated, &ptr, &code, + pop_info, lengthptr)) + return FALSE; + +while (*ptr >= META_ECLASS_OR && *ptr <= META_ECLASS_XOR) + { + uint32_t op; + BOOL op_neg; + BOOL rhs_negated; + eclass_op_info rhs_op_info; + + if (negated) + { + /* The whole expression is being negated; we respond by unconditionally + negating the LHS A, before seeing what follows. And hooray! We can recover, + no matter what follows. */ + /* !(A || B) -> !A && !B */ + /* !(A -- B) -> !(A && !B) -> !A || B */ + /* !(A XOR B) -> !(!A XOR !B) -> !A XNOR !B */ + op = (*ptr == META_ECLASS_OR )? ECL_AND : + (*ptr == META_ECLASS_SUB)? ECL_OR : + /*ptr == META_ECLASS_XOR*/ ECL_XOR; + op_neg = (*ptr == META_ECLASS_XOR); + rhs_negated = *ptr != META_ECLASS_SUB; + } + else + { + /* A || B -> A || B */ + /* A -- B -> A && !B */ + /* A XOR B -> A XOR B */ + op = (*ptr == META_ECLASS_OR )? ECL_OR : + (*ptr == META_ECLASS_SUB)? ECL_AND : + /*ptr == META_ECLASS_XOR*/ ECL_XOR; + op_neg = FALSE; + rhs_negated = *ptr == META_ECLASS_SUB; + } + + ++ptr; + + /* An operand must follow the operator. */ + if (!compile_class_binary_tight(context, rhs_negated, &ptr, &code, + &rhs_op_info, lengthptr)) + return FALSE; + + /* Convert infix to postfix (RPN). */ + fold_binary(op, pop_info, &rhs_op_info, lengthptr); + if (op_neg) fold_negation(pop_info, lengthptr, FALSE); + if (lengthptr == NULL) + code = pop_info->code_start + pop_info->length; + } + +PCRE2_ASSERT(lengthptr == NULL || code == start_code); + +*pptr = ptr; +*pcode = code; +return TRUE; +} + + + +/* This function converts the META codes in pptr into opcodes written to +pcode. The pptr must start at a META_CLASS or META_CLASS_NOT. + +The class is compiled as a left-associative sequence of operator +applications. + +The pptr will be left pointing at the matching META_CLASS_END. */ + +static BOOL +compile_eclass_nested(eclass_context *context, BOOL negated, + uint32_t **pptr, PCRE2_UCHAR **pcode, + eclass_op_info *pop_info, PCRE2_SIZE *lengthptr) +{ +uint32_t *ptr = *pptr; +#ifdef PCRE2_DEBUG +PCRE2_UCHAR *start_code = *pcode; +#endif + +/* The CLASS_IS_ECLASS bit must be set since it is a nested class. */ +PCRE2_ASSERT(*ptr == (META_CLASS | CLASS_IS_ECLASS) || + *ptr == (META_CLASS_NOT | CLASS_IS_ECLASS)); + +if (*ptr++ == (META_CLASS_NOT | CLASS_IS_ECLASS)) + negated = !negated; + +(*pptr)++; + +/* Because it's a non-empty class, there must be an operand at the start. */ +if (!compile_class_binary_loose(context, negated, pptr, pcode, + pop_info, lengthptr)) + return FALSE; + +PCRE2_ASSERT(**pptr == META_CLASS_END); +PCRE2_ASSERT(lengthptr == NULL || *pcode == start_code); +return TRUE; +} + +BOOL +PRIV(compile_class_nested)(uint32_t options, uint32_t xoptions, + uint32_t **pptr, PCRE2_UCHAR **pcode, int *errorcodeptr, + compile_block *cb, PCRE2_SIZE *lengthptr) +{ +eclass_context context; +eclass_op_info op_info; +PCRE2_SIZE previous_length = (lengthptr != NULL)? *lengthptr : 0; +PCRE2_UCHAR *code = *pcode; +PCRE2_UCHAR *previous; +BOOL allbitsone = TRUE; + +context.needs_bitmap = FALSE; +context.options = options; +context.xoptions = xoptions; +context.errorcodeptr = errorcodeptr; +context.cb = cb; + +previous = code; +*code++ = OP_ECLASS; +code += LINK_SIZE; +*code++ = 0; /* Flags, currently zero. */ +if (!compile_eclass_nested(&context, FALSE, pptr, &code, &op_info, lengthptr)) + return FALSE; + +if (lengthptr != NULL) + { + *lengthptr += code - previous; + code = previous; + /* (*lengthptr - previous_length) now holds the amount of buffer that + we require to make the call to compile_class_nested() with + lengthptr = NULL, and including the (1+LINK_SIZE+1) that we write out + before that call. */ + } + +/* Do some useful counting of what's in the bitmap. */ +for (int i = 0; i < 8; i++) + if (op_info.bits.classwords[i] != 0xffffffff) + { + allbitsone = FALSE; + break; + } + +/* After constant-folding the extended class syntax, it may turn out to be +a simple class after all. In that case, we can unwrap it from the +OP_ECLASS container - and in fact, we must do so, because in 8-bit +no-Unicode mode the matcher is compiled without support for OP_ECLASS. */ + +#ifndef SUPPORT_WIDE_CHARS +PCRE2_ASSERT(op_info.op_single_type != 0); +#else +if (op_info.op_single_type != 0) +#endif + { + /* Rewind back over the OP_ECLASS. */ + code = previous; + + /* If the bits are all ones, and the "high characters" are all matched + too, we use a special-cased encoding of OP_ALLANY. */ + + if (op_info.op_single_type == ECL_ANY && allbitsone) + { + /* Advancing code means rewinding lengthptr, at this point. */ + if (lengthptr != NULL) *lengthptr -= 1; + *code++ = OP_ALLANY; + } + + /* If the high bits are all matched / all not-matched, then we emit an + OP_NCLASS/OP_CLASS respectively. */ + + else if (op_info.op_single_type == ECL_ANY || + op_info.op_single_type == ECL_NONE) + { + PCRE2_SIZE required_len = 1 + (32 / sizeof(PCRE2_UCHAR)); + + if (lengthptr != NULL) + { + if (required_len > (*lengthptr - previous_length)) + *lengthptr = previous_length + required_len; + } + + /* Advancing code means rewinding lengthptr, at this point. */ + if (lengthptr != NULL) *lengthptr -= required_len; + *code++ = (op_info.op_single_type == ECL_ANY)? OP_NCLASS : OP_CLASS; + memcpy(code, op_info.bits.classbits, 32); + code += 32 / sizeof(PCRE2_UCHAR); + } + + /* Otherwise, we have an ECL_XCLASS, so we have the OP_XCLASS data + there, but, we pulled out its bitmap into op_info, so now we have to + put that back into the OP_XCLASS. */ + + else + { +#ifndef SUPPORT_WIDE_CHARS + PCRE2_DEBUG_UNREACHABLE(); +#else + BOOL need_map = context.needs_bitmap; + PCRE2_SIZE required_len; + + PCRE2_ASSERT(op_info.op_single_type == ECL_XCLASS); + required_len = op_info.length + (need_map? 32/sizeof(PCRE2_UCHAR) : 0); + + if (lengthptr != NULL) + { + /* Don't unconditionally request all the space we need - we may + already have asked for more during processing of the ECLASS. */ + if (required_len > (*lengthptr - previous_length)) + *lengthptr = previous_length + required_len; + + /* The code we write out here won't be ignored, even during the + (lengthptr != NULL) phase, because if there's a following quantifier + it will peek backwards. So we do have to write out a (truncated) + OP_XCLASS, even on this branch. */ + *lengthptr -= 1 + LINK_SIZE + 1; + *code++ = OP_XCLASS; + PUT(code, 0, 1 + LINK_SIZE + 1); + code += LINK_SIZE; + *code++ = 0; + } + else + { + PCRE2_UCHAR *rest; + PCRE2_SIZE rest_len; + PCRE2_UCHAR flags; + + /* 1 unit: OP_XCLASS | LINK_SIZE units | 1 unit: flags | ...rest */ + PCRE2_ASSERT(op_info.length >= 1 + LINK_SIZE + 1); + rest = op_info.code_start + 1 + LINK_SIZE + 1; + rest_len = (op_info.code_start + op_info.length) - rest; + + /* First read any data we use, before memmove splats it. */ + flags = op_info.code_start[1 + LINK_SIZE]; + PCRE2_ASSERT((flags & XCL_MAP) == 0); + + /* Next do the memmove before any writes. */ + memmove(code + 1 + LINK_SIZE + 1 + (need_map? 32/sizeof(PCRE2_UCHAR) : 0), + rest, CU2BYTES(rest_len)); + + /* Finally write the header data. */ + *code++ = OP_XCLASS; + PUT(code, 0, (int)required_len); + code += LINK_SIZE; + *code++ = flags | (need_map? XCL_MAP : 0); + if (need_map) + { + memcpy(code, op_info.bits.classbits, 32); + code += 32 / sizeof(PCRE2_UCHAR); + } + code += rest_len; + } +#endif /* SUPPORT_WIDE_CHARS */ + } + } + +/* Otherwise, we're going to keep the OP_ECLASS. However, again we need +to do some adjustment to insert the bitmap if we have one. */ + +#ifdef SUPPORT_WIDE_CHARS +else + { + BOOL need_map = context.needs_bitmap; + PCRE2_SIZE required_len = + 1 + LINK_SIZE + 1 + (need_map? 32/sizeof(PCRE2_UCHAR) : 0) + op_info.length; + + if (lengthptr != NULL) + { + if (required_len > (*lengthptr - previous_length)) + *lengthptr = previous_length + required_len; + + /* As for the XCLASS branch above, we do have to write out a dummy + OP_ECLASS, because of the backwards peek by the quantifier code. Write + out a (truncated) OP_ECLASS, even on this branch. */ + *lengthptr -= 1 + LINK_SIZE + 1; + *code++ = OP_ECLASS; + PUT(code, 0, 1 + LINK_SIZE + 1); + code += LINK_SIZE; + *code++ = 0; + } + else + { + if (need_map) + { + PCRE2_UCHAR *map_start = previous + 1 + LINK_SIZE + 1; + previous[1 + LINK_SIZE] |= ECL_MAP; + memmove(map_start + 32/sizeof(PCRE2_UCHAR), map_start, + CU2BYTES(code - map_start)); + memcpy(map_start, op_info.bits.classbits, 32); + code += 32 / sizeof(PCRE2_UCHAR); + } + PUT(previous, 1, (int)(code - previous)); + } + } +#endif /* SUPPORT_WIDE_CHARS */ + +*pcode = code; +return TRUE; +} + +/* End of pcre2_compile_class.c */ diff --git a/ext/pcre/pcre2lib/pcre2_config.c b/ext/pcre/pcre2lib/pcre2_config.c index 5ef103caf7925..031981b09bfea 100644 --- a/ext/pcre/pcre2lib/pcre2_config.c +++ b/ext/pcre/pcre2lib/pcre2_config.c @@ -224,8 +224,8 @@ switch (what) XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted. There are problems using an "obvious" approach like this: - XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR) - XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE) + XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE2_MINOR) + XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE2_DATE) because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion of STRING(). The C standard states: "If (before argument substitution) any diff --git a/ext/pcre/pcre2lib/pcre2_context.c b/ext/pcre/pcre2lib/pcre2_context.c index 9edbd1b2ae865..2345145d3f55c 100644 --- a/ext/pcre/pcre2lib/pcre2_context.c +++ b/ext/pcre/pcre2lib/pcre2_context.c @@ -130,7 +130,7 @@ return gcontext; /* A default compile context is set up to save having to initialize at run time when no context is supplied to the compile function. */ -const pcre2_compile_context PRIV(default_compile_context) = { +pcre2_compile_context PRIV(default_compile_context) = { { default_malloc, default_free, NULL }, /* Default memory handling */ NULL, /* Stack guard */ NULL, /* Stack guard data */ @@ -141,7 +141,8 @@ const pcre2_compile_context PRIV(default_compile_context) = { NEWLINE_DEFAULT, /* Newline convention */ PARENS_NEST_LIMIT, /* As it says */ 0, /* Extra options */ - MAX_VARLOOKBEHIND /* As it says */ + MAX_VARLOOKBEHIND, /* As it says */ + PCRE2_OPTIMIZATION_ALL /* All optimizations enabled */ }; /* The create function copies the default into the new memory, but must @@ -163,7 +164,7 @@ return ccontext; /* A default match context is set up to save having to initialize at run time when no context is supplied to a match function. */ -const pcre2_match_context PRIV(default_match_context) = { +pcre2_match_context PRIV(default_match_context) = { { default_malloc, default_free, NULL }, #ifdef SUPPORT_JIT NULL, /* JIT callback */ @@ -173,6 +174,8 @@ const pcre2_match_context PRIV(default_match_context) = { NULL, /* Callout data */ NULL, /* Substitute callout function */ NULL, /* Substitute callout data */ + NULL, /* Substitute case callout function */ + NULL, /* Substitute case callout data */ PCRE2_UNSET, /* Offset limit */ HEAP_LIMIT, MATCH_LIMIT, @@ -197,7 +200,7 @@ return mcontext; /* A default convert context is set up to save having to initialize at run time when no context is supplied to the convert function. */ -const pcre2_convert_context PRIV(default_convert_context) = { +pcre2_convert_context PRIV(default_convert_context) = { { default_malloc, default_free, NULL }, /* Default memory handling */ #ifdef _WIN32 CHAR_BACKSLASH, /* Default path separator */ @@ -409,6 +412,38 @@ ccontext->stack_guard_data = user_data; return 0; } +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_optimize(pcre2_compile_context *ccontext, uint32_t directive) +{ +if (ccontext == NULL) + return PCRE2_ERROR_NULL; + +switch (directive) + { + case PCRE2_OPTIMIZATION_NONE: + ccontext->optimization_flags = 0; + break; + + case PCRE2_OPTIMIZATION_FULL: + ccontext->optimization_flags = PCRE2_OPTIMIZATION_ALL; + break; + + default: + if (directive >= PCRE2_AUTO_POSSESS && directive <= PCRE2_START_OPTIMIZE_OFF) + { + /* Even directive numbers starting from 64 switch a bit on; + * Odd directive numbers starting from 65 switch a bit off */ + if ((directive & 1) != 0) + ccontext->optimization_flags &= ~(1u << ((directive >> 1) - 32)); + else + ccontext->optimization_flags |= 1u << ((directive >> 1) - 32); + return 0; + } + return PCRE2_ERROR_BADOPTION; + } + +return 0; +} /* ------------ Match context ------------ */ @@ -424,13 +459,24 @@ return 0; PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_substitute_callout(pcre2_match_context *mcontext, int (*substitute_callout)(pcre2_substitute_callout_block *, void *), - void *substitute_callout_data) + void *substitute_callout_data) { mcontext->substitute_callout = substitute_callout; mcontext->substitute_callout_data = substitute_callout_data; return 0; } +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_substitute_case_callout(pcre2_match_context *mcontext, + PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, + PCRE2_SIZE, int, void *), + void *substitute_case_callout_data) +{ +mcontext->substitute_case_callout = substitute_case_callout; +mcontext->substitute_case_callout_data = substitute_case_callout_data; +return 0; +} + PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit) { diff --git a/ext/pcre/pcre2lib/pcre2_convert.c b/ext/pcre/pcre2lib/pcre2_convert.c index fe396ae4f9c58..d2b238ca4afb4 100644 --- a/ext/pcre/pcre2lib/pcre2_convert.c +++ b/ext/pcre/pcre2lib/pcre2_convert.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -74,7 +74,7 @@ enum { POSIX_START_REGEX, POSIX_ANCHORED, POSIX_NOT_BRACKET, #define PUTCHARS(string) \ { \ - for (s = (char *)(string); *s != 0; s++) \ + for (const char *s = string; *s != 0; s++) \ { \ if (p >= endp) return PCRE2_ERROR_NOMEMORY; \ *p++ = *s; \ @@ -125,7 +125,6 @@ convert_posix(uint32_t pattype, PCRE2_SPTR pattern, PCRE2_SIZE plength, BOOL utf, PCRE2_UCHAR *use_buffer, PCRE2_SIZE use_length, PCRE2_SIZE *bufflenptr, BOOL dummyrun, pcre2_convert_context *ccontext) { -char *s; PCRE2_SPTR posix = pattern; PCRE2_UCHAR *p = use_buffer; PCRE2_UCHAR *pp = p; @@ -1065,7 +1064,7 @@ pcre2_pattern_convert(PCRE2_SPTR pattern, PCRE2_SIZE plength, uint32_t options, PCRE2_UCHAR **buffptr, PCRE2_SIZE *bufflenptr, pcre2_convert_context *ccontext) { -int i, rc; +int rc; PCRE2_UCHAR dummy_buffer[DUMMY_BUFFER_SIZE]; PCRE2_UCHAR *use_buffer = dummy_buffer; PCRE2_SIZE use_length = DUMMY_BUFFER_SIZE; @@ -1119,7 +1118,7 @@ if (buffptr != NULL && *buffptr != NULL) /* Call an individual converter, either just once (if a buffer was provided or just the length is needed), or twice (if a memory allocation is required). */ -for (i = 0; i < 2; i++) +for (int i = 0; i < 2; i++) { PCRE2_UCHAR *allocated; BOOL dummyrun = buffptr == NULL || *buffptr == NULL; @@ -1138,8 +1137,7 @@ for (i = 0; i < 2; i++) break; default: - *bufflenptr = 0; /* Error offset */ - return PCRE2_ERROR_INTERNAL; + goto EXIT; } if (rc != 0 || /* Error */ @@ -1159,8 +1157,12 @@ for (i = 0; i < 2; i++) use_length = *bufflenptr + 1; } -/* Control should never get here. */ +/* Something went terribly wrong. Trigger an assert and return an error */ +PCRE2_DEBUG_UNREACHABLE(); +EXIT: + +*bufflenptr = 0; /* Error offset */ return PCRE2_ERROR_INTERNAL; } diff --git a/ext/pcre/pcre2lib/pcre2_dfa_match.c b/ext/pcre/pcre2lib/pcre2_dfa_match.c index caae65248ff7c..ebf31d284d27e 100644 --- a/ext/pcre/pcre2lib/pcre2_dfa_match.c +++ b/ext/pcre/pcre2lib/pcre2_dfa_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2023 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -156,6 +156,7 @@ static const uint8_t coptable[] = { 0, /* CLASS */ 0, /* NCLASS */ 0, /* XCLASS - variable length */ + 0, /* ECLASS - variable length */ 0, /* REF */ 0, /* REFI */ 0, /* DNREF */ @@ -175,6 +176,7 @@ static const uint8_t coptable[] = { 0, /* Assert behind not */ 0, /* NA assert */ 0, /* NA assert behind */ + 0, /* Assert scan substring */ 0, /* ONCE */ 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ @@ -188,7 +190,7 @@ static const uint8_t coptable[] = { 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ - 0, 0 /* \B and \b in UCP mode */ + 0, 0, /* \B and \b in UCP mode */ }; /* This table identifies those opcodes that inspect a character. It is used to @@ -234,6 +236,7 @@ static const uint8_t poptable[] = { 1, /* CLASS */ 1, /* NCLASS */ 1, /* XCLASS - variable length */ + 1, /* ECLASS - variable length */ 0, /* REF */ 0, /* REFI */ 0, /* DNREF */ @@ -253,6 +256,7 @@ static const uint8_t poptable[] = { 0, /* Assert behind not */ 0, /* NA assert */ 0, /* NA assert behind */ + 0, /* Assert scan substring */ 0, /* ONCE */ 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ @@ -266,9 +270,13 @@ static const uint8_t poptable[] = { 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ - 1, 1 /* \B and \b in UCP mode */ + 1, 1, /* \B and \b in UCP mode */ }; +/* Compile-time check that these tables have the correct size. */ +STATIC_ASSERT(sizeof(coptable) == OP_TABLE_LENGTH, coptable); +STATIC_ASSERT(sizeof(poptable) == OP_TABLE_LENGTH, poptable); + /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, and \w */ @@ -695,7 +703,6 @@ for (;;) int i, j; int clen, dlen; uint32_t c, d; - int forced_fail = 0; BOOL partial_newline = FALSE; BOOL could_continue = reset_could_continue; reset_could_continue = FALSE; @@ -841,19 +848,6 @@ for (;;) switch (codevalue) { -/* ========================================================================== */ - /* These cases are never obeyed. This is a fudge that causes a compile- - time error if the vectors coptable or poptable, which are indexed by - opcode, are not the correct length. It seems to be the only way to do - such a check at compile time, as the sizeof() operator does not work - in the C preprocessor. */ - - case OP_TABLE_LENGTH: - case OP_TABLE_LENGTH + - ((sizeof(coptable) == OP_TABLE_LENGTH) && - (sizeof(poptable) == OP_TABLE_LENGTH)): - return 0; - /* ========================================================================== */ /* Reached a closing bracket. If not at the end of the pattern, carry on with the next opcode. For repeating opcodes, also add the repeat @@ -1179,10 +1173,6 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[1]) { - case PT_ANY: - OK = TRUE; - break; - case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || @@ -1462,10 +1452,6 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[2]) { - case PT_ANY: - OK = TRUE; - break; - case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; @@ -1727,10 +1713,6 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[2]) { - case PT_ANY: - OK = TRUE; - break; - case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; @@ -2017,10 +1999,6 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[1 + IMM2_SIZE + 1]) { - case PT_ANY: - OK = TRUE; - break; - case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; @@ -2663,35 +2641,54 @@ for (;;) case OP_CLASS: case OP_NCLASS: +#ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: + case OP_ECLASS: +#endif { BOOL isinclass = FALSE; int next_state_offset; PCRE2_SPTR ecode; +#ifdef SUPPORT_WIDE_CHARS + /* An extended class may have a table or a list of single characters, + ranges, or both, and it may be positive or negative. There's a + function that sorts all this out. */ + + if (codevalue == OP_XCLASS) + { + ecode = code + GET(code, 1); + if (clen > 0) + isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, + (const uint8_t*)mb->start_code, utf); + } + + /* A nested set-based class has internal opcodes for performing + set operations. */ + + else if (codevalue == OP_ECLASS) + { + ecode = code + GET(code, 1); + if (clen > 0) + isinclass = PRIV(eclass)(c, code + 1 + LINK_SIZE, ecode, + (const uint8_t*)mb->start_code, utf); + } + + else +#endif /* SUPPORT_WIDE_CHARS */ + /* For a simple class, there is always just a 32-byte table, and we can set isinclass from it. */ - if (codevalue != OP_XCLASS) { ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR)); if (clen > 0) { isinclass = (c > 255)? (codevalue == OP_NCLASS) : - ((((uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0); + ((((const uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0); } } - /* An extended class may have a table or a list of single characters, - ranges, or both, and it may be positive or negative. There's a - function that sorts all this out. */ - - else - { - ecode = code + GET(code, 1); - if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf); - } - /* At this point, isinclass is set for all kinds of class, and ecode points to the byte after the end of the class. If there is a quantifier, this is where it will be. */ @@ -2784,7 +2781,6 @@ for (;;) though the other "backtracking verbs" are not supported. */ case OP_FAIL: - forced_fail++; /* Count FAILs for multiple states */ break; case OP_ASSERT: @@ -3058,7 +3054,7 @@ for (;;) if (codevalue == OP_BRAPOSZERO) { allow_zero = TRUE; - codevalue = *(++code); /* Codevalue will be one of above BRAs */ + ++code; /* The following opcode will be one of the above BRAs */ } else allow_zero = FALSE; @@ -3271,18 +3267,12 @@ for (;;) matches that we are going to find. If partial matching has been requested, check for appropriate conditions. - The "forced_ fail" variable counts the number of (*F) encountered for the - character. If it is equal to the original active_count (saved in - workspace[1]) it means that (*F) was found on every active state. In this - case we don't want to give a partial match. - The "could_continue" variable is true if a state could have continued but for the fact that the end of the subject was reached. */ if (new_count <= 0) { if (could_continue && /* Some could go on, and */ - forced_fail != workspace[1] && /* Not all forced fail & */ ( /* either... */ (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */ || /* or... */ @@ -3438,7 +3428,7 @@ if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) /* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the options variable for this function. Users of PCRE2 who are not calling the function directly would like to have a way of setting these flags, in the same -way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with +way that they can set pcre2_compile() flags like PCRE2_NO_AUTO_POSSESS with constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and (*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be transferred to the options for this function. The bits are guaranteed to be @@ -3528,8 +3518,7 @@ if (mb->match_limit_depth > re->limit_depth) if (mb->heap_limit > re->limit_heap) mb->heap_limit = re->limit_heap; -mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + - re->name_count * re->name_entry_size; +mb->start_code = (PCRE2_SPTR)((const uint8_t *)re + re->code_start); mb->tables = re->tables; mb->start_subject = subject; mb->end_subject = end_subject; @@ -3576,7 +3565,9 @@ switch(re->newline_convention) mb->nltype = NLTYPE_ANYCRLF; break; - default: return PCRE2_ERROR_INTERNAL; + default: + PCRE2_DEBUG_UNREACHABLE(); + return PCRE2_ERROR_INTERNAL; } /* Check a UTF string for validity if required. For 8-bit and 16-bit strings, @@ -3705,7 +3696,7 @@ for (;;) these, for testing and for ensuring that all callouts do actually occur. The optimizations must also be avoided when restarting a DFA match. */ - if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && + if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0 && (options & PCRE2_DFA_RESTART) == 0) { /* If firstline is TRUE, the start of the match is constrained to the first diff --git a/ext/pcre/pcre2lib/pcre2_error.c b/ext/pcre/pcre2lib/pcre2_error.c index 7fa997aa9510b..8b7423c6c6404 100644 --- a/ext/pcre/pcre2lib/pcre2_error.c +++ b/ext/pcre/pcre2lib/pcre2_error.c @@ -96,7 +96,7 @@ static const unsigned char compile_error_texts[] = "length of lookbehind assertion is not limited\0" "a relative value of zero is not allowed\0" "conditional subpattern contains more than two branches\0" - "assertion expected after (?( or (?(?C)\0" + "atomic assertion expected after (?( or (?(?C)\0" "digit expected after (?+ or (?-\0" /* 30 */ "unknown POSIX class name\0" @@ -161,7 +161,7 @@ static const unsigned char compile_error_texts[] = "using UCP is disabled by the application\0" "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" "character code point value in \\u.... sequence is too large\0" - "digits missing in \\x{} or \\o{} or \\N{U+}\0" + "digits missing after \\x or in \\x{} or \\o{} or \\N{U+}\0" "syntax error or number too big in (?(VERSION condition\0" /* 80 */ "internal error: unknown opcode in auto_possessify()\0" @@ -185,11 +185,29 @@ static const unsigned char compile_error_texts[] = "(*alpha_assertion) not recognized\0" "script runs require Unicode support, which this version of PCRE2 does not have\0" "too many capturing groups (maximum 65535)\0" - "atomic assertion expected after (?( or (?(?C)\0" + "octal digit missing after \\0 (PCRE2_EXTRA_NO_BS0 is set)\0" "\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\0" /* 100 */ "branch too long in variable-length lookbehind assertion\0" "compiled pattern would be longer than the limit set by the application\0" + "octal value given by \\ddd is greater than \\377 (forbidden by PCRE2_EXTRA_PYTHON_OCTAL)\0" + "using callouts is disabled by the application\0" + "PCRE2_EXTRA_TURKISH_CASING require Unicode (UTF or UCP) mode\0" + /* 105 */ + "PCRE2_EXTRA_TURKISH_CASING requires UTF in 8-bit mode\0" + "PCRE2_EXTRA_TURKISH_CASING and PCRE2_EXTRA_CASELESS_RESTRICT are not compatible\0" + "extended character class nesting is too deep\0" + "invalid operator in extended character class\0" + "unexpected operator in extended character class (no preceding operand)\0" + /* 110 */ + "expected operand after operator in extended character class\0" + "square brackets needed to clarify operator precedence in extended character class\0" + "missing terminating ] for extended character class (note '[' must be escaped under PCRE2_ALT_EXTENDED_CLASS)\0" + "unexpected expression in extended character class (no preceding operator)\0" + "empty expression in extended character class\0" + /* 115 */ + "terminating ] with no following closing parenthesis in (?[...]\0" + "unexpected character in (?[...]) extended character class\0" ; /* Match-time and UTF error texts are in the same format. */ @@ -276,6 +294,10 @@ static const unsigned char match_error_texts[] = "internal error - duplicate substitution match\0" "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0" "INTERNAL ERROR: invalid substring offset\0" + "feature is not supported by the JIT compiler\0" + "error performing replacement case transformation\0" + /* 70 */ + "replacement too large (longer than PCRE2_SIZE)\0" ; @@ -318,7 +340,7 @@ else if (enumber < 0) /* Match or UTF error */ } else /* Invalid error number */ { - message = (unsigned char *)"\0"; /* Empty message list */ + message = (const unsigned char *)"\0"; /* Empty message list */ n = 1; } diff --git a/ext/pcre/pcre2lib/pcre2_extuni.c b/ext/pcre/pcre2lib/pcre2_extuni.c index 4ed9f00c55a1c..91d839e2970c4 100644 --- a/ext/pcre/pcre2lib/pcre2_extuni.c +++ b/ext/pcre/pcre2lib/pcre2_extuni.c @@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. /* This module contains an internal function that is used to match a Unicode extended grapheme sequence. It is used by both pcre2_match() and -pcre2_def_match(). However, it is called only when Unicode support is being +pcre2_dfa_match(). However, it is called only when Unicode support is being compiled. Nevertheless, we provide a dummy function when there is no Unicode support, because some compilers do not like functionless source files. */ diff --git a/ext/pcre/pcre2lib/pcre2_find_bracket.c b/ext/pcre/pcre2lib/pcre2_find_bracket.c index 1290c5e9de11b..486f4539d89e3 100644 --- a/ext/pcre/pcre2lib/pcre2_find_bracket.c +++ b/ext/pcre/pcre2lib/pcre2_find_bracket.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2023 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -76,18 +76,19 @@ for (;;) if (c == OP_END) return NULL; /* XCLASS is used for classes that cannot be represented just by a bit map. - This includes negated single high-valued characters. CALLOUT_STR is used for - callouts with string arguments. In both cases the length in the table is + This includes negated single high-valued characters. ECLASS is used for + classes that use set operations internally. CALLOUT_STR is used for + callouts with string arguments. In each case the length in the table is zero; the actual length is stored in the compiled code. */ - if (c == OP_XCLASS) code += GET(code, 1); - else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); + if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1); + else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); /* Handle lookbehind */ else if (c == OP_REVERSE || c == OP_VREVERSE) { - if (number < 0) return (PCRE2_UCHAR *)code; + if (number < 0) return code; code += PRIV(OP_lengths)[c]; } @@ -97,7 +98,7 @@ for (;;) c == OP_CBRAPOS || c == OP_SCBRAPOS) { int n = (int)GET2(code, 1+LINK_SIZE); - if (n == number) return (PCRE2_UCHAR *)code; + if (n == number) return code; code += PRIV(OP_lengths)[c]; } diff --git a/ext/pcre/pcre2lib/pcre2_internal.h b/ext/pcre/pcre2lib/pcre2_internal.h index e5808182e676c..6e0a5e05d03f5 100644 --- a/ext/pcre/pcre2lib/pcre2_internal.h +++ b/ext/pcre/pcre2lib/pcre2_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2023 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -88,6 +88,12 @@ typedef int BOOL; #define TRUE 1 #endif +/* Helper macro for static (compile-time) assertions. Can be used inside +functions, or at the top-level of a file. */ +#define STATIC_ASSERT_JOIN(a,b) a ## b +#define STATIC_ASSERT(cond, msg) \ + typedef int STATIC_ASSERT_JOIN(static_assertion_,msg)[(cond)?1:-1] + /* Valgrind (memcheck) support */ #ifdef SUPPORT_VALGRIND @@ -523,29 +529,29 @@ start/end of string field names are. */ three must not be changed, because whichever is set is actually the number of bytes in a code unit in that mode. */ -#define PCRE2_MODE8 0x00000001 /* compiled in 8 bit mode */ -#define PCRE2_MODE16 0x00000002 /* compiled in 16 bit mode */ -#define PCRE2_MODE32 0x00000004 /* compiled in 32 bit mode */ -#define PCRE2_FIRSTSET 0x00000010 /* first_code unit is set */ -#define PCRE2_FIRSTCASELESS 0x00000020 /* caseless first code unit */ -#define PCRE2_FIRSTMAPSET 0x00000040 /* bitmap of first code units is set */ -#define PCRE2_LASTSET 0x00000080 /* last code unit is set */ -#define PCRE2_LASTCASELESS 0x00000100 /* caseless last code unit */ -#define PCRE2_STARTLINE 0x00000200 /* start after \n for multiline */ -#define PCRE2_JCHANGED 0x00000400 /* j option used in pattern */ -#define PCRE2_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */ -#define PCRE2_HASTHEN 0x00001000 /* pattern contains (*THEN) */ -#define PCRE2_MATCH_EMPTY 0x00002000 /* pattern can match empty string */ -#define PCRE2_BSR_SET 0x00004000 /* BSR was set in the pattern */ -#define PCRE2_NL_SET 0x00008000 /* newline was set in the pattern */ -#define PCRE2_NOTEMPTY_SET 0x00010000 /* (*NOTEMPTY) used ) keep */ -#define PCRE2_NE_ATST_SET 0x00020000 /* (*NOTEMPTY_ATSTART) used) together */ -#define PCRE2_DEREF_TABLES 0x00040000 /* release character tables */ -#define PCRE2_NOJIT 0x00080000 /* (*NOJIT) used */ -#define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */ -#define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */ -#define PCRE2_HASBKC 0x00400000 /* contains \C */ -#define PCRE2_HASACCEPT 0x00800000 /* contains (*ACCEPT) */ +#define PCRE2_MODE8 0x00000001u /* compiled in 8 bit mode */ +#define PCRE2_MODE16 0x00000002u /* compiled in 16 bit mode */ +#define PCRE2_MODE32 0x00000004u /* compiled in 32 bit mode */ +#define PCRE2_FIRSTSET 0x00000010u /* first_code unit is set */ +#define PCRE2_FIRSTCASELESS 0x00000020u /* caseless first code unit */ +#define PCRE2_FIRSTMAPSET 0x00000040u /* bitmap of first code units is set */ +#define PCRE2_LASTSET 0x00000080u /* last code unit is set */ +#define PCRE2_LASTCASELESS 0x00000100u /* caseless last code unit */ +#define PCRE2_STARTLINE 0x00000200u /* start after \n for multiline */ +#define PCRE2_JCHANGED 0x00000400u /* j option used in pattern */ +#define PCRE2_HASCRORLF 0x00000800u /* explicit \r or \n in pattern */ +#define PCRE2_HASTHEN 0x00001000u /* pattern contains (*THEN) */ +#define PCRE2_MATCH_EMPTY 0x00002000u /* pattern can match empty string */ +#define PCRE2_BSR_SET 0x00004000u /* BSR was set in the pattern */ +#define PCRE2_NL_SET 0x00008000u /* newline was set in the pattern */ +#define PCRE2_NOTEMPTY_SET 0x00010000u /* (*NOTEMPTY) used ) keep */ +#define PCRE2_NE_ATST_SET 0x00020000u /* (*NOTEMPTY_ATSTART) used) together */ +#define PCRE2_DEREF_TABLES 0x00040000u /* release character tables */ +#define PCRE2_NOJIT 0x00080000u /* (*NOJIT) used */ +#define PCRE2_HASBKPORX 0x00100000u /* contains \P, \p, or \X */ +#define PCRE2_DUPCAPUSED 0x00200000u /* contains (?| */ +#define PCRE2_HASBKC 0x00400000u /* contains \C */ +#define PCRE2_HASACCEPT 0x00800000u /* contains (*ACCEPT) */ #define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32) @@ -574,6 +580,16 @@ modes. */ #define REQ_CU_MAX 2000 #endif +/* The maximum nesting depth for Unicode character class sets. +Currently fixed. Warning: the interpreter relies on this so it can encode +the operand stack in a uint32_t. A nesting limit of 15 implies (15*2+1)=31 +stack operands required, due to the fact that we have two (and only two) +levels of operator precedence. In the UTS#18 syntax, you can write 'x&&y[z]' +and in Perl syntax you can write '(?[ x - y & (z) ])', both of which imply +pushing the match results for x & y to the stack. */ + +#define ECLASS_NEST_LIMIT 15 + /* Offsets for the bitmap tables in the cbits set of tables. Each table contains a set of bits for a class map. Some classes are built by combining these tables. */ @@ -609,6 +625,13 @@ total length of the tables. */ #define ctypes_offset (cbits_offset + cbit_length) /* Character types */ #define TABLES_LENGTH (ctypes_offset + 256) +/* Private flags used in compile_context.optimization_flags */ + +#define PCRE2_OPTIM_AUTO_POSSESS 0x00000001u +#define PCRE2_OPTIM_DOTSTAR_ANCHOR 0x00000002u +#define PCRE2_OPTIM_START_OPTIMIZE 0x00000004u + +#define PCRE2_OPTIMIZATION_ALL 0x00000007u /* -------------------- Character and string names ------------------------ */ @@ -915,6 +938,7 @@ a positive value. */ #define STRING_naplb0 "naplb\0" #define STRING_nla0 "nla\0" #define STRING_nlb0 "nlb\0" +#define STRING_scs0 "scs\0" #define STRING_sr0 "sr\0" #define STRING_asr0 "asr\0" #define STRING_positive_lookahead0 "positive_lookahead\0" @@ -925,6 +949,7 @@ a positive value. */ #define STRING_negative_lookbehind0 "negative_lookbehind\0" #define STRING_script_run0 "script_run\0" #define STRING_atomic_script_run "atomic_script_run" +#define STRING_scan_substring0 "scan_substring\0" #define STRING_alpha0 "alpha\0" #define STRING_lower0 "lower\0" @@ -965,6 +990,8 @@ a positive value. */ #define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" #define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)" #define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)" +#define STRING_CASELESS_RESTRICT_RIGHTPAR "CASELESS_RESTRICT)" +#define STRING_TURKISH_CASING_RIGHTPAR "TURKISH_CASING)" #define STRING_LIMIT_HEAP_EQ "LIMIT_HEAP=" #define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH=" #define STRING_LIMIT_DEPTH_EQ "LIMIT_DEPTH=" @@ -1216,6 +1243,7 @@ only. */ #define STRING_naplb0 STR_n STR_a STR_p STR_l STR_b "\0" #define STRING_nla0 STR_n STR_l STR_a "\0" #define STRING_nlb0 STR_n STR_l STR_b "\0" +#define STRING_scs0 STR_s STR_c STR_s "\0" #define STRING_sr0 STR_s STR_r "\0" #define STRING_asr0 STR_a STR_s STR_r "\0" #define STRING_positive_lookahead0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0" @@ -1226,6 +1254,7 @@ only. */ #define STRING_negative_lookbehind0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0" #define STRING_script_run0 STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n "\0" #define STRING_atomic_script_run STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n +#define STRING_scan_substring0 STR_s STR_c STR_a STR_n STR_UNDERSCORE STR_s STR_u STR_b STR_s STR_t STR_r STR_i STR_n STR_g "\0" #define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" #define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" @@ -1266,6 +1295,8 @@ only. */ #define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS #define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS #define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS +#define STRING_CASELESS_RESTRICT_RIGHTPAR STR_C STR_A STR_S STR_E STR_L STR_E STR_S STR_S STR_UNDERSCORE STR_R STR_E STR_S STR_T STR_R STR_I STR_C STR_T STR_RIGHT_PARENTHESIS +#define STRING_TURKISH_CASING_RIGHTPAR STR_T STR_U STR_R STR_K STR_I STR_S STR_H STR_UNDERSCORE STR_C STR_A STR_S STR_I STR_N STR_G STR_RIGHT_PARENTHESIS #define STRING_LIMIT_HEAP_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_H STR_E STR_A STR_P STR_EQUALS_SIGN #define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN #define STRING_LIMIT_DEPTH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_D STR_E STR_P STR_T STR_H STR_EQUALS_SIGN @@ -1290,21 +1321,22 @@ only. */ changed, the autopossessifying table in pcre2_auto_possess.c must be updated to match. */ -#define PT_ANY 0 /* Any property - matches all chars */ -#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */ -#define PT_GC 2 /* Specified general characteristic (e.g. L) */ -#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */ -#define PT_SC 4 /* Script only (e.g. Han) */ -#define PT_SCX 5 /* Script extensions (includes SC) */ -#define PT_ALNUM 6 /* Alphanumeric - the union of L and N */ -#define PT_SPACE 7 /* Perl space - general category Z plus 9,10,12,13 */ -#define PT_PXSPACE 8 /* POSIX space - Z plus 9,10,11,12,13 */ -#define PT_WORD 9 /* Word - L, N, Mn, or Pc */ -#define PT_CLIST 10 /* Pseudo-property: match character list */ -#define PT_UCNC 11 /* Universal Character nameable character */ -#define PT_BIDICL 12 /* Specified bidi class */ -#define PT_BOOL 13 /* Boolean property */ -#define PT_TABSIZE 14 /* Size of square table for autopossessify tests */ +#define PT_LAMP 0 /* L& - the union of Lu, Ll, Lt */ +#define PT_GC 1 /* Specified general characteristic (e.g. L) */ +#define PT_PC 2 /* Specified particular characteristic (e.g. Lu) */ +#define PT_SC 3 /* Script only (e.g. Han) */ +#define PT_SCX 4 /* Script extensions (includes SC) */ +#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */ +#define PT_SPACE 6 /* Perl space - general category Z plus 9,10,12,13 */ +#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ +#define PT_WORD 8 /* Word - L, N, Mn, or Pc */ +#define PT_CLIST 9 /* Pseudo-property: match character list */ +#define PT_UCNC 10 /* Universal Character nameable character */ +#define PT_BIDICL 11 /* Specified bidi class */ +#define PT_BOOL 12 /* Boolean property */ +#define PT_ANY 13 /* Must be the last entry! + Any property - matches all chars */ +#define PT_TABSIZE PT_ANY /* Size of square table for autopossessify tests */ /* The following special properties are used only in XCLASS items, when POSIX classes are specified and PCRE2_UCP is set - in other words, for Unicode @@ -1334,6 +1366,94 @@ contain characters with values greater than 255. */ #define XCL_RANGE 2 /* A range (two multibyte chars) follows */ #define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ #define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ +/* This value represents the beginning of character lists. The value +is 16 bit long, and stored as a high and low byte pair in 8 bit mode. +The lower 12 bit contains information about character lists (see later). */ +#define XCL_LIST (sizeof(PCRE2_UCHAR) == 1 ? 0x10 : 0x1000) + +/* When a character class contains many characters/ranges, +they are stored in character lists. There are four character +lists which contain characters/ranges within a given range. + +The name, character range and item size for each list: +Low16 [0x100 - 0x7fff] 16 bit items +High16 [0x8000 - 0xffff] 16 bit items +Low32 [0x10000 - 0x7fffffff] 32 bit items +High32 [0x80000000 - 0xffffffff] 32 bit items + +The Low32 character list is used only when utf encoding or 32 bit +character width is enabled, and the High32 character is used only +when 32 bit character width is enabled. + +Each character list contain items. The lowest bit represents that +an item is the beginning of a range (bit is cleared), or not (bit +is set). The other bits represent the character shifted left by +one, so its highest bit is discarded. Due to the layout of character +lists, the highest bit of a character is always known: + +Low16 and Low32: the highest bit is always zero +High16 and High32: the highest bit is always one + +The items are ordered in increasing order, so binary search can be +used to find the lower bound of an input character. The lower bound +is the highest item, which value is less or equal than the input +character. If the lower bit of the item is cleard, or the character +stored in the item equals to the input character, the input +character is in the character list. */ + +/* Character list constants. */ +#define XCL_CHAR_LIST_LOW_16_START 0x100 +#define XCL_CHAR_LIST_LOW_16_END 0x7fff +#define XCL_CHAR_LIST_LOW_16_ADD 0x0 + +#define XCL_CHAR_LIST_HIGH_16_START 0x8000 +#define XCL_CHAR_LIST_HIGH_16_END 0xffff +#define XCL_CHAR_LIST_HIGH_16_ADD 0x8000 + +#define XCL_CHAR_LIST_LOW_32_START 0x10000 +#define XCL_CHAR_LIST_LOW_32_END 0x7fffffff +#define XCL_CHAR_LIST_LOW_32_ADD 0x0 + +#define XCL_CHAR_LIST_HIGH_32_START 0x80000000 +#define XCL_CHAR_LIST_HIGH_32_END 0xffffffff +#define XCL_CHAR_LIST_HIGH_32_ADD 0x80000000 + +/* Mask for getting the descriptors of character list ranges. +Each descriptor has XCL_TYPE_BIT_LEN bits, and can be processed +by XCL_BEGIN_WITH_RANGE and XCL_ITEM_COUNT_MASK macros. */ +#define XCL_TYPE_MASK 0xfff +#define XCL_TYPE_BIT_LEN 3 +/* If this bit is set, the first item of the character list is the +end of a range, which started before the starting character of the +character list. */ +#define XCL_BEGIN_WITH_RANGE 0x4 +/* Number of items in the character list: 0, 1, or 2. The value 3 +represents that the item count is stored at the begining of the +character list. The item count has the same width as the items +in the character list (e.g. 16 bit for Low16 and High16 lists). */ +#define XCL_ITEM_COUNT_MASK 0x3 +/* Shift and flag for constructing character list items. The XCL_CHAR_END +is set, when the item is not the beginning of a range. The XCL_CHAR_SHIFT +can be used to encode / decode the character value stored in an item. */ +#define XCL_CHAR_END 0x1 +#define XCL_CHAR_SHIFT 1 + +/* Flag bits for an extended class (OP_ECLASS), which is used for complex +character matches such as [\p{Greek} && \p{Ll}]. */ + +#define ECL_MAP 0x01 /* Flag: a 32-byte map is present */ + +/* Type tags for the items stored in an extended class (OP_ECLASS). These items +follow the OP_ECLASS's flag char and bitmap, and represent a Reverse Polish +Notation list of operands and operators manipulating a stack of bits. */ + +#define ECL_AND 1 /* Pop two from the stack, AND, and push result. */ +#define ECL_OR 2 /* Pop two from the stack, OR, and push result. */ +#define ECL_XOR 3 /* Pop two from the stack, XOR, and push result. */ +#define ECL_NOT 4 /* Pop one from the stack, NOT, and push result. */ +#define ECL_XCLASS 5 /* XCLASS nested within ECLASS; match and push result. */ +#define ECL_ANY 6 /* Temporary, only used during compilation. */ +#define ECL_NONE 7 /* Temporary, only used during compilation. */ /* These are escaped items that aren't just an encoding of a particular data value such as \n. They must have non-zero values, as check_escape() returns 0 @@ -1555,102 +1675,105 @@ enum { character > 255 is encountered. */ OP_XCLASS, /* 112 Extended class for handling > 255 chars within the class. This does both positive and negative. */ - OP_REF, /* 113 Match a back reference, casefully */ - OP_REFI, /* 114 Match a back reference, caselessly */ - OP_DNREF, /* 115 Match a duplicate name backref, casefully */ - OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */ - OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */ - OP_CALLOUT, /* 118 Call out to external function if provided */ - OP_CALLOUT_STR, /* 119 Call out with string argument */ - - OP_ALT, /* 120 Start of alternation */ - OP_KET, /* 121 End of group that doesn't have an unbounded repeat */ - OP_KETRMAX, /* 122 These two must remain together and in this */ - OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */ - OP_KETRPOS, /* 124 Possessive unlimited repeat. */ + OP_ECLASS, /* 113 Really-extended class, for handling logical + expressions computed over characters. */ + OP_REF, /* 114 Match a back reference, casefully */ + OP_REFI, /* 115 Match a back reference, caselessly */ + OP_DNREF, /* 116 Match a duplicate name backref, casefully */ + OP_DNREFI, /* 117 Match a duplicate name backref, caselessly */ + OP_RECURSE, /* 118 Match a numbered subpattern (possibly recursive) */ + OP_CALLOUT, /* 119 Call out to external function if provided */ + OP_CALLOUT_STR, /* 120 Call out with string argument */ + + OP_ALT, /* 121 Start of alternation */ + OP_KET, /* 122 End of group that doesn't have an unbounded repeat */ + OP_KETRMAX, /* 123 These two must remain together and in this */ + OP_KETRMIN, /* 124 order. They are for groups the repeat for ever. */ + OP_KETRPOS, /* 125 Possessive unlimited repeat. */ /* The assertions must come before BRA, CBRA, ONCE, and COND. */ - OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */ - OP_VREVERSE, /* 126 Move pointer back - variable */ - OP_ASSERT, /* 127 Positive lookahead */ - OP_ASSERT_NOT, /* 128 Negative lookahead */ - OP_ASSERTBACK, /* 129 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 130 Negative lookbehind */ - OP_ASSERT_NA, /* 131 Positive non-atomic lookahead */ - OP_ASSERTBACK_NA, /* 132 Positive non-atomic lookbehind */ + OP_REVERSE, /* 126 Move pointer back - used in lookbehind assertions */ + OP_VREVERSE, /* 127 Move pointer back - variable */ + OP_ASSERT, /* 128 Positive lookahead */ + OP_ASSERT_NOT, /* 129 Negative lookahead */ + OP_ASSERTBACK, /* 130 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 131 Negative lookbehind */ + OP_ASSERT_NA, /* 132 Positive non-atomic lookahead */ + OP_ASSERTBACK_NA, /* 133 Positive non-atomic lookbehind */ + OP_ASSERT_SCS, /* 134 Scan substring */ /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. The POS versions must immediately follow the non-POS versions in each case. */ - OP_ONCE, /* 133 Atomic group, contains captures */ - OP_SCRIPT_RUN, /* 134 Non-capture, but check characters' scripts */ - OP_BRA, /* 135 Start of non-capturing bracket */ - OP_BRAPOS, /* 136 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 137 Start of capturing bracket */ - OP_CBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 139 Conditional group */ + OP_ONCE, /* 135 Atomic group, contains captures */ + OP_SCRIPT_RUN, /* 136 Non-capture, but check characters' scripts */ + OP_BRA, /* 137 Start of non-capturing bracket */ + OP_BRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 139 Start of capturing bracket */ + OP_CBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 141 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 140 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 141 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 142 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 143 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 144 Conditional group, check empty */ + OP_SBRA, /* 142 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 143 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 144 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 145 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 146 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 145 Used to hold a capture number as condition */ - OP_DNCREF, /* 146 Used to point to duplicate names as a condition */ - OP_RREF, /* 147 Used to hold a recursion number as condition */ - OP_DNRREF, /* 148 Used to point to duplicate names as a condition */ - OP_FALSE, /* 149 Always false (used by DEFINE and VERSION) */ - OP_TRUE, /* 150 Always true (used by VERSION) */ + OP_CREF, /* 147 Used to hold a capture number as condition */ + OP_DNCREF, /* 148 Used to point to duplicate names as a condition */ + OP_RREF, /* 149 Used to hold a recursion number as condition */ + OP_DNRREF, /* 150 Used to point to duplicate names as a condition */ + OP_FALSE, /* 151 Always false (used by DEFINE and VERSION) */ + OP_TRUE, /* 152 Always true (used by VERSION) */ - OP_BRAZERO, /* 151 These two must remain together and in this */ - OP_BRAMINZERO, /* 152 order. */ - OP_BRAPOSZERO, /* 153 */ + OP_BRAZERO, /* 153 These two must remain together and in this */ + OP_BRAMINZERO, /* 154 order. */ + OP_BRAPOSZERO, /* 155 */ /* These are backtracking control verbs */ - OP_MARK, /* 154 always has an argument */ - OP_PRUNE, /* 155 */ - OP_PRUNE_ARG, /* 156 same, but with argument */ - OP_SKIP, /* 157 */ - OP_SKIP_ARG, /* 158 same, but with argument */ - OP_THEN, /* 159 */ - OP_THEN_ARG, /* 160 same, but with argument */ - OP_COMMIT, /* 161 */ - OP_COMMIT_ARG, /* 162 same, but with argument */ + OP_MARK, /* 156 always has an argument */ + OP_PRUNE, /* 157 */ + OP_PRUNE_ARG, /* 158 same, but with argument */ + OP_SKIP, /* 159 */ + OP_SKIP_ARG, /* 160 same, but with argument */ + OP_THEN, /* 161 */ + OP_THEN_ARG, /* 162 same, but with argument */ + OP_COMMIT, /* 163 */ + OP_COMMIT_ARG, /* 164 same, but with argument */ /* These are forced failure and success verbs. FAIL and ACCEPT do accept an argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL) without the need for a special opcode. */ - OP_FAIL, /* 163 */ - OP_ACCEPT, /* 164 */ - OP_ASSERT_ACCEPT, /* 165 Used inside assertions */ - OP_CLOSE, /* 166 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 165 */ + OP_ACCEPT, /* 166 */ + OP_ASSERT_ACCEPT, /* 167 Used inside assertions */ + OP_CLOSE, /* 168 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 167 */ + OP_SKIPZERO, /* 169 */ /* This is used to identify a DEFINE group during compilation so that it can be checked for having only one branch. It is changed to OP_FALSE before compilation finishes. */ - OP_DEFINE, /* 168 */ + OP_DEFINE, /* 170 */ /* These opcodes replace their normal counterparts in UCP mode when PCRE2_EXTRA_ASCII_BSW is not set. */ - OP_NOT_UCP_WORD_BOUNDARY, /* 169 */ - OP_UCP_WORD_BOUNDARY, /* 170 */ + OP_NOT_UCP_WORD_BOUNDARY, /* 171 */ + OP_UCP_WORD_BOUNDARY, /* 172 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1693,19 +1816,21 @@ some cases doesn't actually use these names at all). */ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ "*+","++", "?+", "{", \ - "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ + "class", "nclass", "xclass", "eclass", \ + "Ref", "Refi", "DnRef", "DnRefi", \ "Recurse", "Callout", "CalloutStr", \ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ "Reverse", "VReverse", "Assert", "Assert not", \ "Assert back", "Assert back not", \ "Non-atomic assert", "Non-atomic assert back", \ + "Scan substring", \ "Once", \ "Script run", \ "Bra", "BraPos", "CBra", "CBraPos", \ "Cond", \ "SBra", "SBraPos", "SCBra", "SCBraPos", \ "SCond", \ - "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", \ + "Capture ref", "Capture dnref", "Cond rec", "Cond dnrec", \ "Cond false", "Cond true", \ "Brazero", "Braminzero", "Braposzero", \ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ @@ -1766,10 +1891,11 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+(32/sizeof(PCRE2_UCHAR)), /* CLASS */ \ 1+(32/sizeof(PCRE2_UCHAR)), /* NCLASS */ \ 0, /* XCLASS - variable length */ \ + 0, /* ECLASS - variable length */ \ 1+IMM2_SIZE, /* REF */ \ - 1+IMM2_SIZE, /* REFI */ \ + 1+IMM2_SIZE+1, /* REFI */ \ 1+2*IMM2_SIZE, /* DNREF */ \ - 1+2*IMM2_SIZE, /* DNREFI */ \ + 1+2*IMM2_SIZE+1, /* DNREFI */ \ 1+LINK_SIZE, /* RECURSE */ \ 1+2*LINK_SIZE+1, /* CALLOUT */ \ 0, /* CALLOUT_STR - variable length */ \ @@ -1786,6 +1912,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+LINK_SIZE, /* Assert behind not */ \ 1+LINK_SIZE, /* NA Assert */ \ 1+LINK_SIZE, /* NA Assert behind */ \ + 1+LINK_SIZE, /* Scan substring */ \ 1+LINK_SIZE, /* ONCE */ \ 1+LINK_SIZE, /* SCRIPT_RUN */ \ 1+LINK_SIZE, /* BRA */ \ @@ -1815,6 +1942,11 @@ in UTF-8 mode. The code that uses this table must know about such things. */ #define RREF_ANY 0xffff +/* Constants used by OP_REFI and OP_DNREFI to control matching behaviour. */ + +#define REFI_FLAG_CASELESS_RESTRICT 0x1 +#define REFI_FLAG_TURKISH_CASING 0x2 + /* ---------- Private structures that are mode-independent. ---------- */ @@ -1890,6 +2022,14 @@ typedef struct { #define UCD_SCRIPTX(ch) UCD_SCRIPTX_PROP(GET_UCD(ch)) #define UCD_BPROPS(ch) UCD_BPROPS_PROP(GET_UCD(ch)) #define UCD_BIDICLASS(ch) UCD_BIDICLASS_PROP(GET_UCD(ch)) +#define UCD_ANY_I(ch) \ + /* match any of the four characters 'i', 'I', U+0130, U+0131 */ \ + (((uint32_t)(ch) | 0x20u) == 0x69u || ((uint32_t)(ch) | 1u) == 0x0131u) +#define UCD_DOTTED_I(ch) \ + ((uint32_t)(ch) == 0x69u || (uint32_t)(ch) == 0x0130u) +#define UCD_FOLD_I_TURKISH(ch) \ + ((uint32_t)(ch) == 0x0130u ? 0x69u : \ + (uint32_t)(ch) == 0x49u ? 0x0131u : (uint32_t)(ch)) /* The "scriptx" and bprops fields contain offsets into vectors of 32-bit words that form a bitmap representing a list of scripts or boolean properties. These @@ -1955,6 +2095,9 @@ extern const uint8_t PRIV(utf8_table4)[]; #define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_) #define _pcre2_ucd_boolprop_sets PCRE2_SUFFIX(_pcre2_ucd_boolprop_sets_) #define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_) +#define _pcre2_ucd_turkish_dotted_i_caseset PCRE2_SUFFIX(_pcre2_ucd_turkish_dotted_i_caseset_) +#define _pcre2_ucd_nocase_ranges PCRE2_SUFFIX(_pcre2_ucd_nocase_ranges_) +#define _pcre2_ucd_nocase_ranges_size PCRE2_SUFFIX(_pcre2_ucd_nocase_ranges_size_) #define _pcre2_ucd_digit_sets PCRE2_SUFFIX(_pcre2_ucd_digit_sets_) #define _pcre2_ucd_script_sets PCRE2_SUFFIX(_pcre2_ucd_script_sets_) #define _pcre2_ucd_records PCRE2_SUFFIX(_pcre2_ucd_records_) @@ -1971,14 +2114,17 @@ extern const uint8_t PRIV(utf8_table4)[]; extern const uint8_t PRIV(OP_lengths)[]; extern const uint32_t PRIV(callout_end_delims)[]; extern const uint32_t PRIV(callout_start_delims)[]; -extern const pcre2_compile_context PRIV(default_compile_context); -extern const pcre2_convert_context PRIV(default_convert_context); -extern const pcre2_match_context PRIV(default_match_context); +extern pcre2_compile_context PRIV(default_compile_context); +extern pcre2_convert_context PRIV(default_convert_context); +extern pcre2_match_context PRIV(default_match_context); extern const uint8_t PRIV(default_tables)[]; extern const uint32_t PRIV(hspace_list)[]; extern const uint32_t PRIV(vspace_list)[]; extern const uint32_t PRIV(ucd_boolprop_sets)[]; extern const uint32_t PRIV(ucd_caseless_sets)[]; +extern const uint32_t PRIV(ucd_turkish_dotted_i_caseset); +extern const uint32_t PRIV(ucd_nocase_ranges)[]; +extern const uint32_t PRIV(ucd_nocase_ranges_size); extern const uint32_t PRIV(ucd_digit_sets)[]; extern const uint32_t PRIV(ucd_script_sets)[]; extern const ucd_record PRIV(ucd_records)[]; @@ -2039,11 +2185,12 @@ is available. */ #define _pcre2_valid_utf PCRE2_SUFFIX(_pcre2_valid_utf_) #define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_) #define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_) +#define _pcre2_eclass PCRE2_SUFFIX(_pcre2_eclass_) extern int _pcre2_auto_possessify(PCRE2_UCHAR *, const compile_block *); extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *, - int *, uint32_t, uint32_t, BOOL, compile_block *); + int *, uint32_t, uint32_t, uint32_t, BOOL, compile_block *); extern PCRE2_SPTR _pcre2_extuni(uint32_t, PCRE2_SPTR, PCRE2_SPTR, PCRE2_SPTR, BOOL, int *); extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int); @@ -2066,7 +2213,9 @@ extern int _pcre2_study(pcre2_real_code *); extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *); extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR, uint32_t *, BOOL); -extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL); +extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, const uint8_t *, BOOL); +extern BOOL _pcre2_eclass(uint32_t, PCRE2_SPTR, PCRE2_SPTR, + const uint8_t *, BOOL); /* This function is needed only when memmove() is not available. */ @@ -2079,6 +2228,8 @@ extern void * _pcre2_memmove(void *, const void *, size_t); extern BOOL PRIV(ckd_smul)(PCRE2_SIZE *, int, int); +#include "pcre2_util.h" + #endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */ /* End of pcre2_internal.h */ diff --git a/ext/pcre/pcre2lib/pcre2_intmodedep.h b/ext/pcre/pcre2lib/pcre2_intmodedep.h index 9bd9e694a496e..6b858139f577c 100644 --- a/ext/pcre/pcre2lib/pcre2_intmodedep.h +++ b/ext/pcre/pcre2lib/pcre2_intmodedep.h @@ -47,7 +47,7 @@ to have access to the hidden structures at all supported widths. Some of the mode-dependent macros are required at different widths for different parts of the pcre2test code (in particular, the included -pcre_printint.c file). We undefine them here so that they can be re-defined for +pcre2_printint.c file). We undefine them here so that they can be re-defined for multiple inclusions. Not all of these are used in pcre2test, but it's easier just to undefine them all. */ @@ -435,7 +435,7 @@ UTF-16 mode. */ c = *eptr; \ if ((c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len); -/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the +/* Get the next UTF-16 character, testing for UTF-16 mode, not advancing the pointer, incrementing length if there is a low surrogate. This is called when we do not know if we are in UTF-16 mode. */ @@ -556,6 +556,11 @@ code that uses them is simpler because it assumes this. */ /* The real general context structure. At present it holds only data for custom memory control. */ +/* WARNING: if this is ever changed, code in pcre2_substitute.c will have to be +changed because it builds a general context "by hand" in order to avoid the +malloc() call in pcre2_general_context)_create(). There is also code in +pcre2_match.c that makes the same assumption. */ + typedef struct pcre2_real_general_context { pcre2_memctl memctl; } pcre2_real_general_context; @@ -574,6 +579,7 @@ typedef struct pcre2_real_compile_context { uint32_t parens_nest_limit; uint32_t extra_options; uint32_t max_varlookbehind; + uint32_t optimization_flags; } pcre2_real_compile_context; /* The real match context structure. */ @@ -584,10 +590,13 @@ typedef struct pcre2_real_match_context { pcre2_jit_callback jit_callback; void *jit_callback_data; #endif - int (*callout)(pcre2_callout_block *, void *); - void *callout_data; - int (*substitute_callout)(pcre2_substitute_callout_block *, void *); - void *substitute_callout_data; + int (*callout)(pcre2_callout_block *, void *); + void *callout_data; + int (*substitute_callout)(pcre2_substitute_callout_block *, void *); + void *substitute_callout_data; + PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, + PCRE2_SIZE, int, void *); + void *substitute_case_callout_data; PCRE2_SIZE offset_limit; uint32_t heap_limit; uint32_t match_limit; @@ -623,6 +632,7 @@ typedef struct pcre2_real_code { void *executable_jit; /* Pointer to JIT code */ uint8_t start_bitmap[32]; /* Bitmap for starting code unit < 256 */ CODE_BLOCKSIZE_TYPE blocksize; /* Total (bytes) that was malloc-ed */ + CODE_BLOCKSIZE_TYPE code_start; /* Byte code start offset */ uint32_t magic_number; /* Paranoid and endianness check */ uint32_t compile_options; /* Options passed to pcre2_compile() */ uint32_t overall_options; /* Options after processing the pattern */ @@ -641,6 +651,7 @@ typedef struct pcre2_real_code { uint16_t top_backref; /* Highest numbered back reference */ uint16_t name_entry_size; /* Size (code units) of table entries */ uint16_t name_count; /* Number of name entries in the table */ + uint32_t optimization_flags; /* Optimizations enabled at compile time */ } pcre2_real_code; /* The real match data structure. Define ovector as large as it can ever @@ -716,6 +727,23 @@ typedef struct named_group { uint16_t isdup; /* TRUE if a duplicate */ } named_group; +/* Structure for caching sorted ranges. This improves the performance +of translating META code to byte code. */ + +typedef struct class_ranges { + struct class_ranges *next; /* Next class ranges */ + size_t char_lists_size; /* Total size of encoded char lists */ + size_t char_lists_start; /* Start offset of encoded char lists */ + uint16_t range_list_size; /* Size of ranges array */ + uint16_t char_lists_types; /* The XCL_LIST header of char lists */ + /* Followed by the list of ranges (start/end pairs) */ +} class_ranges; + +typedef union class_bits_storage { + uint8_t classbits[32]; + uint32_t classwords[8]; +} class_bits_storage; + /* Structure for passing "static" information around between the functions doing the compiling, so that they are thread-safe. */ @@ -725,14 +753,15 @@ typedef struct compile_block { const uint8_t *fcc; /* Points to case-flipping table */ const uint8_t *cbits; /* Points to character type table */ const uint8_t *ctypes; /* Points to table of type maps */ - PCRE2_SPTR start_workspace; /* The start of working space */ - PCRE2_SPTR start_code; /* The start of the compiled code */ + PCRE2_UCHAR *start_workspace; /* The start of working space */ + PCRE2_UCHAR *start_code; /* The start of the compiled code */ PCRE2_SPTR start_pattern; /* The start of the pattern */ PCRE2_SPTR end_pattern; /* The end of the pattern */ PCRE2_UCHAR *name_table; /* The name/number table */ PCRE2_SIZE workspace_size; /* Size of workspace */ PCRE2_SIZE small_ref_offset[10]; /* Offsets for \1 to \9 */ PCRE2_SIZE erroroffset; /* Offset of error in pattern */ + class_bits_storage classbits; /* Temporary store for classbits */ uint16_t names_found; /* Number of entries so far */ uint16_t name_entry_size; /* Size of each entry */ uint16_t parens_depth; /* Depth of nested parentheses */ @@ -750,9 +779,9 @@ typedef struct compile_block { uint32_t backref_map; /* Bitmap of low back refs */ uint32_t nltype; /* Newline type */ uint32_t nllen; /* Newline string length */ - uint32_t class_range_start; /* Overall class range start */ - uint32_t class_range_end; /* Overall class range end */ PCRE2_UCHAR nl[4]; /* Newline string when fixed length */ + uint8_t class_op_used[ECLASS_NEST_LIMIT]; /* Operation used for + extended classes */ uint32_t req_varyopt; /* "After variable item" flag for reqbyte */ uint32_t max_varlookbehind; /* Limit for variable lookbehinds */ int max_lookbehind; /* Maximum lookbehind encountered (characters) */ @@ -760,6 +789,11 @@ typedef struct compile_block { BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ BOOL had_recurse; /* Had a pattern recursion or subroutine call */ BOOL dupnames; /* Duplicate names exist */ +#ifdef SUPPORT_WIDE_CHARS + class_ranges *cranges; /* First class range. */ + class_ranges *next_cranges; /* Next class range. */ + size_t char_lists_size; /* Current size of character lists */ +#endif } compile_block; /* Structure for keeping the properties of the in-memory stack used @@ -793,7 +827,7 @@ typedef struct heapframe { to RRMATCH(), but which do not need to be copied to new frames. */ PCRE2_SPTR ecode; /* The current position in the pattern */ - PCRE2_SPTR temp_sptr[2]; /* Used for short-term PCRE_SPTR values */ + PCRE2_SPTR temp_sptr[2]; /* Used for short-term PCRE2_SPTR values */ PCRE2_SIZE length; /* Used for character, string, or code lengths */ PCRE2_SIZE back_frame; /* Amount to subtract on RRETURN */ PCRE2_SIZE temp_size; /* Used for short-term PCRE2_SIZE values */ @@ -841,11 +875,10 @@ typedef struct heapframe { PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ } heapframe; -/* This typedef is a check that the size of the heapframe structure is a -multiple of PCRE2_SIZE. See various comments above. */ +/* Assert that the size of the heapframe structure is a multiple of PCRE2_SIZE. +See various comments above. */ -typedef char check_heapframe_size[ - ((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0)? (+1):(-1)]; +STATIC_ASSERT((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0, heapframe_size); /* Structure for computing the alignment of heapframe. */ diff --git a/ext/pcre/pcre2lib/pcre2_jit_char_inc.h b/ext/pcre/pcre2lib/pcre2_jit_char_inc.h new file mode 100644 index 0000000000000..69fe938fc5bc0 --- /dev/null +++ b/ext/pcre/pcre2lib/pcre2_jit_char_inc.h @@ -0,0 +1,2280 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + This module by Zoltan Herczeg + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* XClass matching code. */ + +#ifdef SUPPORT_WIDE_CHARS + +#define ECLASS_CHAR_DATA STACK_TOP +#define ECLASS_STACK_DATA STACK_LIMIT + +#define SET_CHAR_OFFSET(value) \ + if ((value) != charoffset) \ + { \ + if ((value) < charoffset) \ + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ + else \ + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ + } \ + charoffset = (value); + +#define READ_FROM_CHAR_LIST(destination) \ + if (list_ind <= 1) \ + { \ + destination = *(const uint16_t*)next_char; \ + next_char += 2; \ + } \ + else \ + { \ + destination = *(const uint32_t*)next_char; \ + next_char += 4; \ + } + +#define XCLASS_LOCAL_RANGES_SIZE 32 +#define XCLASS_LOCAL_RANGES_LOG2_SIZE 5 + +typedef struct xclass_stack_item { + sljit_u32 first_item; + sljit_u32 last_item; + struct sljit_jump *jump; +} xclass_stack_item; + +typedef struct xclass_ranges { + size_t range_count; + /* Pointer to ranges. A stack area is provided when a small buffer is enough. */ + uint32_t *ranges; + uint32_t local_ranges[XCLASS_LOCAL_RANGES_SIZE * 2]; + /* Stack size must be log2(ranges / 2). */ + xclass_stack_item *stack; + xclass_stack_item local_stack[XCLASS_LOCAL_RANGES_LOG2_SIZE]; +} xclass_ranges; + +static void xclass_compute_ranges(compiler_common *common, PCRE2_SPTR cc, xclass_ranges *ranges) +{ +DEFINE_COMPILER; +size_t range_count = 0, est_range_count; +size_t est_stack_size, tmp; +uint32_t type, list_ind; +uint32_t est_type; +uint32_t char_list_add, range_start, range_end; +const uint8_t *next_char; +const uint8_t *est_next_char; +#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) +BOOL utf = common->utf; +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ + +if (*cc == XCL_SINGLE || *cc == XCL_RANGE) + { + /* Only a few ranges are present. */ + do + { + type = *cc++; + SLJIT_ASSERT(type == XCL_SINGLE || type == XCL_RANGE); + GETCHARINCTEST(range_end, cc); + ranges->ranges[range_count] = range_end; + + if (type == XCL_RANGE) + { + GETCHARINCTEST(range_end, cc); + } + + ranges->ranges[range_count + 1] = range_end; + range_count += 2; + } + while (*cc != XCL_END); + + SLJIT_ASSERT(range_count <= XCLASS_LOCAL_RANGES_SIZE); + ranges->range_count = range_count; + return; + } + +SLJIT_ASSERT(cc[0] >= XCL_LIST); +#if PCRE2_CODE_UNIT_WIDTH == 8 +type = (uint32_t)(cc[0] << 8) | cc[1]; +cc += 2; +#else +type = cc[0]; +cc++; +#endif /* CODE_UNIT_WIDTH */ + +/* Align characters. */ +next_char = (const uint8_t*)common->start - (GET(cc, 0) << 1); +type &= XCL_TYPE_MASK; + +/* Estimate size. */ +est_next_char = next_char; +est_type = type; +est_range_count = 0; +list_ind = 0; + +while (est_type > 0) + { + uint32_t item_count = est_type & XCL_ITEM_COUNT_MASK; + + if (item_count == XCL_ITEM_COUNT_MASK) + { + if (list_ind <= 1) + { + item_count = *(const uint16_t*)est_next_char; + est_next_char += 2; + } + else + { + item_count = *(const uint32_t*)est_next_char; + est_next_char += 4; + } + } + + est_type >>= XCL_TYPE_BIT_LEN; + est_next_char += (size_t)item_count << (list_ind <= 1 ? 1 : 2); + list_ind++; + est_range_count += item_count + 1; + } + +if (est_range_count > XCLASS_LOCAL_RANGES_SIZE) + { + est_stack_size = 0; + tmp = est_range_count - 1; + + /* Compute log2(est_range_count) */ + while (tmp > 0) + { + est_stack_size++; + tmp >>= 1; + } + + ranges->stack = (xclass_stack_item*)SLJIT_MALLOC((sizeof(xclass_stack_item) * est_stack_size) + + ((sizeof(uint32_t) << 1) * (size_t)est_range_count), compiler->allocator_data); + + if (ranges->stack == NULL) + { + sljit_set_compiler_memory_error(compiler); + ranges->ranges = NULL; + return; + } + + ranges->ranges = (uint32_t*)(ranges->stack + est_stack_size); + } + +char_list_add = XCL_CHAR_LIST_LOW_16_ADD; +range_start = ~(uint32_t)0; +list_ind = 0; + +if ((type & XCL_BEGIN_WITH_RANGE) != 0) + range_start = XCL_CHAR_LIST_LOW_16_START; + +while (type > 0) + { + uint32_t item_count = type & XCL_ITEM_COUNT_MASK; + + if (item_count == XCL_ITEM_COUNT_MASK) + { + READ_FROM_CHAR_LIST(item_count); + SLJIT_ASSERT(item_count >= XCL_ITEM_COUNT_MASK); + } + + while (item_count > 0) + { + READ_FROM_CHAR_LIST(range_end); + + if ((range_end & XCL_CHAR_END) != 0) + { + range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT); + + if (range_start == ~(uint32_t)0) + range_start = range_end; + + ranges->ranges[range_count] = range_start; + ranges->ranges[range_count + 1] = range_end; + range_count += 2; + range_start = ~(uint32_t)0; + } + else + range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT); + + item_count--; + } + + list_ind++; + type >>= XCL_TYPE_BIT_LEN; + + if (range_start == ~(uint32_t)0) + { + if ((type & XCL_BEGIN_WITH_RANGE) != 0) + { + if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START; +#if PCRE2_CODE_UNIT_WIDTH == 32 + else if (list_ind == 2) range_start = XCL_CHAR_LIST_LOW_32_START; + else range_start = XCL_CHAR_LIST_HIGH_32_START; +#else + else range_start = XCL_CHAR_LIST_LOW_32_START; +#endif + } + } + else if ((type & XCL_BEGIN_WITH_RANGE) == 0) + { + if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END; + else if (list_ind == 2) range_end = XCL_CHAR_LIST_HIGH_16_END; +#if PCRE2_CODE_UNIT_WIDTH == 32 + else if (list_ind == 3) range_end = XCL_CHAR_LIST_LOW_32_END; + else range_end = XCL_CHAR_LIST_HIGH_32_END; +#else + else range_end = XCL_CHAR_LIST_LOW_32_END; +#endif + + ranges->ranges[range_count] = range_start; + ranges->ranges[range_count + 1] = range_end; + range_count += 2; + range_start = ~(uint32_t)0; + } + + if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; +#if PCRE2_CODE_UNIT_WIDTH == 32 + else if (list_ind == 2) char_list_add = XCL_CHAR_LIST_LOW_32_ADD; + else char_list_add = XCL_CHAR_LIST_HIGH_32_ADD; +#else + else char_list_add = XCL_CHAR_LIST_LOW_32_ADD; +#endif + } + +SLJIT_ASSERT(range_count > 0 && range_count <= (est_range_count << 1)); +SLJIT_ASSERT(next_char <= (const uint8_t*)common->start); +ranges->range_count = range_count; +} + +static void xclass_check_bitset(compiler_common *common, const sljit_u8 *bitset, jump_list **found, jump_list **backtracks) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; + +jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); +if (!optimize_class(common, bitset, (bitset[31] & 0x80) != 0, TRUE, found)) + { + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)bitset); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); + add_jump(compiler, found, JUMP(SLJIT_NOT_ZERO)); + } + +add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); +JUMPHERE(jump); +} + +#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) + +static void xclass_update_min_max(compiler_common *common, PCRE2_SPTR cc, sljit_u32 *min_ptr, sljit_u32 *max_ptr) +{ +uint32_t type, list_ind, c; +sljit_u32 min = *min_ptr; +sljit_u32 max = *max_ptr; +uint32_t char_list_add; +const uint8_t *next_char; +BOOL utf = TRUE; + +/* This function is pointless without utf 8/16. */ +SLJIT_ASSERT(common->utf); +if (*cc == XCL_SINGLE || *cc == XCL_RANGE) + { + /* Only a few ranges are present. */ + do + { + type = *cc++; + SLJIT_ASSERT(type == XCL_SINGLE || type == XCL_RANGE); + GETCHARINCTEST(c, cc); + + if (c < min) + min = c; + + if (type == XCL_RANGE) + { + GETCHARINCTEST(c, cc); + } + + if (c > max) + max = c; + } + while (*cc != XCL_END); + + SLJIT_ASSERT(min <= MAX_UTF_CODE_POINT && max <= MAX_UTF_CODE_POINT && min <= max); + *min_ptr = min; + *max_ptr = max; + return; + } + +SLJIT_ASSERT(cc[0] >= XCL_LIST); +#if PCRE2_CODE_UNIT_WIDTH == 8 +type = (uint32_t)(cc[0] << 8) | cc[1]; +cc += 2; +#else +type = cc[0]; +cc++; +#endif /* CODE_UNIT_WIDTH */ + +/* Align characters. */ +next_char = (const uint8_t*)common->start - (GET(cc, 0) << 1); +type &= XCL_TYPE_MASK; + +SLJIT_ASSERT(type != 0); + +/* Detect minimum. */ + +/* Skip unused ranges. */ +list_ind = 0; +while ((type & (XCL_BEGIN_WITH_RANGE | XCL_ITEM_COUNT_MASK)) == 0) + { + type >>= XCL_TYPE_BIT_LEN; + list_ind++; + } + +SLJIT_ASSERT(list_ind <= 2); +switch (list_ind) + { + case 0: + char_list_add = XCL_CHAR_LIST_LOW_16_ADD; + c = XCL_CHAR_LIST_LOW_16_START; + break; + + case 1: + char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; + c = XCL_CHAR_LIST_HIGH_16_START; + break; + + default: + char_list_add = XCL_CHAR_LIST_LOW_32_ADD; + c = XCL_CHAR_LIST_LOW_32_START; + break; + } + +if ((type & XCL_BEGIN_WITH_RANGE) != 0) + { + if (c < min) + min = c; + } +else + { + if ((type & XCL_ITEM_COUNT_MASK) == XCL_ITEM_COUNT_MASK) + { + if (list_ind <= 1) + c = *(const uint16_t*)(next_char + 2); + else + c = *(const uint32_t*)(next_char + 4); + } + else + { + if (list_ind <= 1) + c = *(const uint16_t*)next_char; + else + c = *(const uint32_t*)next_char; + } + + c = char_list_add + (c >> XCL_CHAR_SHIFT); + if (c < min) + min = c; + } + +/* Detect maximum. */ + +/* Skip intermediate ranges. */ +while (TRUE) + { + if ((type & XCL_ITEM_COUNT_MASK) == XCL_ITEM_COUNT_MASK) + { + if (list_ind <= 1) + { + c = *(const uint16_t*)next_char; + next_char += (c + 1) << 1; + } + else + { + c = *(const uint32_t*)next_char; + next_char += (c + 1) << 2; + } + } + else + next_char += (type & XCL_ITEM_COUNT_MASK) << (list_ind <= 1 ? 1 : 2); + + if ((type >> XCL_TYPE_BIT_LEN) == 0) + break; + + list_ind++; + type >>= XCL_TYPE_BIT_LEN; + } + +SLJIT_ASSERT(list_ind <= 2 && type != 0); +switch (list_ind) + { + case 0: + char_list_add = XCL_CHAR_LIST_LOW_16_ADD; + c = XCL_CHAR_LIST_LOW_16_END; + break; + + case 1: + char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; + c = XCL_CHAR_LIST_HIGH_16_END; + break; + + default: + char_list_add = XCL_CHAR_LIST_LOW_32_ADD; + c = XCL_CHAR_LIST_LOW_32_END; + break; + } + +if ((type & XCL_ITEM_COUNT_MASK) != 0) + { + /* Type is reused as temporary. */ + if (list_ind <= 1) + type = *(const uint16_t*)(next_char - 2); + else + type = *(const uint32_t*)(next_char - 4); + + if (type & XCL_CHAR_END) + c = char_list_add + (type >> XCL_CHAR_SHIFT); + } + +if (c > max) + max = c; + +SLJIT_ASSERT(min <= MAX_UTF_CODE_POINT && max <= MAX_UTF_CODE_POINT && min <= max); +*min_ptr = min; +*max_ptr = max; +} + +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ + +#define XCLASS_IS_ECLASS 0x001 +#ifdef SUPPORT_UNICODE +#define XCLASS_SAVE_CHAR 0x002 +#define XCLASS_HAS_TYPE 0x004 +#define XCLASS_HAS_SCRIPT 0x008 +#define XCLASS_HAS_SCRIPT_EXTENSION 0x010 +#define XCLASS_HAS_BOOL 0x020 +#define XCLASS_HAS_BIDICL 0x040 +#define XCLASS_NEEDS_UCD (XCLASS_HAS_TYPE | XCLASS_HAS_SCRIPT | XCLASS_HAS_SCRIPT_EXTENSION | XCLASS_HAS_BOOL | XCLASS_HAS_BIDICL) +#define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080 +#define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100 +#define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0 0x200 +#endif /* SUPPORT_UNICODE */ + +static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); + +/* TMP3 must be preserved because it is used by compile_iterator_matchingpath. */ +static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, sljit_u32 status) +{ +DEFINE_COMPILER; +jump_list *found = NULL; +jump_list *check_result = NULL; +jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; +sljit_uw c, charoffset; +sljit_u32 max = READ_CHAR_MAX, min = 0; +struct sljit_jump *jump = NULL; +PCRE2_UCHAR flags; +PCRE2_SPTR ccbegin; +sljit_u32 compares, invertcmp, depth; +sljit_u32 first_item, last_item, mid_item; +sljit_u32 range_start, range_end; +xclass_ranges ranges; +BOOL has_cmov, last_range_set; + +#ifdef SUPPORT_UNICODE +sljit_u32 category_list = 0; +sljit_u32 items; +int typereg = TMP1; +#endif /* SUPPORT_UNICODE */ + +SLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw)); +/* Scanning the necessary info. */ +flags = *cc++; +ccbegin = cc; +compares = 0; + +if (flags & XCL_MAP) + cc += 32 / sizeof(PCRE2_UCHAR); + +#ifdef SUPPORT_UNICODE +while (*cc == XCL_PROP || *cc == XCL_NOTPROP) + { + compares++; + cc++; + + items = 0; + + switch(*cc) + { + case PT_LAMP: + items = UCPCAT3(ucp_Lu, ucp_Ll, ucp_Lt); + break; + + case PT_GC: + items = UCPCAT_RANGE(PRIV(ucp_typerange)[(int)cc[1] * 2], PRIV(ucp_typerange)[(int)cc[1] * 2 + 1]); + break; + + case PT_PC: + items = UCPCAT(cc[1]); + break; + + case PT_WORD: + items = UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N; + break; + + case PT_ALNUM: + items = UCPCAT_L | UCPCAT_N; + break; + + case PT_SCX: + status |= XCLASS_HAS_SCRIPT_EXTENSION; + if (cc[-1] == XCL_NOTPROP) + { + status |= XCLASS_SCRIPT_EXTENSION_NOTPROP; + break; + } + compares++; + /* Fall through */ + + case PT_SC: + status |= XCLASS_HAS_SCRIPT; + break; + + case PT_SPACE: + case PT_PXSPACE: + case PT_PXGRAPH: + case PT_PXPRINT: + case PT_PXPUNCT: + status |= XCLASS_SAVE_CHAR | XCLASS_HAS_TYPE; + break; + + case PT_UCNC: + case PT_PXXDIGIT: + status |= XCLASS_SAVE_CHAR; + break; + + case PT_BOOL: + status |= XCLASS_HAS_BOOL; + break; + + case PT_BIDICL: + status |= XCLASS_HAS_BIDICL; + break; + + default: + SLJIT_UNREACHABLE(); + break; + } + + if (items > 0) + { + if (cc[-1] == XCL_NOTPROP) + items ^= UCPCAT_ALL; + category_list |= items; + status |= XCLASS_HAS_TYPE; + compares--; + } + + cc += 2; + } + +if (category_list == UCPCAT_ALL) + { + /* All or no characters are accepted, same as dotall. */ + if (status & XCLASS_IS_ECLASS) + { + if (list != backtracks) + OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + return; + } + + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list == backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } + +if (category_list != 0) + compares++; +#endif + +if (*cc != XCL_END) + { +#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) + if (common->utf && compares == 0 && !(status & XCLASS_IS_ECLASS)) + { + SLJIT_ASSERT(category_list == 0); + max = 0; + min = (flags & XCL_MAP) != 0 ? 0 : READ_CHAR_MAX; + xclass_update_min_max(common, cc, &min, &max); + } +#endif + compares++; +#ifdef SUPPORT_UNICODE + status |= XCLASS_SAVE_CHAR; +#endif /* SUPPORT_UNICODE */ + } + +#ifdef SUPPORT_UNICODE +SLJIT_ASSERT(compares > 0 || category_list != 0); +#else /* !SUPPORT_UNICODE */ +SLJIT_ASSERT(compares > 0); +#endif /* SUPPORT_UNICODE */ + +/* We are not necessary in utf mode even in 8 bit mode. */ +cc = ccbegin; +if (!(status & XCLASS_IS_ECLASS)) + { + if ((flags & XCL_NOT) != 0) + read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + { +#ifdef SUPPORT_UNICODE + read_char(common, min, max, (status & XCLASS_NEEDS_UCD) ? backtracks : NULL, 0); +#else /* !SUPPORT_UNICODE */ + read_char(common, min, max, NULL, 0); +#endif /* SUPPORT_UNICODE */ + } + } + +if ((flags & XCL_MAP) != 0) + { + SLJIT_ASSERT(!(status & XCLASS_IS_ECLASS)); + xclass_check_bitset(common, (const sljit_u8 *)cc, &found, backtracks); + cc += 32 / sizeof(PCRE2_UCHAR); + } + +#ifdef SUPPORT_UNICODE +if (status & XCLASS_NEEDS_UCD) + { + if ((status & (XCLASS_SAVE_CHAR | XCLASS_IS_ECLASS)) == XCLASS_SAVE_CHAR) + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); + +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (!common->utf) + { + OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, UNASSIGNED_UTF_CHAR, TMP1); + } +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ + + OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); + OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); + OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + + ccbegin = cc; + + if (status & XCLASS_HAS_BIDICL) + { + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BIDICLASS_SHIFT); + + while (*cc == XCL_PROP || *cc == XCL_NOTPROP) + { + cc++; + + if (*cc == PT_BIDICL) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]); + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + cc += 2; + } + + cc = ccbegin; + } + + if (status & XCLASS_HAS_BOOL) + { + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, bprops)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BPROPS_MASK); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); + + while (*cc == XCL_PROP || *cc == XCL_NOTPROP) + { + cc++; + if (*cc == PT_BOOL) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + } + cc += 2; + } + + cc = ccbegin; + } + + if (status & XCLASS_HAS_SCRIPT) + { + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + + while (*cc == XCL_PROP || *cc == XCL_NOTPROP) + { + cc++; + + switch (*cc) + { + case PT_SCX: + if (cc[-1] == XCL_NOTPROP) + break; + /* Fall through */ + + case PT_SC: + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + + add_jump(compiler, compares > 0 ? list : backtracks, CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1])); + } + cc += 2; + } + + cc = ccbegin; + } + + if (status & XCLASS_HAS_SCRIPT_EXTENSION) + { + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_SCRIPTX_MASK); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); + + if (status & XCLASS_SCRIPT_EXTENSION_NOTPROP) + { + if (status & XCLASS_HAS_TYPE) + { + if ((status & (XCLASS_SAVE_CHAR | XCLASS_IS_ECLASS)) == XCLASS_SAVE_CHAR) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, TMP2, 0); + status |= XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0; + } + else + { + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0); + status |= XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR; + } + } + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + } + + while (*cc == XCL_PROP || *cc == XCL_NOTPROP) + { + cc++; + + if (*cc == PT_SCX) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + + jump = NULL; + if (cc[-1] == XCL_NOTPROP) + { + jump = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, (int)cc[1]); + if (invertcmp) + { + add_jump(compiler, backtracks, jump); + jump = NULL; + } + invertcmp ^= 0x1; + } + + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + + if (jump != NULL) + JUMPHERE(jump); + } + cc += 2; + } + + if (status & XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + else if (status & XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR) + OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0); + cc = ccbegin; + } + + if (status & XCLASS_SAVE_CHAR) + OP1(SLJIT_MOV, TMP1, 0, (status & XCLASS_IS_ECLASS) ? ECLASS_CHAR_DATA : RETURN_ADDR, 0); + + if (status & XCLASS_HAS_TYPE) + { + if (status & XCLASS_SAVE_CHAR) + typereg = RETURN_ADDR; + + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP2(SLJIT_SHL, typereg, 0, SLJIT_IMM, 1, TMP2, 0); + + if (category_list > 0) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, category_list); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + } + } + } +#endif /* SUPPORT_UNICODE */ + +/* Generating code. */ +charoffset = 0; + +#ifdef SUPPORT_UNICODE +while (*cc == XCL_PROP || *cc == XCL_NOTPROP) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + jump = NULL; + + if (*cc == XCL_NOTPROP) + invertcmp ^= 0x1; + cc++; + switch(*cc) + { + case PT_LAMP: + case PT_GC: + case PT_PC: + case PT_SC: + case PT_SCX: + case PT_BOOL: + case PT_BIDICL: + case PT_WORD: + case PT_ALNUM: + compares++; + /* Already handled. */ + break; + + case PT_SPACE: + case PT_PXSPACE: + SET_CHAR_OFFSET(9); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xd - 0x9); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_UCNC: + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + SET_CHAR_OFFSET(0xa0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + SET_CHAR_OFFSET(0); + OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_PXGRAPH: + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + + c = charoffset; + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + + JUMPHERE(jump); + jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPRINT: + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT2(ucp_Zl, ucp_Zp)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + + c = charoffset; + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + + JUMPHERE(jump); + jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPUNCT: + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Sc, ucp_So)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); + + SET_CHAR_OFFSET(0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f); + OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Pc, ucp_Ps)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_PXXDIGIT: + SET_CHAR_OFFSET(CHAR_A); + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, ~0x20); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP2, 0, SLJIT_IMM, CHAR_F - CHAR_A); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(CHAR_0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_9 - CHAR_0); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff10); + + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff19 - 0xff10); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff21); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff26 - 0xff21); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff41); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff41); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + + JUMPHERE(jump); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + default: + SLJIT_UNREACHABLE(); + break; + } + + cc += 2; + + if (jump != NULL) + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + +if (compares == 0) + { + if (found != NULL) + set_jumps(found, LABEL()); + + if (status & XCLASS_IS_ECLASS) + OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + return; + } +#endif /* SUPPORT_UNICODE */ + +SLJIT_ASSERT(compares == 1); +ranges.range_count = 0; +ranges.ranges = ranges.local_ranges; +ranges.stack = ranges.local_stack; + +xclass_compute_ranges(common, cc, &ranges); + +/* Memory error is set for the compiler. */ +if (ranges.stack == NULL) + return; + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) && \ + defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) +if (common->utf) + { + min = READ_CHAR_MAX; + max = 0; + xclass_update_min_max(common, cc, &min, &max); + SLJIT_ASSERT(ranges.ranges[0] == min && ranges.ranges[ranges.range_count - 1] == max); + } +#endif /* SLJIT_DEBUG && SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ + +invertcmp = (list != backtracks); + +if (ranges.range_count == 2) + { + range_start = ranges.ranges[0]; + range_end = ranges.ranges[1]; + + if (range_start < range_end) + { + SET_CHAR_OFFSET(range_start); + jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start)); + } + else + jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset)); + + add_jump(compiler, backtracks, jump); + + SLJIT_ASSERT(ranges.stack == ranges.local_stack); + if (found != NULL) + set_jumps(found, LABEL()); + + if (status & XCLASS_IS_ECLASS) + OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + return; + } + +range_start = ranges.ranges[0]; +SET_CHAR_OFFSET(range_start); +if (ranges.range_count >= 6) + { + /* Early fail. */ + range_end = ranges.ranges[ranges.range_count - 1]; + add_jump(compiler, (flags & XCL_NOT) == 0 ? backtracks : &found, + CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start))); + } + +depth = 0; +first_item = 0; +last_item = ranges.range_count - 2; +has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV) != 0; + +while (TRUE) + { + /* At least two items are present. */ + SLJIT_ASSERT(first_item < last_item && charoffset == ranges.ranges[0]); + last_range_set = FALSE; + + if (first_item + 6 <= last_item) + { + mid_item = ((first_item + last_item) >> 1) & ~(sljit_u32)1; + SLJIT_ASSERT(last_item >= mid_item + 4); + + range_end = ranges.ranges[mid_item + 1]; + if (first_item + 6 > mid_item && ranges.ranges[mid_item] == range_end) + { + OP2U(SLJIT_SUB | SLJIT_SET_GREATER | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - charoffset)); + ranges.stack[depth].jump = JUMP(SLJIT_GREATER); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + last_range_set = TRUE; + } + else + ranges.stack[depth].jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - charoffset)); + + ranges.stack[depth].first_item = (sljit_u32)(mid_item + 2); + ranges.stack[depth].last_item = (sljit_u32)last_item; + + depth++; + SLJIT_ASSERT(ranges.stack == ranges.local_stack ? + depth <= XCLASS_LOCAL_RANGES_LOG2_SIZE : (ranges.stack + depth) <= (xclass_stack_item*)ranges.ranges); + + last_item = mid_item; + if (!last_range_set) + continue; + + last_item -= 2; + } + + if (!last_range_set) + { + range_start = ranges.ranges[first_item]; + range_end = ranges.ranges[first_item + 1]; + + if (range_start < range_end) + { + SET_CHAR_OFFSET(range_start); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + } + else + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + } + first_item += 2; + } + + SLJIT_ASSERT(first_item <= last_item); + + do + { + range_start = ranges.ranges[first_item]; + range_end = ranges.ranges[first_item + 1]; + + if (range_start < range_end) + { + SET_CHAR_OFFSET(range_start); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start)); + + if (has_cmov) + SELECT(SLJIT_LESS_EQUAL, TMP2, STR_END, 0, TMP2); + else + OP_FLAGS(SLJIT_OR | ((first_item == last_item) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_LESS_EQUAL); + } + else + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset)); + + if (has_cmov) + SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2); + else + OP_FLAGS(SLJIT_OR | ((first_item == last_item) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); + } + + first_item += 2; + } + while (first_item <= last_item); + + if (depth == 0) break; + + add_jump(compiler, &check_result, JUMP(SLJIT_JUMP)); + + /* The charoffset resets after the end of a branch is reached. */ + charoffset = ranges.ranges[0]; + depth--; + first_item = ranges.stack[depth].first_item; + last_item = ranges.stack[depth].last_item; + JUMPHERE(ranges.stack[depth].jump); + } + +if (check_result != NULL) + set_jumps(check_result, LABEL()); + +if (has_cmov) + jump = CMP(SLJIT_NOT_EQUAL ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); +else + { + sljit_set_current_flags(compiler, SLJIT_SET_Z); + jump = JUMP(SLJIT_NOT_EQUAL ^ invertcmp); + } + +add_jump(compiler, backtracks, jump); + +if (found != NULL) + set_jumps(found, LABEL()); + +if (status & XCLASS_IS_ECLASS) + OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + +if (ranges.stack != ranges.local_stack) + SLJIT_FREE(ranges.stack, compiler->allocator_data); +} + +static PCRE2_SPTR compile_eclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +PCRE2_SPTR end = cc + GET(cc, 0) - 1; +PCRE2_SPTR begin; +jump_list *not_found; +jump_list *found = NULL; + +cc += LINK_SIZE; + +/* Should be optimized later. */ +read_char(common, 0, READ_CHAR_MAX, backtracks, 0); + +if (((*cc++) & ECL_MAP) != 0) + { + xclass_check_bitset(common, (const sljit_u8 *)cc, &found, backtracks); + cc += 32 / sizeof(PCRE2_UCHAR); + } + +begin = cc; + +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, ECLASS_CHAR_DATA, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, ECLASS_STACK_DATA, 0); +OP1(SLJIT_MOV, ECLASS_STACK_DATA, 0, SLJIT_IMM, 0); +OP1(SLJIT_MOV, ECLASS_CHAR_DATA, 0, TMP1, 0); + +/* All eclass must start with an xclass. */ +SLJIT_ASSERT(*cc == ECL_XCLASS); + +while (cc < end) + { + switch (*cc) + { + case ECL_AND: + ++cc; + OP2(SLJIT_OR, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, ~(sljit_sw)1); + OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + OP2(SLJIT_AND, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0); + break; + + case ECL_OR: + ++cc; + OP2(SLJIT_AND, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0); + break; + + case ECL_XOR: + ++cc; + OP2(SLJIT_AND, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + OP2(SLJIT_XOR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0); + break; + + case ECL_NOT: + ++cc; + OP2(SLJIT_XOR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + break; + + default: + SLJIT_ASSERT(*cc == ECL_XCLASS); + if (cc != begin) + { + OP1(SLJIT_MOV, TMP1, 0, ECLASS_CHAR_DATA, 0); + OP2(SLJIT_SHL, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); + } + + not_found = NULL; + compile_xclass_matchingpath(common, cc + 1 + LINK_SIZE, ¬_found, XCLASS_IS_ECLASS); + set_jumps(not_found, LABEL()); + + cc += GET(cc, 1); + break; + } + } + +OP2U(SLJIT_SUB | SLJIT_SET_Z, ECLASS_STACK_DATA, 0, SLJIT_IMM, 0); +OP1(SLJIT_MOV, ECLASS_CHAR_DATA, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); +OP1(SLJIT_MOV, ECLASS_STACK_DATA, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); +add_jump(compiler, backtracks, JUMP(SLJIT_EQUAL)); +set_jumps(found, LABEL()); +return end; +} + +/* Generic character matching code. */ + +#undef SET_CHAR_OFFSET +#undef READ_FROM_CHAR_LIST +#undef XCLASS_LOCAL_RANGES_SIZE +#undef XCLASS_LOCAL_RANGES_LOG2_SIZE + +#endif /* SUPPORT_WIDE_CHARS */ + +static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, + compare_context *context, jump_list **backtracks) +{ +DEFINE_COMPILER; +unsigned int othercasebit = 0; +PCRE2_SPTR othercasechar = NULL; +#ifdef SUPPORT_UNICODE +int utflength; +#endif + +if (caseless && char_has_othercase(common, cc)) + { + othercasebit = char_get_othercase_bit(common, cc); + SLJIT_ASSERT(othercasebit); + /* Extracting bit difference info. */ +#if PCRE2_CODE_UNIT_WIDTH == 8 + othercasechar = cc + (othercasebit >> 8); + othercasebit &= 0xff; +#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + /* Note that this code only handles characters in the BMP. If there + ever are characters outside the BMP whose othercase differs in only one + bit from itself (there currently are none), this code will need to be + revised for PCRE2_CODE_UNIT_WIDTH == 32. */ + othercasechar = cc + (othercasebit >> 9); + if ((othercasebit & 0x100) != 0) + othercasebit = (othercasebit & 0xff) << 8; + else + othercasebit &= 0xff; +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ + } + +if (context->sourcereg == -1) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#elif PCRE2_CODE_UNIT_WIDTH == 32 + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ + context->sourcereg = TMP2; + } + +#ifdef SUPPORT_UNICODE +utflength = 1; +if (common->utf && HAS_EXTRALEN(*cc)) + utflength += GET_EXTRALEN(*cc); + +do + { +#endif + + context->length -= IN_UCHARS(1); +#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) + + /* Unaligned read is supported. */ + if (othercasebit != 0 && othercasechar == cc) + { + context->c.asuchars[context->ucharptr] = *cc | othercasebit; + context->oc.asuchars[context->ucharptr] = othercasebit; + } + else + { + context->c.asuchars[context->ucharptr] = *cc; + context->oc.asuchars[context->ucharptr] = 0; + } + context->ucharptr++; + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) +#else + if (context->ucharptr >= 2 || context->length == 0) +#endif + { + if (context->length >= 4) + OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#if PCRE2_CODE_UNIT_WIDTH == 8 + else if (context->length >= 1) + OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + switch(context->ucharptr) + { + case 4 / sizeof(PCRE2_UCHAR): + if (context->oc.asint != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); + break; + + case 2 / sizeof(PCRE2_UCHAR): + if (context->oc.asushort != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); + break; + +#if PCRE2_CODE_UNIT_WIDTH == 8 + case 1: + if (context->oc.asbyte != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); + break; +#endif + + default: + SLJIT_UNREACHABLE(); + break; + } + context->ucharptr = 0; + } + +#else + + /* Unaligned read is unsupported or in 32 bit mode. */ + if (context->length >= 1) + OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + if (othercasebit != 0 && othercasechar == cc) + { + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); + +#endif + + cc++; +#ifdef SUPPORT_UNICODE + utflength--; + } +while (utflength > 0); +#endif + +return cc; +} + +#ifdef SUPPORT_UNICODE + +#if PCRE2_CODE_UNIT_WIDTH != 32 + +/* The code in this function copies the logic of the interpreter function that +is defined in the pcre2_extuni.c source. If that code is updated, this +function, and those below it, must be kept in step (note by PH, June 2024). */ + +static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc) +{ +PCRE2_SPTR start_subject = args->begin; +PCRE2_SPTR end_subject = args->end; +int lgb, rgb, ricount; +PCRE2_SPTR prevcc, endcc, bptr; +BOOL first = TRUE; +BOOL was_ep_ZWJ = FALSE; +uint32_t c; + +prevcc = cc; +endcc = NULL; +do + { + GETCHARINC(c, cc); + rgb = UCD_GRAPHBREAK(c); + + if (first) + { + lgb = rgb; + endcc = cc; + first = FALSE; + continue; + } + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; + + /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was + preceded by Extended Pictographic. */ + + if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) + break; + + /* Not breaking between Regional Indicators is allowed only if there + are an even number of preceding RIs. */ + + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) + { + ricount = 0; + bptr = prevcc; + + /* bptr is pointing to the left-hand character */ + while (bptr > start_subject) + { + bptr--; + BACKCHAR(bptr); + GETCHAR(c, bptr); + + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) + break; + + ricount++; + } + + if ((ricount & 1) != 0) break; /* Grapheme break required */ + } + + /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in + between; see next statement). */ + + was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); + + /* If Extend follows Extended_Pictographic, do not update lgb; this allows + any number of them before a following ZWJ. */ + + if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) + lgb = rgb; + + prevcc = endcc; + endcc = cc; + } +while (cc < end_subject); + +return endcc; +} + +#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ + +/* The code in this function copies the logic of the interpreter function that +is defined in the pcre2_extuni.c source. If that code is updated, this +function, and the one below it, must be kept in step (note by PH, June 2024). */ + +static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc) +{ +PCRE2_SPTR start_subject = args->begin; +PCRE2_SPTR end_subject = args->end; +int lgb, rgb, ricount; +PCRE2_SPTR prevcc, endcc, bptr; +BOOL first = TRUE; +BOOL was_ep_ZWJ = FALSE; +uint32_t c; + +prevcc = cc; +endcc = NULL; +do + { + GETCHARINC_INVALID(c, cc, end_subject, break); + rgb = UCD_GRAPHBREAK(c); + + if (first) + { + lgb = rgb; + endcc = cc; + first = FALSE; + continue; + } + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; + + /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was + preceded by Extended Pictographic. */ + + if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) + break; + + /* Not breaking between Regional Indicators is allowed only if there + are an even number of preceding RIs. */ + + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) + { + ricount = 0; + bptr = prevcc; + + /* bptr is pointing to the left-hand character */ + while (bptr > start_subject) + { + GETCHARBACK_INVALID(c, bptr, start_subject, break); + + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) + break; + + ricount++; + } + + if ((ricount & 1) != 0) + break; /* Grapheme break required */ + } + + /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in + between; see next statement). */ + + was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); + + /* If Extend follows Extended_Pictographic, do not update lgb; this allows + any number of them before a following ZWJ. */ + + if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) + lgb = rgb; + + prevcc = endcc; + endcc = cc; + } +while (cc < end_subject); + +return endcc; +} + +/* The code in this function copies the logic of the interpreter function that +is defined in the pcre2_extuni.c source. If that code is updated, this +function must be kept in step (note by PH, June 2024). */ + +static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc) +{ +PCRE2_SPTR start_subject = args->begin; +PCRE2_SPTR end_subject = args->end; +int lgb, rgb, ricount; +PCRE2_SPTR bptr; +uint32_t c; +BOOL was_ep_ZWJ = FALSE; + +/* Patch by PH */ +/* GETCHARINC(c, cc); */ +c = *cc++; + +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (c >= 0x110000) + return cc; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ +lgb = UCD_GRAPHBREAK(c); + +while (cc < end_subject) + { + c = *cc; +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x110000) + break; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ + rgb = UCD_GRAPHBREAK(c); + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; + + /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was + preceded by Extended Pictographic. */ + + if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) + break; + + /* Not breaking between Regional Indicators is allowed only if there + are an even number of preceding RIs. */ + + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) + { + ricount = 0; + bptr = cc - 1; + + /* bptr is pointing to the left-hand character */ + while (bptr > start_subject) + { + bptr--; + c = *bptr; +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x110000) + break; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ + + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; + + ricount++; + } + + if ((ricount & 1) != 0) + break; /* Grapheme break required */ + } + + /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in + between; see next statement). */ + + was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); + + /* If Extend follows Extended_Pictographic, do not update lgb; this allows + any number of them before a following ZWJ. */ + + if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) + lgb = rgb; + + cc++; + } + +return cc; +} + +static void compile_clist(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +const sljit_u32 *other_cases; +struct sljit_jump *jump; +sljit_u32 min = 0, max = READ_CHAR_MAX; +BOOL has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV) != 0; + +SLJIT_ASSERT(cc[1] == PT_CLIST); + +if (cc[0] == OP_PROP) + { + other_cases = PRIV(ucd_caseless_sets) + cc[2]; + + min = *other_cases++; + max = min; + + while (*other_cases != NOTACHAR) + { + if (*other_cases > max) max = *other_cases; + if (*other_cases < min) min = *other_cases; + other_cases++; + } + } + +other_cases = PRIV(ucd_caseless_sets) + cc[2]; +SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR); +/* The NOTACHAR is higher than any character. */ +SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); + +read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); + +/* At least two characters are required. + Otherwise this case would be handled by the normal code path. */ +/* NOTACHAR is the unsigned maximum. */ + +/* Optimizing character pairs, if their difference is power of 2. */ +if (is_powerof2(other_cases[1] ^ other_cases[0])) + { + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[1] ^ other_cases[0])); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[1]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + other_cases += 2; + } +else if (is_powerof2(other_cases[2] ^ other_cases[1])) + { + SLJIT_ASSERT(other_cases[2] != NOTACHAR); + + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[2] ^ other_cases[1])); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[2]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)other_cases[0]); + + if (has_cmov) + SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2); + else + OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); + + other_cases += 3; + } +else + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + } + +while (*other_cases != NOTACHAR) + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++)); + + if (has_cmov) + SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2); + else + OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); + } + +if (has_cmov) + jump = CMP(cc[0] == OP_PROP ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0); +else + jump = JUMP(cc[0] == OP_PROP ? SLJIT_ZERO : SLJIT_NOT_ZERO); + +add_jump(compiler, backtracks, jump); +} + +#endif /* SUPPORT_UNICODE */ + +static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr) +{ +DEFINE_COMPILER; +int length; +unsigned int c, oc, bit; +compare_context context; +struct sljit_jump *jump[3]; +jump_list *end_list; +#ifdef SUPPORT_UNICODE +PCRE2_UCHAR propdata[5]; +#endif /* SUPPORT_UNICODE */ + +switch(type) + { + case OP_NOT_DIGIT: + case OP_DIGIT: + /* Digits are usually 0-9, so it is worth to optimize them. */ + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE)) + read_char7_type(common, backtracks, type == OP_NOT_DIGIT); + else +#endif + read_char8_type(common, backtracks, type == OP_NOT_DIGIT); + /* Flip the starting bit in the negative case. */ + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_digit); + add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE)) + read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE); + else +#endif + read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_space); + add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE)) + read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR); + else +#endif + read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_word); + add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_ANY: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + end_list = NULL; + if (common->mode != PCRE2_JIT_PARTIAL_HARD) + add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + else + check_str_end(common, &end_list); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); + set_jumps(end_list, LABEL()); + JUMPHERE(jump[0]); + } + else + check_newlinechar(common, common->nltype, backtracks, TRUE); + return cc; + + case OP_ALLANY: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#ifdef SUPPORT_UNICODE + if (common->utf && common->invalid_utf) + { + read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); + return cc; + } +#endif /* SUPPORT_UNICODE */ + + skip_valid_char(common); + return cc; + + case OP_ANYBYTE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + return cc; + +#ifdef SUPPORT_UNICODE + case OP_NOTPROP: + case OP_PROP: + if (check_str_ptr) + detect_partial_match(common, backtracks); + if (cc[0] == PT_CLIST) + { + compile_clist(common, cc - 1, backtracks); + return cc + 2; + } + + propdata[0] = 0; + propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; + propdata[2] = cc[0]; + propdata[3] = cc[1]; + propdata[4] = XCL_END; + compile_xclass_matchingpath(common, propdata, backtracks, 0); + return cc + 2; +#endif + + case OP_ANYNL: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0); + jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + /* We don't need to handle soft partial matching case. */ + end_list = NULL; + if (common->mode != PCRE2_JIT_PARTIAL_HARD) + add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + else + check_str_end(common, &end_list); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + jump[1] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[0]); + check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); + set_jumps(end_list, LABEL()); + JUMPHERE(jump[1]); + return cc; + + case OP_NOT_HSPACE: + case OP_HSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + if (type == OP_NOT_HSPACE) + read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0x9, 0x3000, NULL, 0); + + add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); + sljit_set_current_flags(compiler, SLJIT_SET_Z); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + + case OP_NOT_VSPACE: + case OP_VSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + if (type == OP_NOT_VSPACE) + read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0xa, 0x2029, NULL, 0); + + add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); + sljit_set_current_flags(compiler, SLJIT_SET_Z); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + +#ifdef SUPPORT_UNICODE + case OP_EXTUNI: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); + OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); + +#if PCRE2_CODE_UNIT_WIDTH != 32 + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, + common->utf ? (common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_utf)) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); +#else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, + common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); +#endif + + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + + if (common->mode == PCRE2_JIT_PARTIAL_HARD) + { + jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0); + /* Since we successfully read a char above, partial matching must occur. */ + check_partial(common, TRUE); + JUMPHERE(jump[0]); + } + return cc; +#endif + + case OP_CHAR: + case OP_CHARI: + length = 1; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); +#endif + + if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE) + detect_partial_match(common, backtracks); + + if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) + { + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); + if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); + + context.length = IN_UCHARS(length); + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); + } + +#ifdef SUPPORT_UNICODE + if (common->utf) + { + GETCHAR(c, cc); + } + else +#endif + c = *cc; + + SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc)); + + if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + + oc = char_othercase(common, c); + read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0); + + SLJIT_ASSERT(!is_powerof2(c ^ oc)); + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc); + SELECT(SLJIT_EQUAL, TMP1, SLJIT_IMM, c, TMP1); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + } + else + { + jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + JUMPHERE(jump[0]); + } + return cc + length; + + case OP_NOT: + case OP_NOTI: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + length = 1; +#ifdef SUPPORT_UNICODE + if (common->utf) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + c = *cc; + if (c < 128 && !common->invalid_utf) + { + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + if (type == OP_NOT || !char_has_othercase(common, cc)) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + else + { + /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); + } + /* Skip the variable-length character. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(jump[0]); + return cc + 1; + } + else +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + { + GETCHARLEN(c, cc, length); + } + } + else +#endif /* SUPPORT_UNICODE */ + c = *cc; + + if (type == OP_NOT || !char_has_othercase(common, cc)) + { + read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + } + else + { + oc = char_othercase(common, c); + read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR); + bit = c ^ oc; + if (is_powerof2(bit)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); + } + else + { + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + } + } + return cc + length; + + case OP_CLASS: + case OP_NCLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255; + if (type == OP_NCLASS) + read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0, bit, NULL, 0); +#else + if (type == OP_NCLASS) + read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0, 255, NULL, 0); +#endif + + if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks)) + return cc + 32 / sizeof(PCRE2_UCHAR); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + jump[0] = NULL; + if (common->utf) + { + jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit); + if (type == OP_CLASS) + { + add_jump(compiler, backtracks, jump[0]); + jump[0] = NULL; + } + } +#elif PCRE2_CODE_UNIT_WIDTH != 8 + jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (type == OP_CLASS) + { + add_jump(compiler, backtracks, jump[0]); + jump[0] = NULL; + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ + + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); + add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + if (jump[0] != NULL) + JUMPHERE(jump[0]); +#endif + return cc + 32 / sizeof(PCRE2_UCHAR); + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + case OP_XCLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); + compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks, 0); + return cc + GET(cc, 0) - 1; + + case OP_ECLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); + return compile_eclass_matchingpath(common, cc, backtracks); +#endif + } +SLJIT_UNREACHABLE(); +return cc; +} + +static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks) +{ +/* This function consumes at least one input character. */ +/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ +DEFINE_COMPILER; +PCRE2_SPTR ccbegin = cc; +compare_context context; +int size; + +context.length = 0; +do + { + if (cc >= ccend) + break; + + if (*cc == OP_CHAR) + { + size = 1; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); +#endif + } + else if (*cc == OP_CHARI) + { + size = 1; +#ifdef SUPPORT_UNICODE + if (common->utf) + { + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + else if (HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); + } + else +#endif + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + } + else + size = 0; + + cc += 1 + size; + context.length += IN_UCHARS(size); + } +while (size > 0 && context.length <= 128); + +cc = ccbegin; +if (context.length > 0) + { + /* We have a fixed-length byte sequence. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); + + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); + return cc; + } + +/* A non-fixed length character will be checked if length == 0. */ +return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); +} + + diff --git a/ext/pcre/pcre2lib/pcre2_jit_compile.c b/ext/pcre/pcre2lib/pcre2_jit_compile.c index 92f4fb858b108..7fd10d5eaf390 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_compile.c +++ b/ext/pcre/pcre2lib/pcre2_jit_compile.c @@ -282,14 +282,14 @@ typedef struct bracket_backtrack { struct sljit_label *zero_matchingpath; /* Contains the branches of a failed condition. */ union { - /* Both for OP_COND, OP_SCOND. */ - jump_list *condfailed; + /* Both for OP_COND, OP_SCOND, OP_ASSERT_SCS. */ + jump_list *no_capture; assert_backtrack *assert; /* For OP_ONCE. Less than 0 if not needed. */ int framesize; - /* For brackets with >3 alternatives. */ - struct sljit_jump *matching_mov_addr; } u; + /* For brackets with >3 alternatives. */ + struct sljit_jump *matching_mov_addr; /* Points to our private memory word on the stack. */ int private_data_ptr; } bracket_backtrack; @@ -313,14 +313,12 @@ typedef struct char_iterator_backtrack { backtrack_common common; /* Next iteration. */ struct sljit_label *matchingpath; - union { - jump_list *backtracks; - struct { - unsigned int othercasebit; - PCRE2_UCHAR chr; - BOOL enabled; - } charpos; - } u; + /* Creating a range based on the next character. */ + struct { + unsigned int othercasebit; + PCRE2_UCHAR chr; + BOOL charpos_enabled; + } charpos; } char_iterator_backtrack; typedef struct ref_iterator_backtrack { @@ -408,6 +406,10 @@ typedef struct compiler_common { then_trap_backtrack *then_trap; /* Starting offset of private data for capturing brackets. */ sljit_s32 cbra_ptr; +#if defined SLJIT_DEBUG && SLJIT_DEBUG + /* End offset of locals for assertions. */ + sljit_s32 locals_size; +#endif /* Output vector starting point. Must be divisible by 2. */ sljit_s32 ovector_start; /* Points to the starting character of the current match. */ @@ -429,6 +431,11 @@ typedef struct compiler_common { Each item must have a previous offset and type (see control_types) values. See do_search_mark. */ sljit_s32 control_head_ptr; + /* The offset of the saved STR_END in the outermost + scan substring block. Since scan substring restores + STR_END after a match, it is enough to restore + STR_END inside a scan substring block. */ + sljit_s32 restore_end_ptr; /* Points to the last matched capture block index. */ sljit_s32 capture_last_ptr; /* Fast forward skipping byte code pointer. */ @@ -513,7 +520,6 @@ typedef struct compiler_common { BOOL invalid_utf; BOOL ucp; /* Points to saving area for iref. */ - sljit_s32 iref_ptr; jump_list *getucd; jump_list *getucdtype; #if PCRE2_CODE_UNIT_WIDTH == 8 @@ -603,14 +609,14 @@ typedef struct compare_context { #endif /* Local space layout. */ -/* These two locals can be used by the current opcode. */ -#define LOCALS0 (0 * sizeof(sljit_sw)) -#define LOCALS1 (1 * sizeof(sljit_sw)) -/* Two local variables for possessive quantifiers (char1 cannot use them). */ -#define POSSESSIVE0 (2 * sizeof(sljit_sw)) -#define POSSESSIVE1 (3 * sizeof(sljit_sw)) /* Max limit of recursions. */ -#define LIMIT_MATCH (4 * sizeof(sljit_sw)) +#define LIMIT_MATCH (0 * sizeof(sljit_sw)) +/* Local variables. Their number is computed by check_opcode_types. */ +#define LOCAL0 (1 * sizeof(sljit_sw)) +#define LOCAL1 (2 * sizeof(sljit_sw)) +#define LOCAL2 (3 * sizeof(sljit_sw)) +#define LOCAL3 (4 * sizeof(sljit_sw)) +#define LOCAL4 (5 * sizeof(sljit_sw)) /* The output vector is stored on the stack, and contains pointers to characters. The vector data is divided into two groups: the first group contains the start / end character pointers, and the second is @@ -667,7 +673,7 @@ the start pointers when the end of the capturing group has not yet reached. */ #define GET_LOCAL_BASE(dst, dstw, offset) \ sljit_get_local_base(compiler, (dst), (dstw), (offset)) -#define READ_CHAR_MAX 0x7fffffff +#define READ_CHAR_MAX ((sljit_u32)0xffffffff) #define INVALID_UTF_CHAR -1 #define UNASSIGNED_UTF_CHAR 888 @@ -862,7 +868,7 @@ the start pointers when the end of the capturing group has not yet reached. */ static PCRE2_SPTR bracketend(PCRE2_SPTR cc) { -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERT_SCS) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); do cc += GET(cc, 1); while (*cc == OP_ALT); SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); cc += 1 + LINK_SIZE; @@ -872,7 +878,7 @@ return cc; static int no_alternatives(PCRE2_SPTR cc) { int count = 0; -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERT_SCS) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); do { cc += GET(cc, 1); @@ -975,6 +981,7 @@ switch(*cc) case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -1097,7 +1104,9 @@ switch(*cc) return cc + GET(cc, 1 + 2*LINK_SIZE); #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + case OP_ECLASS: case OP_XCLASS: + SLJIT_COMPILE_ASSERT(OP_XCLASS + 1 == OP_ECLASS && OP_CLASS + 1 == OP_NCLASS && OP_NCLASS < OP_XCLASS, class_byte_code_order); return cc + GET(cc, 1); #endif @@ -1114,12 +1123,36 @@ switch(*cc) } } +static sljit_s32 ref_update_local_size(compiler_common *common, PCRE2_SPTR cc, sljit_s32 current_locals_size) +{ +/* Depends on do_casefulcmp(), do_caselesscmp(), and compile_ref_matchingpath() */ +int locals_size = 2 * SSIZE_OF(sw); +SLJIT_UNUSED_ARG(common); + +#ifdef SUPPORT_UNICODE +if ((*cc == OP_REFI || *cc == OP_DNREFI) && (common->utf || common->ucp)) + locals_size = 3 * SSIZE_OF(sw); +#endif + +cc += PRIV(OP_lengths)[*cc]; +/* Although do_casefulcmp() uses only one local, the allocate_stack() +calls during the repeat destroys LOCAL1 variables. */ +if (*cc >= OP_CRSTAR && *cc <= OP_CRPOSRANGE) + locals_size += 2 * SSIZE_OF(sw); + +return (current_locals_size >= locals_size) ? current_locals_size : locals_size; +} + static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend) { int count; PCRE2_SPTR slot; PCRE2_SPTR assert_back_end = cc - 1; PCRE2_SPTR assert_na_end = cc - 1; +sljit_s32 locals_size = 2 * SSIZE_OF(sw); +BOOL set_recursive_head = FALSE; +BOOL set_capture_last = FALSE; +BOOL set_mark = FALSE; /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ while (cc < ccend) @@ -1132,22 +1165,41 @@ while (cc < ccend) cc += 1; break; + case OP_TYPEUPTO: + case OP_TYPEEXACT: + if (cc[1 + IMM2_SIZE] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw)) + locals_size = 3 * SSIZE_OF(sw); + cc += (2 + IMM2_SIZE) - 1; + break; + + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + if (cc[1] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw)) + locals_size = 3 * SSIZE_OF(sw); + cc += 2 - 1; + break; + + case OP_TYPEPOSUPTO: +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf && locals_size <= 3 * SSIZE_OF(sw)) + locals_size = 3 * SSIZE_OF(sw); +#endif + if (cc[1 + IMM2_SIZE] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw)) + locals_size = 3 * SSIZE_OF(sw); + cc += (2 + IMM2_SIZE) - 1; + break; + case OP_REFI: -#ifdef SUPPORT_UNICODE - if (common->iref_ptr == 0) - { - common->iref_ptr = common->ovector_start; - common->ovector_start += 3 * sizeof(sljit_sw); - } -#endif /* SUPPORT_UNICODE */ - /* Fall through. */ case OP_REF: + locals_size = ref_update_local_size(common, cc, locals_size); common->optimized_cbracket[GET2(cc, 1)] = 0; - cc += 1 + IMM2_SIZE; + cc += PRIV(OP_lengths)[*cc]; break; case OP_ASSERT_NA: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: slot = bracketend(cc); if (slot > assert_na_end) assert_na_end = slot; @@ -1174,8 +1226,10 @@ while (cc < ccend) cc += 1 + IMM2_SIZE; break; - case OP_DNREF: case OP_DNREFI: + case OP_DNREF: + locals_size = ref_update_local_size(common, cc, locals_size); + /* Fall through */ case OP_DNCREF: count = GET2(cc, 1 + IMM2_SIZE); slot = common->name_table + GET2(cc, 1) * common->name_entry_size; @@ -1184,26 +1238,18 @@ while (cc < ccend) common->optimized_cbracket[GET2(slot, 0)] = 0; slot += common->name_entry_size; } - cc += 1 + 2 * IMM2_SIZE; + cc += PRIV(OP_lengths)[*cc]; break; case OP_RECURSE: /* Set its value only once. */ - if (common->recursive_head_ptr == 0) - { - common->recursive_head_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } + set_recursive_head = TRUE; cc += 1 + LINK_SIZE; break; case OP_CALLOUT: case OP_CALLOUT_STR: - if (common->capture_last_ptr == 0) - { - common->capture_last_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } + set_capture_last = TRUE; cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE); break; @@ -1221,15 +1267,8 @@ while (cc < ccend) case OP_COMMIT_ARG: case OP_PRUNE_ARG: - if (cc < assert_na_end) - return FALSE; - /* Fall through */ case OP_MARK: - if (common->mark_ptr == 0) - { - common->mark_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } + set_mark = TRUE; cc += 1 + 2 + cc[1]; break; @@ -1242,8 +1281,6 @@ while (cc < ccend) case OP_SKIP: if (cc < assert_back_end) common->has_skip_in_assert_back = TRUE; - if (cc < assert_na_end) - return FALSE; cc += 1; break; @@ -1252,19 +1289,31 @@ while (cc < ccend) common->has_skip_arg = TRUE; if (cc < assert_back_end) common->has_skip_in_assert_back = TRUE; - if (cc < assert_na_end) - return FALSE; cc += 1 + 2 + cc[1]; break; - case OP_PRUNE: - case OP_COMMIT: case OP_ASSERT_ACCEPT: if (cc < assert_na_end) return FALSE; cc++; break; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + case OP_CRPOSRANGE: + /* The second value can be 0 for infinite repeats. */ + if (common->utf && GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE) && locals_size <= 3 * SSIZE_OF(sw)) + locals_size = 3 * SSIZE_OF(sw); + cc += 1 + 2 * IMM2_SIZE; + break; + + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + if (common->utf && locals_size <= 3 * SSIZE_OF(sw)) + locals_size = 3 * SSIZE_OF(sw); +#endif + /* Fall through */ default: cc = next_opcode(common, cc); if (cc == NULL) @@ -1272,6 +1321,36 @@ while (cc < ccend) break; } } + +SLJIT_ASSERT((locals_size & (SSIZE_OF(sw) - 1)) == 0); +#if defined SLJIT_DEBUG && SLJIT_DEBUG +common->locals_size = locals_size; +#endif + +if (locals_size > 0) + common->ovector_start += locals_size; + +if (set_mark) + { + SLJIT_ASSERT(common->mark_ptr == 0); + common->mark_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + +if (set_recursive_head) + { + SLJIT_ASSERT(common->recursive_head_ptr == 0); + common->recursive_head_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + +if (set_capture_last) + { + SLJIT_ASSERT(common->capture_last_ptr == 0); + common->capture_last_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } + return TRUE; } @@ -1512,8 +1591,9 @@ do case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: + case OP_ECLASS: accelerated_start = cc; - cc += ((*cc == OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR)))); + cc += (*cc >= OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR))); #else accelerated_start = cc; cc += (1 + (32 / sizeof(PCRE2_UCHAR))); @@ -1687,7 +1767,7 @@ switch(*cc) if (max == 0) return (*cc == OP_CRRANGE) ? 2 : 1; max -= min; - if (max > 2) + if (max > (sljit_u32)(*cc == OP_CRRANGE ? 0 : 1)) max = 2; return max; @@ -1905,6 +1985,12 @@ while (cc < ccend) bracketlen = 1 + LINK_SIZE; break; + case OP_ASSERT_SCS: + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += 2 * sizeof(sljit_sw); + bracketlen = 1 + LINK_SIZE; + break; + case OP_CBRAPOS: case OP_SCBRAPOS: common->private_data_ptrs[cc - common->start] = private_data_ptr; @@ -1962,13 +2048,13 @@ while (cc < ccend) CASE_ITERATOR_TYPE_PRIVATE_DATA_2A size = 1; - if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) + if (cc[1] != OP_EXTUNI) space = 2; break; case OP_TYPEUPTO: size = 1 + IMM2_SIZE; - if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) + if (cc[1 + IMM2_SIZE] != OP_EXTUNI) space = 2; break; @@ -1985,6 +2071,7 @@ while (cc < ccend) #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: + case OP_ECLASS: size = GET(cc, 1); space = get_class_iterator_size(cc + size); break; @@ -2200,6 +2287,7 @@ while (cc < ccend) case OP_CLASS: case OP_NCLASS: case OP_XCLASS: + case OP_ECLASS: case OP_CALLOUT: case OP_CALLOUT_STR: @@ -2242,6 +2330,7 @@ if (ccend == NULL) cc = next_opcode(common, cc); } +/* The data is restored by do_revertframes(). */ SLJIT_ASSERT(cc != NULL); while (cc < ccend) switch(*cc) @@ -2516,6 +2605,13 @@ while (cc < ccend) cc += 1 + LINK_SIZE; break; + case OP_ASSERT_SCS: + SLJIT_ASSERT(PRIVATE_DATA(cc) != 0); + if (recurse_check_bit(common, PRIVATE_DATA(cc))) + length += 2; + cc += 1 + LINK_SIZE; + break; + case OP_CBRA: case OP_SCBRA: offset = GET2(cc, 1 + LINK_SIZE); @@ -2623,7 +2719,8 @@ while (cc < ccend) case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); + case OP_ECLASS: + size = (*cc >= OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); #else size = 1 + 32 / (int)sizeof(PCRE2_UCHAR); #endif @@ -2865,6 +2962,14 @@ while (cc < ccend) cc += 1 + LINK_SIZE; break; + case OP_ASSERT_SCS: + private_srcw[0] = PRIVATE_DATA(cc); + private_srcw[1] = private_srcw[0] + sizeof(sljit_sw); + if (recurse_check_bit(common, private_srcw[0])) + private_count = 2; + cc += 1 + LINK_SIZE; + break; + case OP_CBRA: case OP_SCBRA: offset = GET2(cc, 1 + LINK_SIZE); @@ -3005,7 +3110,8 @@ while (cc < ccend) case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - i = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); + case OP_ECLASS: + i = (*cc >= OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); #else i = 1 + 32 / (int)sizeof(PCRE2_UCHAR); #endif @@ -3140,50 +3246,66 @@ static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_S PCRE2_SPTR end = bracketend(cc); BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; -/* Assert captures then. */ -if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) +/* Assert captures *THEN verb even if it has no alternatives. */ +if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) current_offset = NULL; -/* Conditional block does not. */ -if (*cc == OP_COND || *cc == OP_SCOND) +else if (*cc >= OP_ASSERT_NA && *cc <= OP_ASSERT_SCS) + has_alternatives = TRUE; +/* Conditional block does never capture. */ +else if (*cc == OP_COND || *cc == OP_SCOND) has_alternatives = FALSE; cc = next_opcode(common, cc); if (has_alternatives) { - if (*cc == OP_REVERSE) - cc += 1 + IMM2_SIZE; - else if (*cc == OP_VREVERSE) - cc += 1 + 2 * IMM2_SIZE; + switch (*cc) + { + case OP_REVERSE: + case OP_CREF: + cc += 1 + IMM2_SIZE; + break; + case OP_VREVERSE: + case OP_DNCREF: + cc += 1 + 2 * IMM2_SIZE; + break; + } current_offset = common->then_offsets + (cc - common->start); } while (cc < end) { - if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) - cc = set_then_offsets(common, cc, current_offset); - else + if (*cc >= OP_ASSERT && *cc <= OP_SCOND) { - if (*cc == OP_ALT && has_alternatives) - { - cc += 1 + LINK_SIZE; + cc = set_then_offsets(common, cc, current_offset); + continue; + } - if (*cc == OP_REVERSE) - cc += 1 + IMM2_SIZE; - else if (*cc == OP_VREVERSE) - cc += 1 + 2 * IMM2_SIZE; + if (*cc == OP_ALT && has_alternatives) + { + cc += 1 + LINK_SIZE; - current_offset = common->then_offsets + (cc - common->start); - continue; - } + if (*cc == OP_REVERSE) + cc += 1 + IMM2_SIZE; + else if (*cc == OP_VREVERSE) + cc += 1 + 2 * IMM2_SIZE; - if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) - *current_offset = 1; - cc = next_opcode(common, cc); + current_offset = common->then_offsets + (cc - common->start); + continue; } + + if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) + *current_offset = 1; + cc = next_opcode(common, cc); } +cc = end - 1 - LINK_SIZE; + +/* Ignore repeats. */ +if (*cc == OP_KET && PRIVATE_DATA(cc) != 0) + end += PRIVATE_DATA(cc + 1); + return end; } @@ -3269,8 +3391,12 @@ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * SSIZE_OF(sw)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); +#if defined SLJIT_DEBUG && SLJIT_DEBUG +SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); +/* These two are also used by the stackalloc calls. */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, TMP1, 0); +#endif #endif add_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0)); } @@ -5589,11 +5715,38 @@ if (last) chars->last_count++; } -static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars, int max_chars, sljit_u32 *rec_count) +/* Value can be increased if needed. Patterns +such as /(a|){33}b/ can exhaust the stack. + +Note: /(a|){29}b/ already stops scan_prefix() +because it reaches the maximum step_count. */ +#define SCAN_PREFIX_STACK_END 32 + +/* +Scan prefix stores the prefix string in the chars array. +The elements of the chars array is either small character +sets or "any" (count is set to 255). + +Examples (the chars array is represented by a simple regex): + +/(abc|xbyd)/ prefix: /[ax]b[cy]/ (length: 3) +/a[a-z]b+c/ prefix: a.b (length: 3) +/ab?cd/ prefix: a[bc][cd] (length: 3) +/(ab|cd)|(ef|gh)/ prefix: [aceg][bdfh] (length: 2) + +The length is returned by scan_prefix(). The length is +less than or equal than the minimum length of the pattern. +*/ + +static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars) { -/* Recursive function, which scans prefix literals. */ +fast_forward_char_data *chars_start = chars; +fast_forward_char_data *chars_end = chars + MAX_N_CHARS; +PCRE2_SPTR cc_stack[SCAN_PREFIX_STACK_END]; +fast_forward_char_data *chars_stack[SCAN_PREFIX_STACK_END]; +sljit_u8 next_alternative_stack[SCAN_PREFIX_STACK_END]; BOOL last, any, class, caseless; -int len, repeat, len_save, consumed = 0; +int stack_ptr, step_count, repeat, len, len_save; sljit_u32 chr; /* Any unicode character. */ sljit_u8 *bytes, *bytes_end, byte; PCRE2_SPTR alternative, cc_save, oc; @@ -5606,11 +5759,44 @@ PCRE2_UCHAR othercase[1]; #endif repeat = 1; +stack_ptr = 0; +step_count = 10000; while (TRUE) { - if (*rec_count == 0) + if (--step_count == 0) return 0; - (*rec_count)--; + + SLJIT_ASSERT(chars <= chars_start + MAX_N_CHARS); + + if (chars >= chars_end) + { + if (stack_ptr == 0) + return (int)(chars_end - chars_start); + + --stack_ptr; + cc = cc_stack[stack_ptr]; + chars = chars_stack[stack_ptr]; + + if (chars >= chars_end) + continue; + + if (next_alternative_stack[stack_ptr] != 0) + { + /* When an alternative is processed, the + next alternative is pushed onto the stack. */ + SLJIT_ASSERT(*cc == OP_ALT); + alternative = cc + GET(cc, 1); + if (*alternative == OP_ALT) + { + SLJIT_ASSERT(stack_ptr < SCAN_PREFIX_STACK_END); + SLJIT_ASSERT(chars_stack[stack_ptr] == chars); + SLJIT_ASSERT(next_alternative_stack[stack_ptr] == 1); + cc_stack[stack_ptr] = alternative; + stack_ptr++; + } + cc += 1 + LINK_SIZE; + } + } last = TRUE; any = FALSE; @@ -5650,6 +5836,7 @@ while (TRUE) case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: cc = bracketend(cc); continue; @@ -5686,9 +5873,17 @@ while (TRUE) #ifdef SUPPORT_UNICODE if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); #endif - max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count); - if (max_chars == 0) - return consumed; + if (stack_ptr >= SCAN_PREFIX_STACK_END) + { + chars_end = chars; + continue; + } + + cc_stack[stack_ptr] = cc + len; + chars_stack[stack_ptr] = chars; + next_alternative_stack[stack_ptr] = 0; + stack_ptr++; + last = FALSE; break; @@ -5706,12 +5901,18 @@ while (TRUE) case OP_CBRA: case OP_CBRAPOS: alternative = cc + GET(cc, 1); - while (*alternative == OP_ALT) + if (*alternative == OP_ALT) { - max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count); - if (max_chars == 0) - return consumed; - alternative += GET(alternative, 1); + if (stack_ptr >= SCAN_PREFIX_STACK_END) + { + chars_end = chars; + continue; + } + + cc_stack[stack_ptr] = alternative; + chars_stack[stack_ptr] = chars; + next_alternative_stack[stack_ptr] = 1; + stack_ptr++; } if (*cc == OP_CBRA || *cc == OP_CBRAPOS) @@ -5722,22 +5923,34 @@ while (TRUE) case OP_CLASS: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE)) - return consumed; + { + chars_end = chars; + continue; + } #endif class = TRUE; break; case OP_NCLASS: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; + if (common->utf) + { + chars_end = chars; + continue; + } #endif class = TRUE; break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: + case OP_ECLASS: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; + if (common->utf) + { + chars_end = chars; + continue; + } #endif any = TRUE; cc += GET(cc, 1); @@ -5747,7 +5960,10 @@ while (TRUE) case OP_DIGIT: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) - return consumed; + { + chars_end = chars; + continue; + } #endif any = TRUE; cc++; @@ -5756,7 +5972,10 @@ while (TRUE) case OP_WHITESPACE: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE)) - return consumed; + { + chars_end = chars; + continue; + } #endif any = TRUE; cc++; @@ -5765,7 +5984,10 @@ while (TRUE) case OP_WORDCHAR: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE)) - return consumed; + { + chars_end = chars; + continue; + } #endif any = TRUE; cc++; @@ -5781,7 +6003,11 @@ while (TRUE) case OP_ANY: case OP_ALLANY: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; + if (common->utf) + { + chars_end = chars; + continue; + } #endif any = TRUE; cc++; @@ -5791,7 +6017,11 @@ while (TRUE) case OP_NOTPROP: case OP_PROP: #if PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; + if (common->utf) + { + chars_end = chars; + continue; + } #endif any = TRUE; cc += 1 + 2; @@ -5806,7 +6036,11 @@ while (TRUE) case OP_NOTEXACT: case OP_NOTEXACTI: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) return consumed; + if (common->utf) + { + chars_end = chars; + continue; + } #endif any = TRUE; repeat = GET2(cc, 1); @@ -5814,21 +6048,20 @@ while (TRUE) break; default: - return consumed; + chars_end = chars; + continue; } + SLJIT_ASSERT(chars < chars_end); + if (any) { do { chars->count = 255; - - consumed++; - if (--max_chars == 0) - return consumed; chars++; } - while (--repeat > 0); + while (--repeat > 0 && chars < chars_end); repeat = 1; continue; @@ -5839,17 +6072,27 @@ while (TRUE) bytes = (sljit_u8*) (cc + 1); cc += 1 + 32 / sizeof(PCRE2_UCHAR); + SLJIT_ASSERT(last == TRUE && repeat == 1); switch (*cc) { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPOSSTAR: case OP_CRQUERY: case OP_CRMINQUERY: case OP_CRPOSQUERY: - max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count); - if (max_chars == 0) - return consumed; + last = FALSE; + /* Fall through */ + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPOSSTAR: + if (stack_ptr >= SCAN_PREFIX_STACK_END) + { + chars_end = chars; + continue; + } + + cc_stack[stack_ptr] = ++cc; + chars_stack[stack_ptr] = chars; + next_alternative_stack[stack_ptr] = 0; + stack_ptr++; break; default: @@ -5863,7 +6106,13 @@ while (TRUE) case OP_CRPOSRANGE: repeat = GET2(cc, 1); if (repeat <= 0) - return consumed; + { + chars_end = chars; + continue; + } + + last = (repeat != (int)GET2(cc, 1 + IMM2_SIZE)); + cc += 1 + 2 * IMM2_SIZE; break; } @@ -5898,36 +6147,13 @@ while (TRUE) bytes = bytes_end - 32; } - consumed++; - if (--max_chars == 0) - return consumed; chars++; } - while (--repeat > 0); - - switch (*cc) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPOSSTAR: - return consumed; - - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSQUERY: - cc++; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE)) - return consumed; - cc += 1 + 2 * IMM2_SIZE; - break; - } + while (--repeat > 0 && chars < chars_end); repeat = 1; + if (last) + chars_end = chars; continue; } @@ -5943,7 +6169,10 @@ while (TRUE) { GETCHAR(chr, cc); if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len) - return consumed; + { + chars_end = chars; + continue; + } } else #endif @@ -5974,7 +6203,6 @@ while (TRUE) do { len--; - consumed++; chr = *cc; add_prefix_char(*cc, chars, len == 0); @@ -5982,15 +6210,13 @@ while (TRUE) if (caseless) add_prefix_char(*oc, chars, len == 0); - if (--max_chars == 0) - return consumed; chars++; cc++; oc++; } - while (len > 0); + while (len > 0 && chars < chars_end); - if (--repeat == 0) + if (--repeat == 0 || chars >= chars_end) break; len = len_save; @@ -5999,7 +6225,7 @@ while (TRUE) repeat = 1; if (last) - return consumed; + chars_end = chars; } } @@ -6169,7 +6395,6 @@ int i, max, from; int range_right = -1, range_len; sljit_u8 *update_table = NULL; BOOL in_range; -sljit_u32 rec_count; for (i = 0; i < MAX_N_CHARS; i++) { @@ -6177,8 +6402,7 @@ for (i = 0; i < MAX_N_CHARS; i++) chars[i].last_count = 0; } -rec_count = 10000; -max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count); +max = scan_prefix(common, common->start, chars); if (max < 1) return FALSE; @@ -6768,8 +6992,7 @@ jump = JUMP(SLJIT_NOT_ZERO /* SIG_LESS */); OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump); -OP2(SLJIT_SUB, TMP2, 0, SLJIT_IMM, 0, TMP2, 0); -OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); +OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, TMP2, 0); if (HAS_VIRTUAL_REGISTERS) { OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw))); @@ -6811,7 +7034,8 @@ struct sljit_jump *jump; SLJIT_UNUSED_ARG(ucp); SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); +SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); /* Get type of the previous char, and put it to TMP3. */ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); @@ -6880,7 +7104,7 @@ JUMPHERE(skipread); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); check_str_end(common, &skipread_list); -peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2); +peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCAL1, &invalid_utf2); /* Testing char type. This is a code duplication. */ #ifdef SUPPORT_UNICODE @@ -6919,7 +7143,7 @@ else } set_jumps(skipread_list, LABEL()); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); OP2(SLJIT_XOR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, TMP3, 0); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); @@ -6928,15 +7152,15 @@ if (common->invalid_utf) { set_jumps(invalid_utf1, LABEL()); - peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, NULL); + peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCAL1, NULL); CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR, valid_utf); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); set_jumps(invalid_utf2, LABEL()); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); } @@ -7317,7 +7541,9 @@ else char2_reg = RETURN_ADDR; } -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); +/* Update ref_update_local_size() when this changes. */ +SLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw)); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); if (char1_reg == STR_END) @@ -7336,7 +7562,7 @@ if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); } else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS) { @@ -7351,7 +7577,7 @@ else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_ JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } else @@ -7366,7 +7592,7 @@ else JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); } if (char1_reg == STR_END) @@ -7404,10 +7630,12 @@ if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS) opt_type = 2; -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); +/* Update ref_update_local_size() when this changes. */ +SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, char1_reg, 0); if (char2_reg == STACK_TOP) { @@ -7461,7 +7689,7 @@ OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); if (opt_type == 2) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -7472,1929 +7700,253 @@ if (char2_reg == STACK_TOP) OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0); } -OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); +OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); } -static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, - compare_context *context, jump_list **backtracks) +#include "pcre2_jit_char_inc.h" + +static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) { DEFINE_COMPILER; -unsigned int othercasebit = 0; -PCRE2_SPTR othercasechar = NULL; -#ifdef SUPPORT_UNICODE -int utflength; -#endif +struct sljit_jump *jump[4]; -if (caseless && char_has_othercase(common, cc)) +switch(type) { - othercasebit = char_get_othercase_bit(common, cc); - SLJIT_ASSERT(othercasebit); - /* Extracting bit difference info. */ -#if PCRE2_CODE_UNIT_WIDTH == 8 - othercasechar = cc + (othercasebit >> 8); - othercasebit &= 0xff; -#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - /* Note that this code only handles characters in the BMP. If there - ever are characters outside the BMP whose othercase differs in only one - bit from itself (there currently are none), this code will need to be - revised for PCRE2_CODE_UNIT_WIDTH == 32. */ - othercasechar = cc + (othercasebit >> 9); - if ((othercasebit & 0x100) != 0) - othercasebit = (othercasebit & 0xff) << 8; + case OP_SOD: + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } else - othercasebit &= 0xff; -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ - } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; -if (context->sourcereg == -1) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - if (context->length >= 4) - OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else if (context->length >= 2) - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else -#endif - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - if (context->length >= 4) - OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else -#endif - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif PCRE2_CODE_UNIT_WIDTH == 32 - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ - context->sourcereg = TMP2; - } - -#ifdef SUPPORT_UNICODE -utflength = 1; -if (common->utf && HAS_EXTRALEN(*cc)) - utflength += GET_EXTRALEN(*cc); - -do - { -#endif - - context->length -= IN_UCHARS(1); -#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) - - /* Unaligned read is supported. */ - if (othercasebit != 0 && othercasechar == cc) - { - context->c.asuchars[context->ucharptr] = *cc | othercasebit; - context->oc.asuchars[context->ucharptr] = othercasebit; - } - else - { - context->c.asuchars[context->ucharptr] = *cc; - context->oc.asuchars[context->ucharptr] = 0; - } - context->ucharptr++; - -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) -#else - if (context->ucharptr >= 2 || context->length == 0) -#endif - { - if (context->length >= 4) - OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); - else if (context->length >= 2) - OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#if PCRE2_CODE_UNIT_WIDTH == 8 - else if (context->length >= 1) - OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; - - switch(context->ucharptr) - { - case 4 / sizeof(PCRE2_UCHAR): - if (context->oc.asint != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); - break; - - case 2 / sizeof(PCRE2_UCHAR): - if (context->oc.asushort != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); - break; - -#if PCRE2_CODE_UNIT_WIDTH == 8 - case 1: - if (context->oc.asbyte != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); - break; -#endif - - default: - SLJIT_UNREACHABLE(); - break; - } - context->ucharptr = 0; - } - -#else - - /* Unaligned read is unsupported or in 32 bit mode. */ - if (context->length >= 1) - OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); - - context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; - - if (othercasebit != 0 && othercasechar == cc) - { - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); - } - else - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); - -#endif - - cc++; -#ifdef SUPPORT_UNICODE - utflength--; - } -while (utflength > 0); -#endif - -return cc; -} - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - -#define SET_CHAR_OFFSET(value) \ - if ((value) != charoffset) \ - { \ - if ((value) < charoffset) \ - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ - else \ - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ - } \ - charoffset = (value); - -static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); - -#ifdef SUPPORT_UNICODE -#define XCLASS_SAVE_CHAR 0x001 -#define XCLASS_CHAR_SAVED 0x002 -#define XCLASS_HAS_TYPE 0x004 -#define XCLASS_HAS_SCRIPT 0x008 -#define XCLASS_HAS_SCRIPT_EXTENSION 0x010 -#define XCLASS_HAS_BOOL 0x020 -#define XCLASS_HAS_BIDICL 0x040 -#define XCLASS_NEEDS_UCD (XCLASS_HAS_TYPE | XCLASS_HAS_SCRIPT | XCLASS_HAS_SCRIPT_EXTENSION | XCLASS_HAS_BOOL | XCLASS_HAS_BIDICL) -#define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080 -#define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100 -#define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0 0x200 -#endif /* SUPPORT_UNICODE */ - -static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) -{ -DEFINE_COMPILER; -jump_list *found = NULL; -jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; -sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX; -struct sljit_jump *jump = NULL; -PCRE2_SPTR ccbegin; -int compares, invertcmp, numberofcmps; -#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) -BOOL utf = common->utf; -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ - -#ifdef SUPPORT_UNICODE -sljit_u32 unicode_status = 0; -sljit_u32 category_list = 0; -sljit_u32 items; -int typereg = TMP1; -const sljit_u32 *other_cases; -#endif /* SUPPORT_UNICODE */ - -/* Scanning the necessary info. */ -cc++; -ccbegin = cc; -compares = 0; - -if (cc[-1] & XCL_MAP) - { - min = 0; - cc += 32 / sizeof(PCRE2_UCHAR); - } - -while (*cc != XCL_END) - { - compares++; - - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - if (c > max) max = c; - if (c < min) min = c; -#ifdef SUPPORT_UNICODE - unicode_status |= XCLASS_SAVE_CHAR; -#endif /* SUPPORT_UNICODE */ - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - if (c < min) min = c; - GETCHARINCTEST(c, cc); - if (c > max) max = c; -#ifdef SUPPORT_UNICODE - unicode_status |= XCLASS_SAVE_CHAR; -#endif /* SUPPORT_UNICODE */ - } -#ifdef SUPPORT_UNICODE - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - cc++; - - if (*cc == PT_CLIST && cc[-1] == XCL_PROP) - { - other_cases = PRIV(ucd_caseless_sets) + cc[1]; - while (*other_cases != NOTACHAR) - { - if (*other_cases > max) max = *other_cases; - if (*other_cases < min) min = *other_cases; - other_cases++; - } - } - else - { - max = READ_CHAR_MAX; - min = 0; - } - - items = 0; - - switch(*cc) - { - case PT_ANY: - /* Any either accepts everything or ignored. */ - if (cc[-1] == XCL_PROP) - items = UCPCAT_ALL; - else - compares--; - break; - - case PT_LAMP: - items = UCPCAT3(ucp_Lu, ucp_Ll, ucp_Lt); - break; - - case PT_GC: - items = UCPCAT_RANGE(PRIV(ucp_typerange)[(int)cc[1] * 2], PRIV(ucp_typerange)[(int)cc[1] * 2 + 1]); - break; - - case PT_PC: - items = UCPCAT(cc[1]); - break; - - case PT_WORD: - items = UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N; - break; - - case PT_ALNUM: - items = UCPCAT_L | UCPCAT_N; - break; - - case PT_SCX: - unicode_status |= XCLASS_HAS_SCRIPT_EXTENSION; - if (cc[-1] == XCL_NOTPROP) - { - unicode_status |= XCLASS_SCRIPT_EXTENSION_NOTPROP; - break; - } - compares++; - /* Fall through */ - - case PT_SC: - unicode_status |= XCLASS_HAS_SCRIPT; - break; - - case PT_SPACE: - case PT_PXSPACE: - case PT_PXGRAPH: - case PT_PXPRINT: - case PT_PXPUNCT: - unicode_status |= XCLASS_SAVE_CHAR | XCLASS_HAS_TYPE; - break; - - case PT_CLIST: - case PT_UCNC: - case PT_PXXDIGIT: - unicode_status |= XCLASS_SAVE_CHAR; - break; - - case PT_BOOL: - unicode_status |= XCLASS_HAS_BOOL; - break; - - case PT_BIDICL: - unicode_status |= XCLASS_HAS_BIDICL; - break; - - default: - SLJIT_UNREACHABLE(); - break; - } - - if (items > 0) - { - if (cc[-1] == XCL_NOTPROP) - items ^= UCPCAT_ALL; - category_list |= items; - unicode_status |= XCLASS_HAS_TYPE; - compares--; - } - - cc += 2; - } -#endif /* SUPPORT_UNICODE */ - } - -#ifdef SUPPORT_UNICODE -if (category_list == UCPCAT_ALL) - { - /* All characters are accepted, same as dotall. */ - compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); - if (list == backtracks) - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - return; - } - -if (compares == 0 && category_list == 0) - { - /* No characters are accepted, same as (*F) or dotall. */ - compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); - if (list != backtracks) - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - return; - } -#else /* !SUPPORT_UNICODE */ -SLJIT_ASSERT(compares > 0); -#endif /* SUPPORT_UNICODE */ - -/* We are not necessary in utf mode even in 8 bit mode. */ -cc = ccbegin; -if ((cc[-1] & XCL_NOT) != 0) - read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); -else - { -#ifdef SUPPORT_UNICODE - read_char(common, min, max, (unicode_status & XCLASS_NEEDS_UCD) ? backtracks : NULL, 0); -#else /* !SUPPORT_UNICODE */ - read_char(common, min, max, NULL, 0); -#endif /* SUPPORT_UNICODE */ - } - -if ((cc[-1] & XCL_HASPROP) == 0) - { - if ((cc[-1] & XCL_MAP) != 0) - { - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - if (!optimize_class(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found)) - { - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); - add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO)); - } - - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump); - - cc += 32 / sizeof(PCRE2_UCHAR); - } - else - { - OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); - add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min)); - } - } -else if ((cc[-1] & XCL_MAP) != 0) - { - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); -#ifdef SUPPORT_UNICODE - unicode_status |= XCLASS_CHAR_SAVED; -#endif /* SUPPORT_UNICODE */ - if (!optimize_class(common, (const sljit_u8 *)cc, FALSE, TRUE, list)) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - jump = NULL; - if (common->utf) -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); - add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); - -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf) -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - JUMPHERE(jump); - } - - OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); - cc += 32 / sizeof(PCRE2_UCHAR); - } - -#ifdef SUPPORT_UNICODE -if (unicode_status & XCLASS_NEEDS_UCD) - { - if ((unicode_status & (XCLASS_SAVE_CHAR | XCLASS_CHAR_SAVED)) == XCLASS_SAVE_CHAR) - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); - -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (!common->utf) - { - jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR); - JUMPHERE(jump); - } -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ - - OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); - OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - - ccbegin = cc; - - if (category_list != 0) - compares++; - - if (unicode_status & XCLASS_HAS_BIDICL) - { - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BIDICLASS_SHIFT); - - while (*cc != XCL_END) - { - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - GETCHARINCTEST(c, cc); - } - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - cc++; - if (*cc == PT_BIDICL) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - if (cc[-1] == XCL_NOTPROP) - invertcmp ^= 0x1; - jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]); - add_jump(compiler, compares > 0 ? list : backtracks, jump); - } - cc += 2; - } - } - - cc = ccbegin; - } - - if (unicode_status & XCLASS_HAS_BOOL) - { - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, bprops)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BPROPS_MASK); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); - - while (*cc != XCL_END) - { - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - GETCHARINCTEST(c, cc); - } - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - cc++; - if (*cc == PT_BOOL) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - if (cc[-1] == XCL_NOTPROP) - invertcmp ^= 0x1; - - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); - add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); - } - cc += 2; - } - } - - cc = ccbegin; - } - - if (unicode_status & XCLASS_HAS_SCRIPT) - { - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - - while (*cc != XCL_END) - { - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - GETCHARINCTEST(c, cc); - } - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - cc++; - switch (*cc) - { - case PT_SCX: - if (cc[-1] == XCL_NOTPROP) - break; - /* Fall through */ - - case PT_SC: - compares--; - invertcmp = (compares == 0 && list != backtracks); - if (cc[-1] == XCL_NOTPROP) - invertcmp ^= 0x1; - - add_jump(compiler, compares > 0 ? list : backtracks, CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1])); - } - cc += 2; - } - } - - cc = ccbegin; - } - - if (unicode_status & XCLASS_HAS_SCRIPT_EXTENSION) - { - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_SCRIPTX_MASK); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); - - if (unicode_status & XCLASS_SCRIPT_EXTENSION_NOTPROP) - { - if (unicode_status & XCLASS_HAS_TYPE) - { - if (unicode_status & XCLASS_SAVE_CHAR) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP2, 0); - unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0; - } - else - { - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0); - unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR; - } - } - OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - } - - while (*cc != XCL_END) - { - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - GETCHARINCTEST(c, cc); - } - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - cc++; - if (*cc == PT_SCX) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - - jump = NULL; - if (cc[-1] == XCL_NOTPROP) - { - jump = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, (int)cc[1]); - if (invertcmp) - { - add_jump(compiler, backtracks, jump); - jump = NULL; - } - invertcmp ^= 0x1; - } - - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); - add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); - - if (jump != NULL) - JUMPHERE(jump); - } - cc += 2; - } - } - - if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); - else if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR) - OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0); - cc = ccbegin; - } - - if (unicode_status & XCLASS_SAVE_CHAR) - OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); - - if (unicode_status & XCLASS_HAS_TYPE) - { - if (unicode_status & XCLASS_SAVE_CHAR) - typereg = RETURN_ADDR; - - OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); - OP2(SLJIT_SHL, typereg, 0, SLJIT_IMM, 1, TMP2, 0); - - if (category_list > 0) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, category_list); - add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); - } - } - } -#endif /* SUPPORT_UNICODE */ - -/* Generating code. */ -charoffset = 0; -numberofcmps = 0; - -while (*cc != XCL_END) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - jump = NULL; - - if (*cc == XCL_SINGLE) - { - cc ++; - GETCHARINCTEST(c, cc); - - if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - numberofcmps++; - } - else if (numberofcmps > 0) - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - numberofcmps = 0; - } - else - { - jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - numberofcmps = 0; - } - } - else if (*cc == XCL_RANGE) - { - cc ++; - GETCHARINCTEST(c, cc); - SET_CHAR_OFFSET(c); - GETCHARINCTEST(c, cc); - - if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) - { - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - numberofcmps++; - } - else if (numberofcmps > 0) - { - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - numberofcmps = 0; - } - else - { - jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); - numberofcmps = 0; - } - } -#ifdef SUPPORT_UNICODE - else - { - SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); - if (*cc == XCL_NOTPROP) - invertcmp ^= 0x1; - cc++; - switch(*cc) - { - case PT_ANY: - case PT_LAMP: - case PT_GC: - case PT_PC: - case PT_SC: - case PT_SCX: - case PT_BOOL: - case PT_BIDICL: - case PT_WORD: - case PT_ALNUM: - compares++; - /* Already handled. */ - break; - - case PT_SPACE: - case PT_PXSPACE: - SET_CHAR_OFFSET(9); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xd - 0x9); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Zl, ucp_Zs)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_CLIST: - other_cases = PRIV(ucd_caseless_sets) + cc[1]; - - /* At least three characters are required. - Otherwise this case would be handled by the normal code path. */ - SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR); - SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); - - /* Optimizing character pairs, if their difference is power of 2. */ - if (is_powerof2(other_cases[1] ^ other_cases[0])) - { - if (charoffset == 0) - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - else - { - OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - } - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[1]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - other_cases += 2; - } - else if (is_powerof2(other_cases[2] ^ other_cases[1])) - { - if (charoffset == 0) - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]); - else - { - OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - } - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[2]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); - OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); - - other_cases += 3; - } - else - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - } - - while (*other_cases != NOTACHAR) - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); - OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); - } - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_UCNC: - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - SET_CHAR_OFFSET(0xa0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - SET_CHAR_OFFSET(0); - OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_PXGRAPH: - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT_RANGE(ucp_Zl, ucp_Zs)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); - jump = JUMP(SLJIT_ZERO); - - c = charoffset; - /* In case of ucp_Cf, we overwrite the result. */ - SET_CHAR_OFFSET(0x2066); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - /* Restore charoffset. */ - SET_CHAR_OFFSET(c); - - JUMPHERE(jump); - jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); - break; - - case PT_PXPRINT: - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT2(ucp_Zl, ucp_Zp)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); - jump = JUMP(SLJIT_ZERO); - - c = charoffset; - /* In case of ucp_Cf, we overwrite the result. */ - SET_CHAR_OFFSET(0x2066); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - /* Restore charoffset. */ - SET_CHAR_OFFSET(c); - - JUMPHERE(jump); - jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); - break; - - case PT_PXPUNCT: - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Sc, ucp_So)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - - SET_CHAR_OFFSET(0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f); - OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Pc, ucp_Ps)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_PXXDIGIT: - SET_CHAR_OFFSET(CHAR_A); - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, ~0x20); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP2, 0, SLJIT_IMM, CHAR_F - CHAR_A); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(CHAR_0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_9 - CHAR_0); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff10); - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff10); - - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff19 - 0xff10); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff21); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff26 - 0xff21); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff41); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff41); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff10); - - JUMPHERE(jump); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - default: - SLJIT_UNREACHABLE(); - break; - } - cc += 2; - } -#endif /* SUPPORT_UNICODE */ - - if (jump != NULL) - add_jump(compiler, compares > 0 ? list : backtracks, jump); - } - -SLJIT_ASSERT(compares == 0); -if (found != NULL) - set_jumps(found, LABEL()); -} - -#undef SET_TYPE_OFFSET -#undef SET_CHAR_OFFSET - -#endif - -static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) -{ -DEFINE_COMPILER; -struct sljit_jump *jump[4]; - -switch(type) - { - case OP_SOD: - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - } - else - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); - return cc; - - case OP_SOM: - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); - } - else - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); - return cc; - - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_NOT_UCP_WORD_BOUNDARY: - case OP_UCP_WORD_BOUNDARY: - add_jump(compiler, (type == OP_NOT_WORD_BOUNDARY || type == OP_WORD_BOUNDARY) ? &common->wordboundary : &common->ucp_wordboundary, JUMP(SLJIT_FAST_CALL)); -#ifdef SUPPORT_UNICODE - if (common->invalid_utf) - { - add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); - return cc; - } -#endif /* SUPPORT_UNICODE */ - sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - - case OP_EODN: - /* Requires rather complex checks. */ - jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - else - { - jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, STR_END, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); - } - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else if (common->nltype == NLTYPE_FIXED) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); - } - else - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, TMP2, 0, STR_END, 0); - jump[2] = JUMP(SLJIT_GREATER); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */); - /* Equal. */ - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - - JUMPHERE(jump[1]); - if (common->nltype == NLTYPE_ANYCRLF) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); - } - else - { - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); - add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); - sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - } - JUMPHERE(jump[2]); - JUMPHERE(jump[3]); - } - JUMPHERE(jump[0]); - if (common->mode != PCRE2_JIT_COMPLETE) - check_partial(common, TRUE); - return cc; - - case OP_EOD: - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - if (common->mode != PCRE2_JIT_COMPLETE) - check_partial(common, TRUE); - return cc; - - case OP_DOLL: - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - } - else - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - - if (!common->endonly) - compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); - else - { - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - check_partial(common, FALSE); - } - return cc; - - case OP_DOLLM: - jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - } - else - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - check_partial(common, FALSE); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); - - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); - else - { - jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); - /* STR_PTR = STR_END - IN_UCHARS(1) */ - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); - } - - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else - { - peek_char(common, common->nlmax, TMP3, 0, NULL); - check_newlinechar(common, common->nltype, backtracks, FALSE); - } - JUMPHERE(jump[0]); - return cc; - - case OP_CIRC: - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - } - else - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - } - return cc; - - case OP_CIRCM: - /* TMP2 might be used by peek_char_back. */ - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - } - else - { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - } - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); - - if (!common->alt_circumflex) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 0)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else - { - peek_char_back(common, common->nlmax, backtracks); - check_newlinechar(common, common->nltype, backtracks, FALSE); - } - JUMPHERE(jump[0]); - return cc; - } -SLJIT_UNREACHABLE(); -return cc; -} - -#ifdef SUPPORT_UNICODE - -#if PCRE2_CODE_UNIT_WIDTH != 32 - -/* The code in this function copies the logic of the interpreter function that -is defined in the pcre2_extuni.c source. If that code is updated, this -function, and those below it, must be kept in step (note by PH, June 2024). */ - -static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc) -{ -PCRE2_SPTR start_subject = args->begin; -PCRE2_SPTR end_subject = args->end; -int lgb, rgb, ricount; -PCRE2_SPTR prevcc, endcc, bptr; -BOOL first = TRUE; -BOOL was_ep_ZWJ = FALSE; -uint32_t c; - -prevcc = cc; -endcc = NULL; -do - { - GETCHARINC(c, cc); - rgb = UCD_GRAPHBREAK(c); - - if (first) - { - lgb = rgb; - endcc = cc; - first = FALSE; - continue; - } - - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) - break; - - /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was - preceded by Extended Pictographic. */ - - if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) - break; - - /* Not breaking between Regional Indicators is allowed only if there - are an even number of preceding RIs. */ - - if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) - { - ricount = 0; - bptr = prevcc; - - /* bptr is pointing to the left-hand character */ - while (bptr > start_subject) - { - bptr--; - BACKCHAR(bptr); - GETCHAR(c, bptr); - - if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) - break; - - ricount++; - } - - if ((ricount & 1) != 0) break; /* Grapheme break required */ - } - - /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in - between; see next statement). */ - - was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); - - /* If Extend follows Extended_Pictographic, do not update lgb; this allows - any number of them before a following ZWJ. */ - - if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) - lgb = rgb; - - prevcc = endcc; - endcc = cc; - } -while (cc < end_subject); - -return endcc; -} - -#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ - -/* The code in this function copies the logic of the interpreter function that -is defined in the pcre2_extuni.c source. If that code is updated, this -function, and the one below it, must be kept in step (note by PH, June 2024). */ - -static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc) -{ -PCRE2_SPTR start_subject = args->begin; -PCRE2_SPTR end_subject = args->end; -int lgb, rgb, ricount; -PCRE2_SPTR prevcc, endcc, bptr; -BOOL first = TRUE; -BOOL was_ep_ZWJ = FALSE; -uint32_t c; - -prevcc = cc; -endcc = NULL; -do - { - GETCHARINC_INVALID(c, cc, end_subject, break); - rgb = UCD_GRAPHBREAK(c); - - if (first) - { - lgb = rgb; - endcc = cc; - first = FALSE; - continue; - } - - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) - break; - - /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was - preceded by Extended Pictographic. */ - - if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) - break; - - /* Not breaking between Regional Indicators is allowed only if there - are an even number of preceding RIs. */ - - if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) - { - ricount = 0; - bptr = prevcc; - - /* bptr is pointing to the left-hand character */ - while (bptr > start_subject) - { - GETCHARBACK_INVALID(c, bptr, start_subject, break); - - if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) - break; - - ricount++; - } - - if ((ricount & 1) != 0) - break; /* Grapheme break required */ - } - - /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in - between; see next statement). */ - - was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); - - /* If Extend follows Extended_Pictographic, do not update lgb; this allows - any number of them before a following ZWJ. */ - - if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) - lgb = rgb; - - prevcc = endcc; - endcc = cc; - } -while (cc < end_subject); - -return endcc; -} - -/* The code in this function copies the logic of the interpreter function that -is defined in the pcre2_extuni.c source. If that code is updated, this -function must be kept in step (note by PH, June 2024). */ - -static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc) -{ -PCRE2_SPTR start_subject = args->begin; -PCRE2_SPTR end_subject = args->end; -int lgb, rgb, ricount; -PCRE2_SPTR bptr; -uint32_t c; -BOOL was_ep_ZWJ = FALSE; - -/* Patch by PH */ -/* GETCHARINC(c, cc); */ -c = *cc++; - -#if PCRE2_CODE_UNIT_WIDTH == 32 -if (c >= 0x110000) - return cc; -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ -lgb = UCD_GRAPHBREAK(c); - -while (cc < end_subject) - { - c = *cc; -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x110000) - break; -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ - rgb = UCD_GRAPHBREAK(c); - - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) - break; - - /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was - preceded by Extended Pictographic. */ - - if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) - break; - - /* Not breaking between Regional Indicators is allowed only if there - are an even number of preceding RIs. */ - - if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) - { - ricount = 0; - bptr = cc - 1; - - /* bptr is pointing to the left-hand character */ - while (bptr > start_subject) - { - bptr--; - c = *bptr; -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x110000) - break; -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ - - if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; - - ricount++; - } - - if ((ricount & 1) != 0) - break; /* Grapheme break required */ - } - - /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in - between; see next statement). */ - - was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); - - /* If Extend follows Extended_Pictographic, do not update lgb; this allows - any number of them before a following ZWJ. */ - - if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) - lgb = rgb; - - cc++; - } - -return cc; -} - -#endif /* SUPPORT_UNICODE */ - -static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr) -{ -DEFINE_COMPILER; -int length; -unsigned int c, oc, bit; -compare_context context; -struct sljit_jump *jump[3]; -jump_list *end_list; -#ifdef SUPPORT_UNICODE -PCRE2_UCHAR propdata[5]; -#endif /* SUPPORT_UNICODE */ - -switch(type) - { - case OP_NOT_DIGIT: - case OP_DIGIT: - /* Digits are usually 0-9, so it is worth to optimize them. */ - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE)) - read_char7_type(common, backtracks, type == OP_NOT_DIGIT); - else -#endif - read_char8_type(common, backtracks, type == OP_NOT_DIGIT); - /* Flip the starting bit in the negative case. */ - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_digit); - add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE)) - read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE); - else -#endif - read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_space); - add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE)) - read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR); - else -#endif - read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_word); - add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_ANY: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) + case OP_SOM: + if (HAS_VIRTUAL_REGISTERS) { - jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - end_list = NULL; - if (common->mode != PCRE2_JIT_PARTIAL_HARD) - add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - else - check_str_end(common, &end_list); - - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); - set_jumps(end_list, LABEL()); - JUMPHERE(jump[0]); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); } else - check_newlinechar(common, common->nltype, backtracks, TRUE); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); return cc; - case OP_ALLANY: - if (check_str_ptr) - detect_partial_match(common, backtracks); + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + add_jump(compiler, (type == OP_NOT_WORD_BOUNDARY || type == OP_WORD_BOUNDARY) ? &common->wordboundary : &common->ucp_wordboundary, JUMP(SLJIT_FAST_CALL)); #ifdef SUPPORT_UNICODE - if (common->utf && common->invalid_utf) + if (common->invalid_utf) { - read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); + add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); return cc; } #endif /* SUPPORT_UNICODE */ - - skip_valid_char(common); - return cc; - - case OP_ANYBYTE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - return cc; - -#ifdef SUPPORT_UNICODE - case OP_NOTPROP: - case OP_PROP: - propdata[0] = XCL_HASPROP; - propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; - propdata[2] = cc[0]; - propdata[3] = cc[1]; - propdata[4] = XCL_END; - if (check_str_ptr) - detect_partial_match(common, backtracks); - compile_xclass_matchingpath(common, propdata, backtracks); - return cc + 2; -#endif - - case OP_ANYNL: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0); - jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - /* We don't need to handle soft partial matching case. */ - end_list = NULL; - if (common->mode != PCRE2_JIT_PARTIAL_HARD) - add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - else - check_str_end(common, &end_list); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - jump[2] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[0]); - check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); - set_jumps(end_list, LABEL()); - JUMPHERE(jump[1]); - JUMPHERE(jump[2]); - return cc; - - case OP_NOT_HSPACE: - case OP_HSPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - if (type == OP_NOT_HSPACE) - read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - read_char(common, 0x9, 0x3000, NULL, 0); - - add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + add_jump(compiler, backtracks, JUMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_ZERO : SLJIT_ZERO)); return cc; - case OP_NOT_VSPACE: - case OP_VSPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - if (type == OP_NOT_VSPACE) - read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR); + case OP_EODN: + /* Requires rather complex checks. */ + jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, STR_END, 0); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else if (common->nltype == NLTYPE_FIXED) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } else - read_char(common, 0xa, 0x2029, NULL, 0); + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, TMP2, 0, STR_END, 0); + jump[2] = JUMP(SLJIT_GREATER); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */); + /* Equal. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); - sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + JUMPHERE(jump[1]); + if (common->nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + sljit_set_current_flags(compiler, SLJIT_SET_Z); + add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + } + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + } + JUMPHERE(jump[0]); + if (common->mode != PCRE2_JIT_COMPLETE) + check_partial(common, TRUE); return cc; -#ifdef SUPPORT_UNICODE - case OP_EXTUNI: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); - OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); - -#if PCRE2_CODE_UNIT_WIDTH != 32 - sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, - common->utf ? (common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_utf)) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); - if (common->invalid_utf) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); -#else - sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, - common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); - if (common->invalid_utf) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); -#endif - - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); - - if (common->mode == PCRE2_JIT_PARTIAL_HARD) - { - jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0); - /* Since we successfully read a char above, partial matching must occure. */ + case OP_EOD: + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + if (common->mode != PCRE2_JIT_COMPLETE) check_partial(common, TRUE); - JUMPHERE(jump[0]); - } return cc; -#endif - - case OP_CHAR: - case OP_CHARI: - length = 1; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); -#endif - - if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE) - detect_partial_match(common, backtracks); - if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) + case OP_DOLL: + if (HAS_VIRTUAL_REGISTERS) { - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); - - context.length = IN_UCHARS(length); - context.sourcereg = -1; -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - context.ucharptr = 0; -#endif - return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); } + else + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); -#ifdef SUPPORT_UNICODE - if (common->utf) + if (!common->endonly) + compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); + else { - GETCHAR(c, cc); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); } - else -#endif - c = *cc; - - SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc)); - - if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - - oc = char_othercase(common, c); - read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0); - - SLJIT_ASSERT(!is_powerof2(c ^ oc)); + return cc; - if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) + case OP_DOLLM: + jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + if (HAS_VIRTUAL_REGISTERS) { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc); - SELECT(SLJIT_EQUAL, TMP1, SLJIT_IMM, c, TMP1); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); } else - { - jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); - JUMPHERE(jump[0]); - } - return cc + length; - - case OP_NOT: - case OP_NOTI: - if (check_str_ptr) - detect_partial_match(common, backtracks); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + check_partial(common, FALSE); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); - length = 1; -#ifdef SUPPORT_UNICODE - if (common->utf) + if (common->nltype == NLTYPE_FIXED && common->newline > 255) { -#if PCRE2_CODE_UNIT_WIDTH == 8 - c = *cc; - if (c < 128 && !common->invalid_utf) - { - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - if (type == OP_NOT || !char_has_othercase(common, cc)) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - else - { - /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); - } - /* Skip the variable-length character. */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(jump[0]); - return cc + 1; - } + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); else -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ { - GETCHARLEN(c, cc, length); + jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); + /* STR_PTR = STR_END - IN_UCHARS(1) */ + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); } + + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); } else -#endif /* SUPPORT_UNICODE */ - c = *cc; + { + peek_char(common, common->nlmax, TMP3, 0, NULL); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; - if (type == OP_NOT || !char_has_othercase(common, cc)) + case OP_CIRC: + if (HAS_VIRTUAL_REGISTERS) { - read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); } else { - oc = char_othercase(common, c); - read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR); - bit = c ^ oc; - if (is_powerof2(bit)) - { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); - } - else - { - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); - } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); } - return cc + length; - - case OP_CLASS: - case OP_NCLASS: - if (check_str_ptr) - detect_partial_match(common, backtracks); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255; - if (type == OP_NCLASS) - read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - read_char(common, 0, bit, NULL, 0); -#else - if (type == OP_NCLASS) - read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - read_char(common, 0, 255, NULL, 0); -#endif - - if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks)) - return cc + 32 / sizeof(PCRE2_UCHAR); + return cc; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - jump[0] = NULL; - if (common->utf) + case OP_CIRCM: + /* TMP2 might be used by peek_char_back. */ + if (HAS_VIRTUAL_REGISTERS) { - jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit); - if (type == OP_CLASS) - { - add_jump(compiler, backtracks, jump[0]); - jump[0] = NULL; - } + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); } -#elif PCRE2_CODE_UNIT_WIDTH != 8 - jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - if (type == OP_CLASS) + else { - add_jump(compiler, backtracks, jump[0]); - jump[0] = NULL; + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ - - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); - add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - if (jump[0] != NULL) - JUMPHERE(jump[0]); -#endif - return cc + 32 / sizeof(PCRE2_UCHAR); - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - case OP_XCLASS: - if (check_str_ptr) - detect_partial_match(common, backtracks); - compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); - return cc + GET(cc, 0) - 1; -#endif - } -SLJIT_UNREACHABLE(); -return cc; -} - -static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks) -{ -/* This function consumes at least one input character. */ -/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ -DEFINE_COMPILER; -PCRE2_SPTR ccbegin = cc; -compare_context context; -int size; + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); -context.length = 0; -do - { - if (cc >= ccend) - break; + if (!common->alt_circumflex) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - if (*cc == OP_CHAR) + if (common->nltype == NLTYPE_FIXED && common->newline > 255) { - size = 1; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[1])) - size += GET_EXTRALEN(cc[1]); -#endif + OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 0)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); } - else if (*cc == OP_CHARI) + else { - size = 1; -#ifdef SUPPORT_UNICODE - if (common->utf) - { - if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) - size = 0; - else if (HAS_EXTRALEN(cc[1])) - size += GET_EXTRALEN(cc[1]); - } - else -#endif - if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) - size = 0; + peek_char_back(common, common->nlmax, backtracks); + check_newlinechar(common, common->nltype, backtracks, FALSE); } - else - size = 0; - - cc += 1 + size; - context.length += IN_UCHARS(size); - } -while (size > 0 && context.length <= 128); - -cc = ccbegin; -if (context.length > 0) - { - /* We have a fixed-length byte sequence. */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); - - context.sourcereg = -1; -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - context.ucharptr = 0; -#endif - do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); + JUMPHERE(jump[0]); return cc; } - -/* A non-fixed length character will be checked if length == 0. */ -return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); +SLJIT_UNREACHABLE(); +return cc; } /* Forward definitions. */ @@ -9470,10 +8022,16 @@ struct sljit_jump *nopartial; #if defined SUPPORT_UNICODE struct sljit_label *loop; struct sljit_label *caseless_loop; +struct sljit_jump *turkish_ascii_i = NULL; +struct sljit_jump *turkish_non_ascii_i = NULL; jump_list *no_match = NULL; int source_reg = COUNT_MATCH; int source_end_reg = ARGUMENTS; int char1_reg = STACK_LIMIT; +PCRE2_UCHAR refi_flag = 0; + +if (*cc == OP_REFI || *cc == OP_DNREFI) + refi_flag = cc[PRIV(OP_lengths)[*cc] - 1]; #endif /* SUPPORT_UNICODE */ if (ref) @@ -9488,9 +8046,10 @@ else OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); #if defined SUPPORT_UNICODE -if (common->utf && *cc == OP_REFI) +if ((common->utf || common->ucp) && (*cc == OP_REFI || *cc == OP_DNREFI)) { - SLJIT_ASSERT(common->iref_ptr != 0); + /* Update ref_update_local_size() when this changes. */ + SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw)); if (ref) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); @@ -9500,9 +8059,9 @@ if (common->utf && *cc == OP_REFI) if (withchecks && emptyfail) add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr, source_reg, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw), source_end_reg, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2, char1_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, source_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, source_end_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, char1_reg, 0); OP1(SLJIT_MOV, source_reg, 0, TMP1, 0); OP1(SLJIT_MOV, source_end_reg, 0, TMP2, 0); @@ -9526,6 +8085,16 @@ if (common->utf && *cc == OP_REFI) CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); + if ((refi_flag & (REFI_FLAG_TURKISH_CASING|REFI_FLAG_CASELESS_RESTRICT)) == + REFI_FLAG_TURKISH_CASING) + { + OP2(SLJIT_OR, SLJIT_TMP_DEST_REG, 0, char1_reg, 0, SLJIT_IMM, 0x20); + turkish_ascii_i = CMP(SLJIT_EQUAL, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 0x69); + + OP2(SLJIT_OR, SLJIT_TMP_DEST_REG, 0, char1_reg, 0, SLJIT_IMM, 0x1); + turkish_non_ascii_i = CMP(SLJIT_EQUAL, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 0x131); + } + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); @@ -9545,6 +8114,9 @@ if (common->utf && *cc == OP_REFI) OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_caseless_sets)); + if (refi_flag & REFI_FLAG_CASELESS_RESTRICT) + add_jump(compiler, &no_match, CMP(SLJIT_LESS | SLJIT_32, SLJIT_MEM1(TMP2), 0, SLJIT_IMM, 128)); + caseless_loop = LABEL(); OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP2), 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(uint32_t)); @@ -9552,30 +8124,52 @@ if (common->utf && *cc == OP_REFI) JUMPTO(SLJIT_EQUAL, loop); JUMPTO(SLJIT_LESS, caseless_loop); + if ((refi_flag & (REFI_FLAG_TURKISH_CASING|REFI_FLAG_CASELESS_RESTRICT)) == + REFI_FLAG_TURKISH_CASING) + { + add_jump(compiler, &no_match, JUMP(SLJIT_JUMP)); + JUMPHERE(turkish_ascii_i); + + OP2(SLJIT_LSHR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 5); + OP2(SLJIT_AND, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); + OP2(SLJIT_XOR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 0x130); + CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); + + add_jump(compiler, &no_match, JUMP(SLJIT_JUMP)); + JUMPHERE(turkish_non_ascii_i); + + OP2(SLJIT_AND, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); + OP2(SLJIT_XOR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); + OP2(SLJIT_SHL, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 5); + OP2(SLJIT_ADD, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 0x49); + CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); + } + set_jumps(no_match, LABEL()); if (common->mode == PCRE2_JIT_COMPLETE) JUMPHERE(partial); - OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); - OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); if (common->mode != PCRE2_JIT_COMPLETE) { JUMPHERE(partial); - OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); - OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); check_partial(common, FALSE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); } JUMPHERE(jump); - OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); - OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); return; } else @@ -9594,7 +8188,7 @@ else if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, backtracks, partial); - add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, (*cc == OP_REF || *cc == OP_DNREF) ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); if (common->mode != PCRE2_JIT_COMPLETE) @@ -9606,7 +8200,7 @@ else OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); - add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, (*cc == OP_REF || *cc == OP_DNREF) ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); JUMPHERE(partial); check_partial(common, FALSE); @@ -9630,6 +8224,7 @@ DEFINE_COMPILER; BOOL ref = (*cc == OP_REF || *cc == OP_REFI); backtrack_common *backtrack; PCRE2_UCHAR type; +int local_start = LOCAL2; int offset = 0; struct sljit_label *label; struct sljit_jump *zerolength; @@ -9644,9 +8239,21 @@ if (ref) offset = GET2(cc, 1) << 1; else cc += IMM2_SIZE; + +if (*ccbegin == OP_REFI || *ccbegin == OP_DNREFI) + { + cc += 1; +#ifdef SUPPORT_UNICODE + if (common->utf || common->ucp) + local_start = LOCAL3; +#endif + } + type = cc[1 + IMM2_SIZE]; SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even); +/* Update ref_update_local_size() when this changes. */ +SLJIT_ASSERT(local_start + 2 * SSIZE_OF(sw) <= (int)LOCAL0 + common->locals_size); minimize = (type & 0x1) != 0; switch(type) { @@ -9698,7 +8305,7 @@ if (!minimize) { compile_dnref_search(common, ccbegin, NULL); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw), TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); } /* Restore if not zero length. */ @@ -9721,24 +8328,24 @@ if (!minimize) { compile_dnref_search(common, ccbegin, &backtrack->own_backtracks); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw), TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); } } if (min > 1 || max > 1) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start, SLJIT_IMM, 0); label = LABEL(); if (!ref) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw)); compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, FALSE, FALSE); if (min > 1 || max > 1) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), local_start); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start, TMP1, 0); if (min > 1) CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label); if (max > 1) @@ -10006,12 +8613,13 @@ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_pt SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); /* Needed to save important temporary registers. */ -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); +SLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0); /* SLJIT_R0 = arguments */ OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0); GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START); sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS3(32, W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_callout_jit)); -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); free_stack(common, callout_arg_size); /* Check return value. */ @@ -10179,6 +8787,7 @@ jump_list **found; /* Saving previous accept variables. */ BOOL save_local_quit_available = common->local_quit_available; BOOL save_in_positive_assertion = common->in_positive_assertion; +sljit_s32 save_restore_end_ptr = common->restore_end_ptr; then_trap_backtrack *save_then_trap = common->then_trap; struct sljit_label *save_quit_label = common->quit_label; struct sljit_label *save_accept_label = common->accept_label; @@ -10286,6 +8895,7 @@ if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)) { /* Control verbs cannot escape from these asserts. */ local_quit_available = TRUE; + common->restore_end_ptr = 0; common->local_quit_available = TRUE; common->quit_label = NULL; common->quit = NULL; @@ -10321,6 +8931,7 @@ while (1) common->quit = save_quit; } common->in_positive_assertion = save_in_positive_assertion; + common->restore_end_ptr = save_restore_end_ptr; common->then_trap = save_then_trap; common->accept_label = save_accept_label; common->positive_assertion_quit = save_positive_assertion_quit; @@ -10418,6 +9029,7 @@ while (1) common->quit = save_quit; } common->in_positive_assertion = save_in_positive_assertion; + common->restore_end_ptr = save_restore_end_ptr; common->then_trap = save_then_trap; common->accept_label = save_accept_label; common->positive_assertion_quit = save_positive_assertion_quit; @@ -10557,7 +9169,8 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { JUMPTO(SLJIT_JUMP, backtrack->matchingpath); JUMPHERE(brajump); - if (framesize >= 0) + SLJIT_ASSERT(framesize != 0); + if (framesize > 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -10622,7 +9235,9 @@ if (local_quit_available) common->quit_label = save_quit_label; common->quit = save_quit; } + common->in_positive_assertion = save_in_positive_assertion; +common->restore_end_ptr = save_restore_end_ptr; common->then_trap = save_then_trap; common->accept_label = save_accept_label; common->positive_assertion_quit = save_positive_assertion_quit; @@ -10813,6 +9428,7 @@ BOOL needs_control_head = FALSE; BOOL has_vreverse = FALSE; struct sljit_jump *jump; struct sljit_jump *skip; +jump_list *jumplist; struct sljit_label *rmax_label = NULL; struct sljit_jump *braminzero = NULL; @@ -10875,7 +9491,8 @@ if (opcode == OP_CBRA || opcode == OP_SCBRA) BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; matchingpath += IMM2_SIZE; } -else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) +else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE + || opcode == OP_ASSERT_SCS || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { /* Other brackets simply allocate the next entry. */ private_data_ptr = PRIVATE_DATA(ccbegin); @@ -11086,6 +9703,88 @@ else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SC if (*matchingpath == OP_REVERSE) matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack); } +else if (opcode == OP_ASSERT_SCS) + { + /* Nested scs blocks will not update this variable. */ + if (common->restore_end_ptr == 0) + common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw); + + if (*matchingpath == OP_CREF && (matchingpath[1 + IMM2_SIZE] != OP_CREF && matchingpath[1 + IMM2_SIZE] != OP_DNCREF)) + { + /* Optimized case for a single capture reference. */ + i = OVECTOR(GET2(matchingpath, 1) << 1); + + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), i); + + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + matchingpath += 1 + IMM2_SIZE; + + allocate_stack(common, has_alternatives ? 3 : 2); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), i + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); + jumplist = NULL; + + while (TRUE) + { + if (*matchingpath == OP_CREF) + { + sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(matchingpath, 1) << 1)); + matchingpath += 1 + IMM2_SIZE; + } + else + { + SLJIT_ASSERT(*matchingpath == OP_DNCREF); + + i = GET2(matchingpath, 1 + IMM2_SIZE); + slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; + + while (i-- > 1) + { + sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(slot, 0) << 1)); + add_jump(compiler, &jumplist, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0)); + slot += common->name_entry_size; + } + + sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(slot, 0) << 1)); + matchingpath += 1 + 2 * IMM2_SIZE; + } + + if (*matchingpath != OP_CREF && *matchingpath != OP_DNCREF) + break; + + add_jump(compiler, &jumplist, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0)); + } + + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), + CMP(SLJIT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0)); + + set_jumps(jumplist, LABEL()); + + allocate_stack(common, has_alternatives ? 3 : 2); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + } + + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_TMP_DEST_REG, 0); + + if (has_alternatives) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); + } else if (has_alternatives) { /* Pushing the starting string pointer. */ @@ -11099,7 +9798,7 @@ if (opcode == OP_COND || opcode == OP_SCOND) if (*matchingpath == OP_CREF) { SLJIT_ASSERT(has_alternatives); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); matchingpath += 1 + IMM2_SIZE; } @@ -11121,13 +9820,13 @@ if (opcode == OP_COND || opcode == OP_SCOND) slot += common->name_entry_size; } OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO)); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), JUMP(SLJIT_ZERO)); matchingpath += 1 + 2 * IMM2_SIZE; } else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) { /* Never has other case. */ - BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; + BACKTRACK_AS(bracket_backtrack)->u.no_capture = NULL; SLJIT_ASSERT(!has_alternatives); if (*matchingpath == OP_TRUE) @@ -11216,9 +9915,6 @@ switch (opcode) if (PRIVATE_DATA(ccbegin + 1)) OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); break; - case OP_ASSERT_NA: - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - break; case OP_ONCE: match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); break; @@ -11284,7 +9980,7 @@ if (has_alternatives) if (i <= 3) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); else - BACKTRACK_AS(bracket_backtrack)->u.matching_mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize)); + BACKTRACK_AS(bracket_backtrack)->matching_mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize)); } if (ket != OP_KETRMAX) BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); @@ -11296,6 +9992,22 @@ if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0) SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); } +else switch (opcode) + { + case OP_ASSERT_NA: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + break; + case OP_ASSERT_SCS: + OP1(SLJIT_MOV, TMP1, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP1, 0); + + /* Nested scs blocks will not update this variable. */ + if (common->restore_end_ptr == private_data_ptr + SSIZE_OF(sw)) + common->restore_end_ptr = 0; + break; + } if (ket == OP_KETRMAX) { @@ -11359,13 +10071,19 @@ if (bra == OP_BRAMINZERO) /* We need to release the end pointer to perform the backtrack for the zero-length iteration. When framesize is < 0, OP_ONCE will do the release itself. */ - if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) + if (opcode == OP_ONCE) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw)); + int framesize = BACKTRACK_AS(bracket_backtrack)->u.framesize; + + SLJIT_ASSERT(framesize != 0); + if (framesize > 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); + } } - else if (ket == OP_KETRMIN && opcode != OP_ONCE) + else if (ket == OP_KETRMIN) free_stack(common, 1); } /* Continue to the normal backtrack. */ @@ -11613,12 +10331,7 @@ while (*cc != OP_KETRPOS) add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); if (!zero) - { - if (framesize < 0) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); - else - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } JUMPTO(SLJIT_JUMP, loop); @@ -11712,11 +10425,11 @@ else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) } else { - SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS); + SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS || *opcode == OP_ECLASS); *type = *opcode; + class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 1); + *opcode = cc[class_len]; cc++; - class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0); - *opcode = cc[class_len - 1]; if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) { @@ -11728,8 +10441,10 @@ else *exact = 1; *opcode -= OP_PLUS - OP_STAR; } + return cc; } - else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) + + if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) { *opcode -= OP_CRPOSSTAR - OP_POSSTAR; *end = cc + class_len; @@ -11739,41 +10454,40 @@ else *exact = 1; *opcode = OP_POSSTAR; } + return cc; } - else + + SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); + *max = GET2(cc, (class_len + IMM2_SIZE)); + *exact = GET2(cc, class_len); + *end = cc + class_len + 2 * IMM2_SIZE; + + if (*max == 0) { - SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); - *max = GET2(cc, (class_len + IMM2_SIZE)); - *exact = GET2(cc, class_len); + SLJIT_ASSERT(*exact > 1); + if (*opcode == OP_CRRANGE) + *opcode = OP_UPTO; + else if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSUPTO; + else + *opcode = OP_MINSTAR; + return cc; + } - if (*max == 0) - { - if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSSTAR; - else - *opcode -= OP_CRRANGE - OP_STAR; - } + *max -= *exact; + if (*max == 0) + *opcode = OP_EXACT; + else + { + SLJIT_ASSERT(*exact > 0 || *max > 1); + if (*opcode == OP_CRRANGE) + *opcode = OP_UPTO; + else if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSUPTO; + else if (*max == 1) + *opcode = OP_MINQUERY; else - { - *max -= *exact; - if (*max == 0) - *opcode = OP_EXACT; - else if (*max == 1) - { - if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSQUERY; - else - *opcode -= OP_CRRANGE - OP_QUERY; - } - else - { - if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSUPTO; - else - *opcode -= OP_CRRANGE - OP_UPTO; - } - } - *end = cc + class_len + 2 * IMM2_SIZE; + *opcode = OP_MINUPTO; } return cc; } @@ -11819,16 +10533,17 @@ if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); return cc; } -static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent, jump_list **prev_backtracks) { DEFINE_COMPILER; -backtrack_common *backtrack; +backtrack_common *backtrack = NULL; +PCRE2_SPTR begin = cc; PCRE2_UCHAR opcode; PCRE2_UCHAR type; sljit_u32 max = 0, exact; sljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1); sljit_s32 early_fail_type; -BOOL charpos_enabled; +BOOL charpos_enabled, use_tmp; PCRE2_UCHAR charpos_char; unsigned int charpos_othercasebit; PCRE2_SPTR end; @@ -11841,11 +10556,6 @@ int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw); int tmp_base, tmp_offset; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -BOOL use_tmp; -#endif - -PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL); early_fail_type = (early_fail_ptr & 0x7); early_fail_ptr >>= 3; @@ -11861,7 +10571,7 @@ SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0 || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr)); if (early_fail_type == type_fail) - add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); + add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); @@ -11873,39 +10583,47 @@ if (type != OP_EXTUNI) else { tmp_base = SLJIT_MEM1(SLJIT_SP); - tmp_offset = POSSESSIVE0; + tmp_offset = LOCAL2; } -/* Handle fixed part first. */ -if (exact > 1) +if (opcode == OP_EXACT) { - SLJIT_ASSERT(early_fail_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0 && exact >= 2); if (common->mode == PCRE2_JIT_COMPLETE -#ifdef SUPPORT_UNICODE +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 && !common->utf #endif && type != OP_ANYNL && type != OP_EXTUNI) { - OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); - add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); + OP2(SLJIT_SUB, TMP1, 0, STR_END, 0, STR_PTR, 0); + add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, IN_UCHARS(exact))); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32 + if (type == OP_ALLANY && !common->invalid_utf) +#else + if (type == OP_ALLANY) +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); + else + { + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, prev_backtracks, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } } else { + SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw)); OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); + compile_char1_matchingpath(common, type, cc, prev_backtracks, TRUE); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } } -else if (exact == 1) - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); if (early_fail_type == type_fail_range) { @@ -11914,38 +10632,57 @@ if (early_fail_type == type_fail_range) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0); OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0); - add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); + add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw), STR_PTR, 0); } +if (opcode < OP_EXACT) + PUSH_BACKTRACK(sizeof(char_iterator_backtrack), begin, NULL); + switch(opcode) { case OP_STAR: case OP_UPTO: - SLJIT_ASSERT(early_fail_ptr == 0 || opcode == OP_STAR); + SLJIT_ASSERT(backtrack != NULL && (early_fail_ptr == 0 || opcode == OP_STAR)); + max += exact; - if (type == OP_ANYNL || type == OP_EXTUNI) + if (type == OP_EXTUNI) { SLJIT_ASSERT(private_data_ptr == 0); SLJIT_ASSERT(early_fail_ptr == 0); - allocate_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + if (exact == 1) + { + SLJIT_ASSERT(opcode == OP_STAR); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + { + /* If OP_EXTUNI is present, it has a separate EXACT opcode. */ + SLJIT_ASSERT(exact == 0); + + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + } if (opcode == OP_UPTO) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max); + { + SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, SLJIT_IMM, max); + } label = LABEL(); - compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); if (opcode == OP_UPTO) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); jump = JUMP(SLJIT_ZERO); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, TMP1, 0); } /* We cannot use TMP3 because of allocate_stack. */ @@ -11965,6 +10702,9 @@ switch(opcode) { if (opcode == OP_STAR) { + if (exact == 1) + detect_partial_match(common, prev_backtracks); + if (private_data_ptr == 0) allocate_stack(common, 2); @@ -11985,6 +10725,9 @@ switch(opcode) else #endif { + /* If OP_ALLANY is present, it has a separate EXACT opcode. */ + SLJIT_ASSERT(exact == 0); + if (private_data_ptr == 0) allocate_stack(common, 2); @@ -12016,6 +10759,7 @@ switch(opcode) charpos_char = 0; charpos_othercasebit = 0; + SLJIT_ASSERT(tmp_base == TMP3); if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI)) { #ifdef SUPPORT_UNICODE @@ -12045,176 +10789,320 @@ switch(opcode) if (charpos_othercasebit != 0) charpos_char |= charpos_othercasebit; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit; + BACKTRACK_AS(char_iterator_backtrack)->charpos.charpos_enabled = TRUE; + BACKTRACK_AS(char_iterator_backtrack)->charpos.chr = charpos_char; + BACKTRACK_AS(char_iterator_backtrack)->charpos.othercasebit = charpos_othercasebit; + + if (private_data_ptr == 0) + allocate_stack(common, 2); + + use_tmp = (opcode == OP_STAR); + + if (use_tmp) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, base, offset0, TMP3, 0); + } + else + { + OP1(SLJIT_MOV, base, offset1, COUNT_MATCH, 0); + OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, base, offset0, COUNT_MATCH, 0); + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? 0 : (max + 1)); + } + + /* Search the first instance of charpos_char. */ + if (exact > 0) + detect_partial_match(common, &no_match); + else + jump = JUMP(SLJIT_JUMP); + + label = LABEL(); + + if (opcode == OP_UPTO) + { + if (exact == max) + OP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + else + { + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + } + } + + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); + + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); + + if (exact == 0) + JUMPHERE(jump); + + detect_partial_match(common, &no_match); + + if (opcode == OP_UPTO && exact > 0) + { + if (exact == max) + CMPTO(SLJIT_LESS, TMP3, 0, SLJIT_IMM, exact, label); + else + CMPTO(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, (max + 1) - exact, label); + } + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (use_tmp) + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, SLJIT_IMM, 0); + SELECT(SLJIT_EQUAL, TMP3, STR_PTR, 0, TMP3); + } + else + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, SLJIT_IMM, 0); + SELECT(SLJIT_EQUAL, COUNT_MATCH, STR_PTR, 0, COUNT_MATCH); + } + JUMPTO(SLJIT_JUMP, label); + + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + if (use_tmp) + OP1(SLJIT_MOV, base, offset1, TMP3, 0); + else + { + OP1(SLJIT_MOV, TMP1, 0, base, offset1); + OP1(SLJIT_MOV, base, offset1, COUNT_MATCH, 0); + OP1(SLJIT_MOV, COUNT_MATCH, 0, TMP1, 0); + } + + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0)); + + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + break; } } - if (charpos_enabled) - { - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1); + if (private_data_ptr == 0) + allocate_stack(common, 2); - /* Search the first instance of charpos_char. */ - jump = JUMP(SLJIT_JUMP); - label = LABEL(); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_ZERO)); - } - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); - if (early_fail_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); - JUMPHERE(jump); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + use_tmp = (opcode == OP_STAR); - detect_partial_match(common, &backtrack->own_backtracks); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (charpos_othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + if (common->utf) + { + if (!use_tmp) + OP1(SLJIT_MOV, base, offset0, COUNT_MATCH, 0); - if (private_data_ptr == 0) - allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0); + } +#endif - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); - } + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? -(sljit_sw)exact : (sljit_sw)max); - /* Search the last instance of charpos_char. */ + if (opcode == OP_UPTO && exact > 0) + { label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - if (early_fail_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); detect_partial_match(common, &no_match); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (charpos_othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0); +#endif - if (opcode == OP_STAR) + if (exact == max) { - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, label); + OP2(SLJIT_ADD | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); } else { - jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPHERE(jump); - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + CMPTO(SLJIT_NOT_EQUAL, TMP3, 0, SLJIT_IMM, max - exact, label); } - set_jumps(no_match, LABEL()); - OP2(SLJIT_ADD, STR_PTR, 0, base, offset0, SLJIT_IMM, IN_UCHARS(1)); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); } else { - if (private_data_ptr == 0) - allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR); - SLJIT_ASSERT(!use_tmp || tmp_base == TMP3); - - if (common->utf) - OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0); -#endif - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); detect_partial_match(common, &no_match); label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 if (common->utf) - OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0); + OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0); #endif if (opcode == OP_UPTO) { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); } detect_partial_match_to(common, label); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } - set_jumps(no_char1_match, LABEL()); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) + if (common->utf) + { + set_jumps(no_char1_match, LABEL()); + set_jumps(no_match, LABEL()); + if (use_tmp) { - set_jumps(no_match, LABEL()); - if (use_tmp) - { - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - OP1(SLJIT_MOV, base, offset0, TMP3, 0); - } - else - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + OP1(SLJIT_MOV, base, offset0, TMP3, 0); } else -#endif { - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, COUNT_MATCH, 0); + OP1(SLJIT_MOV, COUNT_MATCH, 0, base, offset0); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); } + } + else +#endif + { + if (opcode != OP_UPTO || exact == 0) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_char1_match, LABEL()); - if (early_fail_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } + + if (opcode == OP_UPTO) + { + if (exact > 0) + { + if (max == exact) + jump = CMP(SLJIT_GREATER_EQUAL, TMP3, 0, SLJIT_IMM, -(sljit_sw)exact); + else + jump = CMP(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, max - exact); + + add_jump(compiler, &backtrack->own_backtracks, jump); + } } + else if (exact == 1) + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, base, offset1, STR_PTR, 0)); + + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; - case OP_MINSTAR: + case OP_QUERY: + SLJIT_ASSERT(backtrack != NULL && early_fail_ptr == 0); if (private_data_ptr == 0) allocate_stack(common, 1); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; + + case OP_MINSTAR: + case OP_MINQUERY: + SLJIT_ASSERT(backtrack != NULL && (opcode == OP_MINSTAR || early_fail_ptr == 0)); + if (private_data_ptr == 0) + allocate_stack(common, 1); + + if (exact >= 1) + { + if (exact >= 2) + { + /* Extuni has a separate exact opcode. */ + SLJIT_ASSERT(tmp_base == TMP3 && early_fail_ptr == 0); + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact); + } + + if (opcode == OP_MINQUERY) + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, -1); + + label = LABEL(); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = label; + + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); + + if (exact >= 2) + { + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + + if (opcode == OP_MINQUERY) + OP2(SLJIT_AND, base, offset0, base, offset0, STR_PTR, 0); + else + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } + else + { + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + } + if (early_fail_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); break; case OP_MINUPTO: - SLJIT_ASSERT(early_fail_ptr == 0); + SLJIT_ASSERT(backtrack != NULL && early_fail_ptr == 0); if (private_data_ptr == 0) allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - break; - case OP_QUERY: - case OP_MINQUERY: - SLJIT_ASSERT(early_fail_ptr == 0); - if (private_data_ptr == 0) - allocate_stack(common, 1); + if (exact == 0) + { + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; + } + + if (exact >= 2) + { + /* Extuni has a separate exact opcode. */ + SLJIT_ASSERT(tmp_base == TMP3); + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact); + } + + label = LABEL(); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = label; + + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); + + if (exact >= 2) + { + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (opcode == OP_QUERY) - compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; case OP_EXACT: + SLJIT_ASSERT(backtrack == NULL); break; case OP_POSSTAR: + SLJIT_ASSERT(backtrack == NULL); #if defined SUPPORT_UNICODE if (type == OP_ALLANY && !common->invalid_utf) #else if (type == OP_ALLANY) #endif { + if (exact == 1) + detect_partial_match(common, prev_backtracks); + OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); process_partial_match(common); if (early_fail_ptr != 0) @@ -12223,98 +11111,150 @@ switch(opcode) } #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (type == OP_EXTUNI || common->utf) + if (common->utf) { - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw)); + + if (tmp_base != TMP3) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, COUNT_MATCH, 0); + tmp_base = COUNT_MATCH; + } + + OP1(SLJIT_MOV, tmp_base, 0, exact == 1 ? SLJIT_IMM : STR_PTR, 0); detect_partial_match(common, &no_match); label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + OP1(SLJIT_MOV, tmp_base, 0, STR_PTR, 0); detect_partial_match_to(common, label); set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, 0); + + if (tmp_base != TMP3) + OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); + + if (exact == 1) + add_jump(compiler, prev_backtracks, CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0)); + if (early_fail_ptr != 0) - { - if (!HAS_VIRTUAL_REGISTERS && tmp_base == TMP3) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, TMP3, 0); - else - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); - } + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); break; } #endif + if (exact == 1) + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + detect_partial_match(common, &no_match); label = LABEL(); + /* Extuni never fails, so no_char1_match is not used in that case. + Anynl optionally reads an extra character on success. */ compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); detect_partial_match_to(common, label); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + if (type != OP_EXTUNI) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_char1_match, LABEL()); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + if (type != OP_EXTUNI) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + + if (exact == 1) + add_jump(compiler, prev_backtracks, CMP(SLJIT_EQUAL, tmp_base, tmp_offset, STR_PTR, 0)); + if (early_fail_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); break; - case OP_POSUPTO: - SLJIT_ASSERT(early_fail_ptr == 0); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - - detect_partial_match(common, &no_match); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); - detect_partial_match_to(common, label); + case OP_POSUPTO: + SLJIT_ASSERT(backtrack == NULL && early_fail_ptr == 0); + max += exact; - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); - break; - } +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (type == OP_EXTUNI || common->utf) +#else + if (type == OP_EXTUNI) #endif - - if (type == OP_ALLANY) { - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max)); + SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw)); - if (common->mode == PCRE2_JIT_COMPLETE) + /* Count match is not modified by compile_char1_matchingpath. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, COUNT_MATCH, 0); + OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_IMM, exact == max ? 0 : max); + + label = LABEL(); + /* Extuni only modifies TMP3 on successful match. */ + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + + if (exact == max) { - OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); + OP2(SLJIT_ADD, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_JUMP, label); } else { - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0); - process_partial_match(common); - JUMPHERE(jump); + OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + } + + set_jumps(no_match, LABEL()); + + if (exact > 0) + { + if (exact == max) + OP2U(SLJIT_SUB | SLJIT_SET_LESS, COUNT_MATCH, 0, SLJIT_IMM, exact); + else + OP2U(SLJIT_SUB | SLJIT_SET_GREATER, COUNT_MATCH, 0, SLJIT_IMM, max - exact); } + + OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); + + if (exact > 0) + add_jump(compiler, prev_backtracks, JUMP(exact == max ? SLJIT_LESS : SLJIT_GREATER)); + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); break; } - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + SLJIT_ASSERT(tmp_base == TMP3); + + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? 0 : max); detect_partial_match(common, &no_match); label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + + if (exact == max) + OP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + else + { + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + } detect_partial_match_to(common, label); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_char1_match, LABEL()); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_match, LABEL()); + + if (exact > 0) + { + if (exact == max) + jump = CMP(SLJIT_LESS, TMP3, 0, SLJIT_IMM, exact); + else + jump = CMP(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, max - exact); + + add_jump(compiler, prev_backtracks, jump); + } break; case OP_POSQUERY: - SLJIT_ASSERT(early_fail_ptr == 0); + SLJIT_ASSERT(backtrack == NULL && early_fail_ptr == 0); + SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw)); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); compile_char1_matchingpath(common, type, cc, &no_match, TRUE); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); @@ -12477,6 +11417,7 @@ DEFINE_COMPILER; backtrack_common *backtrack; BOOL has_then_trap = FALSE; then_trap_backtrack *save_then_trap = NULL; +size_t op_len; SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); @@ -12612,21 +11553,23 @@ while (cc < ccend) case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSUPTO: - cc = compile_iterator_matchingpath(common, cc, parent); + cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); break; case OP_CLASS: case OP_NCLASS: if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE) - cc = compile_iterator_matchingpath(common, cc, parent); + cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); else cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 case OP_XCLASS: - if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) - cc = compile_iterator_matchingpath(common, cc, parent); + case OP_ECLASS: + op_len = GET(cc, 1); + if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE) + cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); else cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; @@ -12634,24 +11577,26 @@ while (cc < ccend) case OP_REF: case OP_REFI: - if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE) + op_len = PRIV(OP_lengths)[*cc]; + if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); - cc += 1 + IMM2_SIZE; + cc += op_len; } break; case OP_DNREF: case OP_DNREFI: - if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE) + op_len = PRIV(OP_lengths)[*cc]; + if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); - cc += 1 + 2 * IMM2_SIZE; + cc += op_len; } break; @@ -12692,6 +11637,7 @@ while (cc < ccend) case OP_ASSERT_NA: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -12803,6 +11749,28 @@ SLJIT_ASSERT(cc == ccend); #define CURRENT_AS(type) ((type *)current) +static void compile_newline_move_back(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; + +OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, TMP2, 0); +/* All newlines are single byte, or their last byte +is not equal to CHAR_NL/CHAR_CR even if UTF is enabled. */ +OP1(MOV_UCHAR, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); +OP2(SLJIT_SHL, SLJIT_TMP_DEST_REG, 0, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 8); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_TMP_DEST_REG, 0); +OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_CR << 8 | CHAR_NL); +OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +JUMPHERE(jump); +} + static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; @@ -12825,52 +11793,104 @@ switch(opcode) { case OP_STAR: case OP_UPTO: - if (type == OP_ANYNL || type == OP_EXTUNI) + if (type == OP_EXTUNI) { SLJIT_ASSERT(private_data_ptr == 0); - set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); } else { - if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled) + if (CURRENT_AS(char_iterator_backtrack)->charpos.charpos_enabled) { OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP1(SLJIT_MOV, TMP2, 0, base, offset1); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); label = LABEL(); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); + if (type == OP_ANYNL) + compile_newline_move_back(common); move_back(common, NULL, TRUE); - CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (CURRENT_AS(char_iterator_backtrack)->charpos.othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->charpos.othercasebit); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); + /* The range beginning must match, no need to compare. */ + JUMPTO(SLJIT_JUMP, label); + + set_jumps(current->own_backtracks, LABEL()); + current->own_backtracks = NULL; } else { OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); - move_back(common, NULL, TRUE); + + if (opcode == OP_STAR && exact == 1) + { + if (type == OP_ANYNL) + { + OP1(SLJIT_MOV, TMP2, 0, base, offset1); + compile_newline_move_back(common); + } + + move_back(common, NULL, TRUE); + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); + } + else + { + if (type == OP_ANYNL) + { + OP1(SLJIT_MOV, TMP2, 0, base, offset1); + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + compile_newline_move_back(common); + } + else + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); + + move_back(common, NULL, TRUE); + } + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + + set_jumps(current->own_backtracks, LABEL()); } + JUMPHERE(jump); if (private_data_ptr == 0) free_stack(common, 2); } break; + case OP_QUERY: + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); + jump = JUMP(SLJIT_JUMP); + set_jumps(current->own_backtracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + JUMPHERE(jump); + if (private_data_ptr == 0) + free_stack(common, 1); + break; + case OP_MINSTAR: OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (exact == 0) + { + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } + else if (exact > 1) + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - set_jumps(jumplist, LABEL()); + set_jumps(exact > 0 ? current->own_backtracks : jumplist, LABEL()); if (private_data_ptr == 0) free_stack(common, 1); break; @@ -12879,56 +11899,60 @@ switch(opcode) OP1(SLJIT_MOV, TMP1, 0, base, offset1); OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO)); - OP1(SLJIT_MOV, base, offset1, TMP1, 0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + if (exact == 0) + { + add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO)); - set_jumps(jumplist, LABEL()); - if (private_data_ptr == 0) - free_stack(common, 2); - break; + OP1(SLJIT_MOV, base, offset1, TMP1, 0); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + + set_jumps(jumplist, LABEL()); + } + else + { + if (exact > 1) + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, base, offset1, TMP1, 0); + JUMPTO(SLJIT_NOT_ZERO, CURRENT_AS(char_iterator_backtrack)->matchingpath); + + set_jumps(current->own_backtracks, LABEL()); + } - case OP_QUERY: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); - jump = JUMP(SLJIT_JUMP); - set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - JUMPHERE(jump); if (private_data_ptr == 0) - free_stack(common, 1); + free_stack(common, 2); break; case OP_MINQUERY: OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - set_jumps(jumplist, LABEL()); - JUMPHERE(jump); + + if (exact >= 1) + { + if (exact >= 2) + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); + set_jumps(current->own_backtracks, LABEL()); + } + else + { + jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + set_jumps(jumplist, LABEL()); + JUMPHERE(jump); + } + if (private_data_ptr == 0) free_stack(common, 1); break; - case OP_EXACT: - case OP_POSSTAR: - case OP_POSQUERY: - case OP_POSUPTO: - break; - default: SLJIT_UNREACHABLE(); break; } - -set_jumps(current->own_backtracks, LABEL()); } static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -12938,7 +11962,7 @@ PCRE2_SPTR cc = current->cc; BOOL ref = (*cc == OP_REF || *cc == OP_REFI); PCRE2_UCHAR type; -type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; +type = cc[PRIV(OP_lengths)[*cc]]; if ((type & 0x1) == 0) { @@ -13057,7 +12081,7 @@ PCRE2_SPTR ccbegin; PCRE2_SPTR ccprev; PCRE2_UCHAR bra = OP_BRA; PCRE2_UCHAR ket; -assert_backtrack *assert; +const assert_backtrack *assert; BOOL has_alternatives; BOOL needs_control_head = FALSE; BOOL has_vreverse; @@ -13093,7 +12117,7 @@ ccbegin = cc; cc += GET(cc, 1); has_alternatives = *cc == OP_ALT; if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) - has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; + has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.no_capture != NULL; if (opcode == OP_CBRA || opcode == OP_SCBRA) offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) @@ -13196,14 +12220,27 @@ if (offset != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); } } +else if (SLJIT_UNLIKELY(opcode == OP_ASSERT_SCS)) + { + OP1(SLJIT_MOV, TMP1, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP1, 0); + + /* Nested scs blocks will not update this variable. */ + if (common->restore_end_ptr == 0) + common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw); + } if (SLJIT_UNLIKELY(opcode == OP_ONCE)) { - if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + int framesize = CURRENT_AS(bracket_backtrack)->u.framesize; + + SLJIT_ASSERT(framesize != 0); + if (framesize > 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); } once = JUMP(SLJIT_JUMP); } @@ -13228,8 +12265,8 @@ else if (has_alternatives) { sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0); - SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_mov_addr); - sljit_set_label(CURRENT_AS(bracket_backtrack)->u.matching_mov_addr, LABEL()); + SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->matching_mov_addr != NULL); + sljit_set_label(CURRENT_AS(bracket_backtrack)->matching_mov_addr, LABEL()); sljit_emit_op0(compiler, SLJIT_ENDBR); } else @@ -13247,7 +12284,8 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { SLJIT_ASSERT(has_alternatives); assert = CURRENT_AS(bracket_backtrack)->u.assert; - if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) + SLJIT_ASSERT(assert->framesize != 0); + if (assert->framesize > 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -13258,11 +12296,11 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) cond = JUMP(SLJIT_JUMP); set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); } - else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) + else if (CURRENT_AS(bracket_backtrack)->u.no_capture != NULL) { SLJIT_ASSERT(has_alternatives); cond = JUMP(SLJIT_JUMP); - set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); + set_jumps(CURRENT_AS(bracket_backtrack)->u.no_capture, LABEL()); } else SLJIT_ASSERT(!has_alternatives); @@ -13283,26 +12321,33 @@ if (has_alternatives) cc += GET(cc, 1); has_vreverse = FALSE; - if (opcode == OP_ASSERTBACK || opcode == OP_ASSERTBACK_NA) - { - SLJIT_ASSERT(private_data_ptr != 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - has_vreverse = (*ccprev == OP_VREVERSE); - if (*ccprev == OP_REVERSE || has_vreverse) - ccprev = compile_reverse_matchingpath(common, ccprev, current); - } - else if (opcode != OP_COND && opcode != OP_SCOND) + switch (opcode) { - if (opcode != OP_ONCE) - { + case OP_ASSERTBACK: + case OP_ASSERTBACK_NA: + SLJIT_ASSERT(private_data_ptr != 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + + has_vreverse = (*ccprev == OP_VREVERSE); + if (*ccprev == OP_REVERSE || has_vreverse) + ccprev = compile_reverse_matchingpath(common, ccprev, current); + break; + case OP_ASSERT_SCS: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); + break; + case OP_ONCE: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); + break; + case OP_COND: + case OP_SCOND: + break; + default: if (private_data_ptr != 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); else OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - } - else - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); + break; } compile_matchingpath(common, ccprev, cc, current); @@ -13423,14 +12468,18 @@ if (has_alternatives) if (cond != NULL) { SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); - assert = CURRENT_AS(bracket_backtrack)->u.assert; - if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) + if (ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0); + assert = CURRENT_AS(bracket_backtrack)->u.assert; + SLJIT_ASSERT(assert->framesize != 0); + if (assert->framesize > 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0); + } } JUMPHERE(cond); } @@ -13472,6 +12521,21 @@ else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SC OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); } +else if (opcode == OP_ASSERT_SCS) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP2, 0); + free_stack(common, has_alternatives ? 3 : 2); + + set_jumps(CURRENT_AS(bracket_backtrack)->u.no_capture, LABEL()); + + /* Nested scs blocks will not update this variable. */ + if (common->restore_end_ptr == private_data_ptr + SSIZE_OF(sw)) + common->restore_end_ptr = 0; + } else if (opcode == OP_ONCE) { cc = ccbegin + GET(ccbegin, 1); @@ -13652,6 +12716,9 @@ if (opcode == OP_THEN || opcode == OP_THEN_ARG) } } +if (common->restore_end_ptr != 0 && opcode != OP_SKIP_ARG) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr); + if (common->local_quit_available) { /* Abort match with a fail. */ @@ -13669,8 +12736,18 @@ if (opcode == OP_SKIP_ARG) OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2)); sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_search_mark)); + if (common->restore_end_ptr == 0) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0); + add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0)); + return; + } + + jump = CMP(SLJIT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0); - add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0)); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr); + add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); + JUMPHERE(jump); return; } @@ -13702,6 +12779,7 @@ static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *com { DEFINE_COMPILER; struct sljit_jump *jump; +int framesize; int size; if (CURRENT_AS(then_trap_backtrack)->then_trap) @@ -13718,11 +12796,15 @@ free_stack(common, size); jump = JUMP(SLJIT_JUMP); set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); + +framesize = CURRENT_AS(then_trap_backtrack)->framesize; +SLJIT_ASSERT(framesize != 0); + /* STACK_TOP is set by THEN. */ -if (CURRENT_AS(then_trap_backtrack)->framesize >= 0) +if (framesize > 0) { add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(then_trap_backtrack)->framesize - 1) * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); } OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 3); @@ -13813,10 +12895,13 @@ while (current) case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSUPTO: + /* Since classes has no backtracking path, this + backtrackingpath was pushed by an iterator. */ case OP_CLASS: case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: + case OP_ECLASS: #endif compile_iterator_backtrackingpath(common, current); break; @@ -13841,6 +12926,7 @@ while (current) case OP_ASSERT_NA: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -13892,8 +12978,12 @@ while (current) case OP_COMMIT: case OP_COMMIT_ARG: + if (common->restore_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr); + if (!common->local_quit_available) OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); + if (common->quit_label == NULL) add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); else @@ -14154,8 +13244,7 @@ int private_data_size; PCRE2_SPTR ccend; executable_functions *functions; void *executable_func; -sljit_uw executable_size; -sljit_uw total_length; +sljit_uw executable_size, private_data_length, total_length; struct sljit_label *mainloop_label = NULL; struct sljit_label *continue_match_label; struct sljit_label *empty_match_found_label = NULL; @@ -14182,7 +13271,7 @@ memset(&rootbacktrack, 0, sizeof(backtrack_common)); memset(common, 0, sizeof(compiler_common)); common->re = re; common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); -rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size; +rootbacktrack.cc = (PCRE2_SPTR)((uint8_t *)re + re->code_start); #ifdef SUPPORT_UNICODE common->invalid_utf = (mode & PCRE2_JIT_INVALID_UTF) != 0; @@ -14230,7 +13319,7 @@ common->name_entry_size = re->name_entry_size; common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0; common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0; #ifdef SUPPORT_UNICODE -/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ +/* PCRE2_UTF[16|32] have the same value as PCRE2_UTF8. */ common->utf = (re->overall_options & PCRE2_UTF) != 0; common->ucp = (re->overall_options & PCRE2_UCP) != 0; if (common->utf) @@ -14262,10 +13351,26 @@ else ccend = bracketend(common->start); /* Calculate the local space size on the stack. */ -common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); -common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data); -if (!common->optimized_cbracket) +common->ovector_start = LOCAL0; +/* Allocate space for temporary data structures. */ +private_data_length = ccend - common->start; +/* The chance of overflow is very low, but might happen on 32 bit. */ +if (private_data_length > ~(sljit_uw)0 / sizeof(sljit_s32)) return PCRE2_ERROR_NOMEMORY; + +private_data_length *= sizeof(sljit_s32); +/* Align to 32 bit. */ +total_length = ((re->top_bracket + 1) + (sljit_uw)(sizeof(sljit_s32) - 1)) & ~(sljit_uw)(sizeof(sljit_s32) - 1); +if (~(sljit_uw)0 - private_data_length < total_length) + return PCRE2_ERROR_NOMEMORY; + +total_length += private_data_length; +common->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length, allocator_data); +if (!common->private_data_ptrs) + return PCRE2_ERROR_NOMEMORY; + +memset(common->private_data_ptrs, 0, private_data_length); +common->optimized_cbracket = ((sljit_u8 *)common->private_data_ptrs) + private_data_length; #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 memset(common->optimized_cbracket, 0, re->top_bracket + 1); #else @@ -14279,16 +13384,19 @@ common->ovector_start += sizeof(sljit_sw); #endif if (!check_opcode_types(common, common->start, ccend)) { - SLJIT_FREE(common->optimized_cbracket, allocator_data); - return PCRE2_ERROR_NOMEMORY; + SLJIT_FREE(common->private_data_ptrs, allocator_data); + return PCRE2_ERROR_JIT_UNSUPPORTED; } /* Checking flags and updating ovector_start. */ -if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) +if (mode == PCRE2_JIT_COMPLETE && + (re->flags & PCRE2_LASTSET) != 0 && + (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) { common->req_char_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } + if (mode != PCRE2_JIT_COMPLETE) { common->start_used_ptr = common->ovector_start; @@ -14299,19 +13407,23 @@ if (mode != PCRE2_JIT_COMPLETE) common->ovector_start += sizeof(sljit_sw); } } + if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0) { common->match_end_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } + #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD common->control_head_ptr = 1; #endif + if (common->control_head_ptr != 0) { common->control_head_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } + if (common->has_set_som) { /* Saving the real start pointer is necessary. */ @@ -14332,19 +13444,11 @@ if (common->capture_last_ptr != 0) SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); - -total_length = ccend - common->start; -common->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data); -if (!common->private_data_ptrs) - { - SLJIT_FREE(common->optimized_cbracket, allocator_data); - return PCRE2_ERROR_NOMEMORY; - } -memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32)); - private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); -if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back) +if ((re->overall_options & PCRE2_ANCHORED) == 0 && + (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0 && + !common->has_skip_in_assert_back) detect_early_fail(common, common->start, &private_data_size, 0, 0); set_private_data_ptrs(common, &private_data_size, ccend); @@ -14354,13 +13458,18 @@ SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr); if (private_data_size > 65536) { SLJIT_FREE(common->private_data_ptrs, allocator_data); - SLJIT_FREE(common->optimized_cbracket, allocator_data); - return PCRE2_ERROR_NOMEMORY; + return PCRE2_ERROR_JIT_UNSUPPORTED; } if (common->has_then) { - common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length); + total_length = ccend - common->start; + common->then_offsets = (sljit_u8 *)SLJIT_MALLOC(total_length, allocator_data); + if (!common->then_offsets) + { + SLJIT_FREE(common->private_data_ptrs, allocator_data); + return PCRE2_ERROR_NOMEMORY; + } memset(common->then_offsets, 0, total_length); set_then_offsets(common, common->start, NULL); } @@ -14368,15 +13477,16 @@ if (common->has_then) compiler = sljit_create_compiler(allocator_data); if (!compiler) { - SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); + if (common->has_then) + SLJIT_FREE(common->then_offsets, allocator_data); return PCRE2_ERROR_NOMEMORY; } common->compiler = compiler; /* Main pcre2_jit_exec entry. */ SLJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0); -sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS, 0, private_data_size); +sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5 | SLJIT_ENTER_VECTOR(SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS), 5, private_data_size); /* Register init. */ reset_ovector(common, (re->top_bracket + 1) * 2); @@ -14410,7 +13520,7 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0) mainloop_label = mainloop_entry(common); continue_match_label = LABEL(); /* Forward search if possible. */ - if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) + if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) { if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common)) ; @@ -14425,7 +13535,8 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0) else continue_match_label = LABEL(); -if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) +if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && + (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) { OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength)); @@ -14460,8 +13571,9 @@ compile_matchingpath(common, common->start, ccend, &rootbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); + if (common->has_then) + SLJIT_FREE(common->then_offsets, allocator_data); PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); return PCRE2_ERROR_NOMEMORY; } @@ -14516,8 +13628,9 @@ compile_backtrackingpath(common, rootbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); + if (common->has_then) + SLJIT_FREE(common->then_offsets, allocator_data); PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); return PCRE2_ERROR_NOMEMORY; } @@ -14598,6 +13711,8 @@ common->early_fail_end_ptr = 0; common->currententry = common->entries; common->local_quit_available = TRUE; quit_label = common->quit_label; +SLJIT_ASSERT(common->restore_end_ptr == 0); + if (common->currententry != NULL) { /* A free bit for each private data. */ @@ -14627,24 +13742,28 @@ if (common->currententry != NULL) SLJIT_ASSERT(sljit_get_compiler_error(compiler) || common->recurse_bitset == NULL); sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); + if (common->has_then) + SLJIT_FREE(common->then_offsets, allocator_data); PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); return PCRE2_ERROR_NOMEMORY; } } + common->local_quit_available = FALSE; common->quit_label = quit_label; +SLJIT_ASSERT(common->restore_end_ptr == 0); -/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ +/* Allocating stack, returns with PCRE2_ERROR_JIT_STACKLIMIT if fails. */ /* This is a (really) rare case. */ set_jumps(common->stackalloc, LABEL()); /* RETURN_ADDR is not a saved register. */ -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); +SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE); OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack)); @@ -14655,8 +13774,8 @@ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FU jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); /* Allocation failed. */ @@ -14777,8 +13896,9 @@ if (common->getucdtype != NULL) } #endif /* SUPPORT_UNICODE */ -SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); +if (common->has_then) + SLJIT_FREE(common->then_offsets, allocator_data); executable_func = sljit_generate_code(compiler, 0, NULL); executable_size = sljit_get_generated_code_size(compiler); @@ -14848,9 +13968,36 @@ pcre2_jit_compile(pcre2_code *code, uint32_t options) { pcre2_real_code *re = (pcre2_real_code *)code; #ifdef SUPPORT_JIT +void *exec_memory; executable_functions *functions; static int executable_allocator_is_working = -1; + +if (executable_allocator_is_working == -1) + { + /* Checks whether the executable allocator is working. This check + might run multiple times in multi-threaded environments, but the + result should not be affected by it. */ + exec_memory = SLJIT_MALLOC_EXEC(32, NULL); + if (exec_memory != NULL) + { + SLJIT_FREE_EXEC(((sljit_u8*)(exec_memory)) + SLJIT_EXEC_OFFSET(exec_memory), NULL); + executable_allocator_is_working = 1; + } + else executable_allocator_is_working = 0; + } +#endif + +if (options & PCRE2_JIT_TEST_ALLOC) + { + if (options != PCRE2_JIT_TEST_ALLOC) + return PCRE2_ERROR_JIT_BADOPTION; + +#ifdef SUPPORT_JIT + return executable_allocator_is_working ? 0 : PCRE2_ERROR_NOMEMORY; +#else + return PCRE2_ERROR_JIT_UNSUPPORTED; #endif + } if (code == NULL) return PCRE2_ERROR_NULL; @@ -14912,20 +14059,6 @@ return PCRE2_ERROR_JIT_BADOPTION; if ((re->flags & PCRE2_NOJIT) != 0) return 0; -if (executable_allocator_is_working == -1) - { - /* Checks whether the executable allocator is working. This check - might run multiple times in multi-threaded environments, but the - result should not be affected by it. */ - void *ptr = SLJIT_MALLOC_EXEC(32, NULL); - if (ptr != NULL) - { - SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr), NULL); - executable_allocator_is_working = 1; - } - else executable_allocator_is_working = 0; - } - if (!executable_allocator_is_working) return PCRE2_ERROR_NOMEMORY; diff --git a/ext/pcre/pcre2lib/pcre2_jit_match.c b/ext/pcre/pcre2lib/pcre2_jit_match.c index ae5903e202b57..8867f768df15c 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_match.c +++ b/ext/pcre/pcre2lib/pcre2_jit_match.c @@ -83,7 +83,7 @@ return executable_func(arguments); Returns: > 0 => success; value is the number of ovector pairs filled = 0 => success, but ovector is not big enough - -1 => failed to match (PCRE_ERROR_NOMATCH) + -1 => failed to match (PCRE2_ERROR_NOMATCH) < -1 => some kind of unexpected problem */ diff --git a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h index 4a718b67b7eba..1389a16573d56 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h +++ b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h @@ -82,7 +82,7 @@ POSSIBILITY OF SUCH DAMAGE. # endif # endif -#if (defined(__GNUC__) && __SANITIZE_ADDRESS__) \ +#if (defined(__GNUC__) && defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__ ) \ || (defined(__clang__) \ && ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3))) __attribute__((no_sanitize_address)) @@ -198,14 +198,14 @@ vect_t data = VLD1Q(*str_ptr); #if PCRE2_CODE_UNIT_WIDTH != 8 data = VANDQ(data, char_mask); #endif - + #if defined(FFCS) vect_t eq = VCEQQ(data, vc1); #elif defined(FFCS_2) vect_t eq1 = VCEQQ(data, vc1); vect_t eq2 = VCEQQ(data, vc2); -vect_t eq = VORRQ(eq1, eq2); +vect_t eq = VORRQ(eq1, eq2); #elif defined(FFCS_MASK) vect_t eq = VORRQ(data, vmask); @@ -226,7 +226,7 @@ if (p1 < *str_ptr) } else data2 = shift_left_n_lanes(data, offs1 - offs2); - + if (compare1_type == compare_match1) data = VCEQQ(data, cmp1a); else @@ -281,7 +281,7 @@ while (*str_ptr < str_end) #elif defined(FFCS_2) eq1 = VCEQQ(data, vc1); eq2 = VCEQQ(data, vc2); - eq = VORRQ(eq1, eq2); + eq = VORRQ(eq1, eq2); #elif defined(FFCS_MASK) eq = VORRQ(data, vmask); diff --git a/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h b/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h index 502977fc32045..66e93cd5996fd 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h +++ b/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h @@ -246,10 +246,10 @@ struct sljit_jump *quit; struct sljit_jump *partial_quit[2]; vector_compare_type compare_type = vector_compare_match1; sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); -sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); -sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); -sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); -sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3); sljit_u32 bit = 0; int i; @@ -273,17 +273,17 @@ if (common->mode == PCRE2_JIT_COMPLETE) /* First part (unaligned start) */ value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; -sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR1, SLJIT_VR1, 0); if (char1 != char2) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); @@ -294,12 +294,12 @@ OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -318,11 +318,11 @@ if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, &common->failed_match, partial_quit[1]); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); @@ -380,10 +380,10 @@ struct sljit_jump *quit; jump_list *not_found = NULL; vector_compare_type compare_type = vector_compare_match1; sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); -sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); -sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); -sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); -sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3); sljit_u32 bit = 0; int i; @@ -406,29 +406,29 @@ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); /* First part (unaligned start) */ value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; -sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR1, SLJIT_VR1, 0); if (char1 != char2) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0); value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -445,12 +445,12 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); @@ -488,14 +488,14 @@ sljit_u32 bit1 = 0; sljit_u32 bit2 = 0; sljit_u32 diff = IN_UCHARS(offs1 - offs2); sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); -sljit_s32 data1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); -sljit_s32 data2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); -sljit_s32 cmp1a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); -sljit_s32 cmp2a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); -sljit_s32 cmp1b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR4); -sljit_s32 cmp2b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR5); -sljit_s32 tmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR6); -sljit_s32 tmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_TMP_FR0); +sljit_s32 data1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0); +sljit_s32 data2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1); +sljit_s32 cmp1a_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2); +sljit_s32 cmp2a_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3); +sljit_s32 cmp1b_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR4); +sljit_s32 cmp2b_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR5); +sljit_s32 tmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR6); +sljit_s32 tmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_TMP_DEST_VREG); struct sljit_label *start; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 struct sljit_label *restart; @@ -541,10 +541,10 @@ else } value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; -sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, TMP1, 0); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, TMP1, 0); if (char1a != char1b) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR4, 0, TMP2, 0); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR4, 0, TMP2, 0); if (char2a == char2b) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); @@ -566,18 +566,18 @@ else } } -sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR3, 0, TMP1, 0); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR3, 0, TMP1, 0); if (char2a != char2b) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR5, 0, TMP2, 0); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR5, 0, TMP2, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0); if (char1a != char1b) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR4, SLJIT_FR4, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR4, SLJIT_VR4, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR3, SLJIT_FR3, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR3, SLJIT_VR3, 0); if (char2a != char2b) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR5, SLJIT_FR5, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR5, SLJIT_VR5, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); @@ -589,11 +589,11 @@ value = (reg_type == SLJIT_SIMD_REG_256) ? ~0x1f : ~0xf; OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0); -sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); jump[1] = JUMP(SLJIT_JUMP); JUMPHERE(jump[0]); @@ -668,8 +668,8 @@ for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); } -sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); /* Ignore matches before the first STR_PTR. */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); @@ -687,8 +687,8 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); -sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); for (i = 0; i < 4; i++) { @@ -696,8 +696,8 @@ for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); } -sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); @@ -843,12 +843,13 @@ DEFINE_COMPILER; int_char ic; struct sljit_jump *partial_quit, *quit; /* Save temporary registers. */ -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0); +SLJIT_ASSERT(common->locals_size >= 2 * (int)sizeof(sljit_sw)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, TMP3, 0); /* Prepare function arguments */ OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0); -GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCAL0); OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset); if (char1 == char2) @@ -910,8 +911,8 @@ else } } /* Restore registers. */ -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); -OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); +OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); /* Check return value. */ partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); @@ -1038,7 +1039,7 @@ SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); SLJIT_ASSERT(compiler->scratches == 5); /* Save temporary register STR_PTR. */ -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0); /* Prepare arguments for the function call. */ if (common->match_end_ptr == 0) @@ -1052,7 +1053,7 @@ else SELECT(SLJIT_LESS, SLJIT_R0, STR_END, 0, SLJIT_R0); } -GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCAL0); OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1); OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2); ic.c.c1 = char1a; @@ -1093,7 +1094,7 @@ if (diff == 1) { } /* Restore STR_PTR register. */ -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); /* Check return value. */ partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); diff --git a/ext/pcre/pcre2lib/pcre2_maketables.c b/ext/pcre/pcre2lib/pcre2_maketables.c index ac8b63b8097fb..0474cc7dbb41c 100644 --- a/ext/pcre/pcre2lib/pcre2_maketables.c +++ b/ext/pcre/pcre2lib/pcre2_maketables.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2020 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -155,10 +155,10 @@ return yield; PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables) { - if (gcontext) - gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data); - else - free((void *)tables); +if (gcontext != NULL) + gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data); +else + free((void *)tables); } #endif diff --git a/ext/pcre/pcre2lib/pcre2_match.c b/ext/pcre/pcre2lib/pcre2_match.c index 6c422c2e5ef9e..5adc03480522f 100644 --- a/ext/pcre/pcre2lib/pcre2_match.c +++ b/ext/pcre/pcre2lib/pcre2_match.c @@ -155,17 +155,17 @@ changed, the code at RETURN_SWITCH below must be updated in sync. */ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, - RM31, RM32, RM33, RM34, RM35, RM36, RM37 }; + RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39 }; #ifdef SUPPORT_WIDE_CHARS -enum { RM100=100, RM101 }; +enum { RM100=100, RM101, RM102, RM103 }; #endif #ifdef SUPPORT_UNICODE enum { RM200=200, RM201, RM202, RM203, RM204, RM205, RM206, RM207, RM208, RM209, RM210, RM211, RM212, RM213, RM214, RM215, RM216, RM217, RM218, RM219, RM220, RM221, RM222, RM223, - RM224, RM225 }; + RM224 }; #endif /* Define short names for general fields in the current backtrack frame, which @@ -348,6 +348,7 @@ seems unlikely.) Arguments: offset index into the offset vector caseless TRUE if caseless + caseopts bitmask of REFI_FLAG_XYZ values F the current backtracking frame pointer mb points to match block lengthptr pointer for returning the length matched @@ -358,8 +359,8 @@ Returns: = 0 sucessful match; number of code units matched is set */ static int -match_ref(PCRE2_SIZE offset, BOOL caseless, heapframe *F, match_block *mb, - PCRE2_SIZE *lengthptr) +match_ref(PCRE2_SIZE offset, BOOL caseless, int caseopts, heapframe *F, + match_block *mb, PCRE2_SIZE *lengthptr) { PCRE2_SPTR p; PCRE2_SIZE length; @@ -389,6 +390,8 @@ if (caseless) { #if defined SUPPORT_UNICODE BOOL utf = (mb->poptions & PCRE2_UTF) != 0; + BOOL caseless_restrict = (caseopts & REFI_FLAG_CASELESS_RESTRICT) != 0; + BOOL turkish_casing = !caseless_restrict && (caseopts & REFI_FLAG_TURKISH_CASING) != 0; if (utf || (mb->poptions & PCRE2_UCP) != 0) { @@ -420,10 +423,20 @@ if (caseless) d = *p++; } - ur = GET_UCD(d); - if (c != d && c != (uint32_t)((int)d + ur->other_case)) + if (turkish_casing && UCD_ANY_I(d)) + { + c = UCD_FOLD_I_TURKISH(c); + d = UCD_FOLD_I_TURKISH(d); + if (c != d) return -1; /* No match */ + } + else if (c != d && c != (uint32_t)((int)d + (ur = GET_UCD(d))->other_case)) { const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset; + + /* When PCRE2_EXTRA_CASELESS_RESTRICT is set, ignore any caseless sets + that start with an ASCII character. */ + if (caseless_restrict && *pp < 128) return -1; /* No match */ + for (;;) { if (c < *pp) return -1; /* No match */ @@ -528,38 +541,46 @@ For hard partial matching, we immediately return a partial match. Otherwise, carrying on means that a complete match on the current subject will be sought. A partial match is returned only if no complete match can be found. */ -#define CHECK_PARTIAL()\ - if (Feptr >= mb->end_subject) \ - { \ - SCHECK_PARTIAL(); \ - } - -#define SCHECK_PARTIAL()\ - if (mb->partial != 0 && \ - (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \ - { \ - mb->hitend = TRUE; \ - if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \ - } +#define CHECK_PARTIAL() \ + do { \ + if (Feptr >= mb->end_subject) \ + { \ + SCHECK_PARTIAL(); \ + } \ + } \ + while (0) + +#define SCHECK_PARTIAL() \ + do { \ + if (mb->partial != 0 && \ + (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \ + { \ + mb->hitend = TRUE; \ + if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \ + } \ + } \ + while (0) /* These macros are used to implement backtracking. They simulate a recursive call to the match() function by means of a local vector of frames which remember the backtracking points. */ -#define RMATCH(ra,rb)\ - {\ - start_ecode = ra;\ - Freturn_id = rb;\ - goto MATCH_RECURSE;\ - L_##rb:;\ - } +#define RMATCH(ra,rb) \ + do { \ + start_ecode = ra; \ + Freturn_id = rb; \ + goto MATCH_RECURSE; \ + L_##rb:; \ + } \ + while (0) -#define RRETURN(ra)\ - {\ - rrc = ra;\ - goto RETURN_SWITCH;\ - } +#define RRETURN(ra) \ + do { \ + rrc = ra; \ + goto RETURN_SWITCH; \ + } \ + while (0) @@ -813,7 +834,10 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, offset = Flast_group_offset; for(;;) { + /* Corrupted heapframes?. Trigger an assert and return an error */ + PCRE2_ASSERT(offset != PCRE2_UNSET); if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; + N = (heapframe *)((char *)match_data->heapframes + offset); P = (heapframe *)((char *)N - frame_size); if (N->group_frame_type == (GF_CAPTURE | number)) break; @@ -852,7 +876,10 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, offset = Flast_group_offset; for(;;) { + /* Corrupted heapframes?. Trigger an assert and return an error */ + PCRE2_ASSERT(offset != PCRE2_UNSET); if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; + N = (heapframe *)((char *)match_data->heapframes + offset); P = (heapframe *)((char *)N - frame_size); if (GF_IDMASK(N->group_frame_type) == GF_RECURSE) break; @@ -1329,7 +1356,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } else /* Maximize */ @@ -1430,7 +1457,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH); Feptr++; } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } else /* Maximize */ @@ -1488,7 +1515,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } else /* Maximize */ { @@ -1706,7 +1733,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Feptr++; } } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } /* Maximize case */ @@ -1844,7 +1871,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH); } } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } /* Maximize case */ @@ -1928,7 +1955,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #define Lmax F->temp_32[1] #define Lstart_eptr F->temp_sptr[0] #define Lbyte_map_address F->temp_sptr[1] -#define Lbyte_map ((unsigned char *)Lbyte_map_address) +#define Lbyte_map ((const unsigned char *)Lbyte_map_address) case OP_NCLASS: case OP_CLASS: @@ -2071,7 +2098,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); } } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } /* If maximizing, find the longest possible run, then work backwards. */ @@ -2151,7 +2178,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } } - /* Control never gets here */ + + PCRE2_UNREACHABLE(); /* Control never reaches here */ #undef Lbyte_map_address #undef Lbyte_map @@ -2219,7 +2247,9 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(fc, Lxclass_data, + (const uint8_t*)mb->start_code, utf)) + RRETURN(MATCH_NOMATCH); } /* If Lmax == Lmin we can just continue with the main loop. */ @@ -2242,9 +2272,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(fc, Lxclass_data, + (const uint8_t*)mb->start_code, utf)) + RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } /* If maximizing, find the longest possible run, then work backwards. */ @@ -2265,7 +2297,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #else fc = *Feptr; #endif - if (!PRIV(xclass)(fc, Lxclass_data, utf)) break; + if (!PRIV(xclass)(fc, Lxclass_data, + (const uint8_t*)mb->start_code, utf)) break; Feptr += len; } @@ -2287,7 +2320,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ } #endif /* SUPPORT_WIDE_CHARS: end of XCLASS */ @@ -2297,6 +2330,151 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #undef Lmax + /* ===================================================================== */ + /* Match a complex, set-based character class. This opcodes are used when + there is complex nesting or logical operations within the character + class. */ + +#define Lstart_eptr F->temp_sptr[0] +#define Leclass_data F->temp_sptr[1] +#define Leclass_len F->temp_size +#define Lmin F->temp_32[0] +#define Lmax F->temp_32[1] + +#ifdef SUPPORT_WIDE_CHARS + case OP_ECLASS: + { + Leclass_data = Fecode + 1 + LINK_SIZE; /* Save for matching */ + Fecode += GET(Fecode, 1); /* Advance past the item */ + Leclass_len = (PCRE2_SIZE)(Fecode - Leclass_data); + + switch (*Fecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + case OP_CRPOSQUERY: + fc = *Fecode++ - OP_CRSTAR; + Lmin = rep_min[fc]; + Lmax = rep_max[fc]; + reptype = rep_typ[fc]; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + Lmin = GET2(Fecode, 1); + Lmax = GET2(Fecode, 1 + IMM2_SIZE); + if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */ + reptype = rep_typ[*Fecode - OP_CRSTAR]; + Fecode += 1 + 2 * IMM2_SIZE; + break; + + default: /* No repeat follows */ + Lmin = Lmax = 1; + break; + } + + /* First, ensure the minimum number of matches are present. */ + + for (i = 1; i <= Lmin; i++) + { + if (Feptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(fc, Feptr); + if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len, + (const uint8_t*)mb->start_code, utf)) + RRETURN(MATCH_NOMATCH); + } + + /* If Lmax == Lmin we can just continue with the main loop. */ + + if (Lmin == Lmax) continue; + + /* If minimizing, keep testing the rest of the expression and advancing + the pointer while it matches the class. */ + + if (reptype == REPTYPE_MIN) + { + for (;;) + { + RMATCH(Fecode, RM102); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); + if (Feptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(fc, Feptr); + if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len, + (const uint8_t*)mb->start_code, utf)) + RRETURN(MATCH_NOMATCH); + } + PCRE2_UNREACHABLE(); /* Control never reaches here */ + } + + /* If maximizing, find the longest possible run, then work backwards. */ + + else + { + Lstart_eptr = Feptr; + for (i = Lmin; i < Lmax; i++) + { + int len = 1; + if (Feptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } +#ifdef SUPPORT_UNICODE + GETCHARLENTEST(fc, Feptr, len); +#else + fc = *Feptr; +#endif + if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len, + (const uint8_t*)mb->start_code, utf)) + break; + Feptr += len; + } + + if (reptype == REPTYPE_POS) continue; /* No backtracking */ + + /* After \C in UTF mode, Lstart_eptr might be in the middle of a + Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't + go too far. */ + + for(;;) + { + RMATCH(Fecode, RM103); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */ +#ifdef SUPPORT_UNICODE + if (utf) BACKCHAR(Feptr); +#endif + } + RRETURN(MATCH_NOMATCH); + } + + PCRE2_UNREACHABLE(); /* Control never reaches here */ + } +#endif /* SUPPORT_WIDE_CHARS: end of ECLASS */ + +#undef Lstart_eptr +#undef Leclass_data +#undef Leclass_len +#undef Lmin +#undef Lmax + + /* ===================================================================== */ /* Match various character types when PCRE2_UCP is not set. These opcodes are not generated when PCRE2_UCP is set - instead appropriate property @@ -2492,10 +2670,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, switch(Fecode[1]) { - case PT_ANY: - if (notmatch) RRETURN(MATCH_NOMATCH); - break; - case PT_LAMP: chartype = prop->chartype; if ((chartype == ucp_Lu || @@ -2606,6 +2780,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, /* This should never occur */ default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -2728,19 +2903,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, BOOL notmatch = Lctype == OP_NOTPROP; switch(proptype) { - case PT_ANY: - if (notmatch) RRETURN(MATCH_NOMATCH); - for (i = 1; i <= Lmin; i++) - { - if (Feptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(fc, Feptr); - } - break; - case PT_LAMP: for (i = 1; i <= Lmin; i++) { @@ -2969,6 +3131,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, /* This should not occur */ default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -3244,6 +3407,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } /* End switch(Lctype) */ @@ -3496,6 +3660,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -3516,27 +3681,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, { switch(proptype) { - case PT_ANY: - for (;;) - { - RMATCH(Fecode, RM208); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); - if (Feptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(fc, Feptr); - if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH); - } - /* Control never gets here */ - case PT_LAMP: for (;;) { int chartype; - RMATCH(Fecode, RM209); + RMATCH(Fecode, RM208); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3551,12 +3700,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, chartype == ucp_Lt) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_GC: for (;;) { - RMATCH(Fecode, RM210); + RMATCH(Fecode, RM209); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3568,12 +3717,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_PC: for (;;) { - RMATCH(Fecode, RM211); + RMATCH(Fecode, RM210); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3585,12 +3734,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_SC: for (;;) { - RMATCH(Fecode, RM212); + RMATCH(Fecode, RM211); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3602,14 +3751,14 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_SCX: for (;;) { BOOL ok; const ucd_record *prop; - RMATCH(Fecode, RM225); + RMATCH(Fecode, RM224); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3624,13 +3773,13 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (ok == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_ALNUM: for (;;) { int category; - RMATCH(Fecode, RM213); + RMATCH(Fecode, RM212); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3643,7 +3792,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((category == ucp_L || category == ucp_N) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ /* Perl space used to exclude VT, but from Perl 5.18 it is included, which means that Perl space and POSIX space are now identical. PCRE @@ -3653,7 +3802,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case PT_PXSPACE: /* POSIX space */ for (;;) { - RMATCH(Fecode, RM214); + RMATCH(Fecode, RM213); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3675,13 +3824,13 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; } } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_WORD: for (;;) { int chartype, category; - RMATCH(Fecode, RM215); + RMATCH(Fecode, RM214); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3698,13 +3847,13 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, chartype == ucp_Pc) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_CLIST: for (;;) { const uint32_t *cp; - RMATCH(Fecode, RM216); + RMATCH(Fecode, RM215); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3735,12 +3884,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } } } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_UCNC: for (;;) { - RMATCH(Fecode, RM217); + RMATCH(Fecode, RM216); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3754,12 +3903,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, fc >= 0xe000) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_BIDICL: for (;;) { - RMATCH(Fecode, RM224); + RMATCH(Fecode, RM223); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3771,14 +3920,14 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_BIDICLASS(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ case PT_BOOL: for (;;) { BOOL ok; const ucd_record *prop; - RMATCH(Fecode, RM223); + RMATCH(Fecode, RM222); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3793,10 +3942,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (ok == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ /* This should never occur */ default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -3808,7 +3958,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, { for (;;) { - RMATCH(Fecode, RM218); + RMATCH(Fecode, RM217); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3835,7 +3985,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, { for (;;) { - RMATCH(Fecode, RM219); + RMATCH(Fecode, RM218); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3951,6 +4101,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -4095,11 +4246,13 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } } - /* Control never gets here */ + + PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ } /* If maximizing, it is worth using inline code for speed, doing the type @@ -4117,21 +4270,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, BOOL notmatch = Lctype == OP_NOTPROP; switch(proptype) { - case PT_ANY: - for (i = Lmin; i < Lmax; i++) - { - int len = 1; - if (Feptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(fc, Feptr, len); - if (notmatch) break; - Feptr+= len; - } - break; - case PT_LAMP: for (i = Lmin; i < Lmax; i++) { @@ -4377,6 +4515,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -4391,7 +4530,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for(;;) { if (Feptr <= Lstart_eptr) break; - RMATCH(Fecode, RM222); + RMATCH(Fecode, RM221); if (rrc != MATCH_NOMATCH) RRETURN(rrc); Feptr--; if (utf) BACKCHAR(Feptr); @@ -4434,7 +4573,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, PCRE2_SPTR fptr; if (Feptr <= Lstart_eptr) break; /* At start of char run */ - RMATCH(Fecode, RM220); + RMATCH(Fecode, RM219); if (rrc != MATCH_NOMATCH) RRETURN(rrc); /* Backtracking over an extended grapheme cluster involves inspecting @@ -4695,6 +4834,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -4707,7 +4847,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for(;;) { if (Feptr <= Lstart_eptr) break; - RMATCH(Fecode, RM221); + RMATCH(Fecode, RM220); if (rrc != MATCH_NOMATCH) RRETURN(rrc); Feptr--; BACKCHAR(Feptr); @@ -4952,6 +5092,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -4988,16 +5129,18 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #define Lmin F->temp_32[0] #define Lmax F->temp_32[1] #define Lcaseless F->temp_32[2] +#define Lcaseopts F->temp_32[3] #define Lstart F->temp_sptr[0] #define Loffset F->temp_size case OP_DNREF: case OP_DNREFI: Lcaseless = (Fop == OP_DNREFI); + Lcaseopts = (Fop == OP_DNREFI)? Fecode[1 + 2*IMM2_SIZE] : 0; { int count = GET2(Fecode, 1+IMM2_SIZE); PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size; - Fecode += 1 + 2*IMM2_SIZE; + Fecode += 1 + 2*IMM2_SIZE + (Fop == OP_DNREFI? 1 : 0); while (count-- > 0) { @@ -5011,8 +5154,9 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_REF: case OP_REFI: Lcaseless = (Fop == OP_REFI); + Lcaseopts = (Fop == OP_REFI)? Fecode[1 + IMM2_SIZE] : 0; Loffset = (GET2(Fecode, 1) << 1) - 2; - Fecode += 1 + IMM2_SIZE; + Fecode += 1 + IMM2_SIZE + (Fop == OP_REFI? 1 : 0); /* Set up for repetition, or handle the non-repeated case. The maximum and minimum must be in the heap frame, but as they are short-term values, we @@ -5044,7 +5188,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, default: /* No repeat follows */ { - rrc = match_ref(Loffset, Lcaseless, F, mb, &length); + rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &length); if (rrc != 0) { if (rrc > 0) Feptr = mb->end_subject; /* Partial match */ @@ -5078,7 +5222,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for (i = 1; i <= Lmin; i++) { PCRE2_SIZE slength; - rrc = match_ref(Loffset, Lcaseless, F, mb, &slength); + rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); if (rrc != 0) { if (rrc > 0) Feptr = mb->end_subject; /* Partial match */ @@ -5102,7 +5246,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RMATCH(Fecode, RM20); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); - rrc = match_ref(Loffset, Lcaseless, F, mb, &slength); + rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); if (rrc != 0) { if (rrc > 0) Feptr = mb->end_subject; /* Partial match */ @@ -5111,7 +5255,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } Feptr += slength; } - /* Control never gets here */ + + PCRE2_UNREACHABLE(); /* Control never reaches here */ } /* If maximizing, find the longest string and work backwards, as long as @@ -5126,7 +5271,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for (i = Lmin; i < Lmax; i++) { PCRE2_SIZE slength; - rrc = match_ref(Loffset, Lcaseless, F, mb, &slength); + rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); if (rrc != 0) { /* Can't use CHECK_PARTIAL because we don't want to update Feptr in @@ -5177,7 +5322,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for (i = Lmin; i < Lmax; i++) { PCRE2_SIZE slength; - (void)match_ref(Loffset, Lcaseless, F, mb, &slength); + (void)match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); Feptr += slength; } } @@ -5185,7 +5330,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + + PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ #undef Lcaseless #undef Lmin @@ -5409,7 +5555,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += GET(Fecode, 1); if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH); } - /* Control never reaches here. */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ #undef Lframe_type @@ -5494,7 +5640,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Lstart_branch = next_ecode; if (*Lstart_branch != OP_ALT) RRETURN(MATCH_NOMATCH); } - /* Control never reaches here. */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ #undef Lframe_type #undef Lstart_branch @@ -5585,6 +5731,132 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #undef Lframe_type + /* ===================================================================== */ + /* Handle scan substring operation. */ + +#define Lframe_type F->temp_32[0] +#define Lextra_size F->temp_32[1] +#define Lsaved_moptions F->temp_32[2] +#define Lsaved_end_subject F->temp_sptr[0] +#define Lsaved_eptr F->temp_sptr[1] +#define Ltrue_end_extra F->temp_size + + case OP_ASSERT_SCS: + { + PCRE2_SPTR ecode = Fecode + 1 + LINK_SIZE; + uint32_t extra_size = 0; + int count; + PCRE2_SPTR slot; + + /* Disable compiler warning. */ + offset = 0; + (void)offset; + + for (;;) + { + if (*ecode == OP_CREF) + { + extra_size += 1+IMM2_SIZE; + offset = (GET2(ecode, 1) << 1) - 2; + ecode += 1+IMM2_SIZE; + if (offset < Foffset_top && Fovector[offset] != PCRE2_UNSET) + goto SCS_OFFSET_FOUND; + continue; + } + + if (*ecode != OP_DNCREF) RRETURN(MATCH_NOMATCH); + + count = GET2(ecode, 1 + IMM2_SIZE); + slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; + extra_size += 1+2*IMM2_SIZE; + ecode += 1+2*IMM2_SIZE; + + while (count > 0) + { + offset = (GET2(slot, 0) << 1) - 2; + if (offset < Foffset_top && Fovector[offset] != PCRE2_UNSET) + goto SCS_OFFSET_FOUND; + slot += mb->name_entry_size; + count--; + } + } + + SCS_OFFSET_FOUND: + + /* Skip remaining options. */ + for (;;) + { + if (*ecode == OP_CREF) + { + extra_size += 1+IMM2_SIZE; + ecode += 1+IMM2_SIZE; + } + else if (*ecode == OP_DNCREF) + { + extra_size += 1+2*IMM2_SIZE; + ecode += 1+2*IMM2_SIZE; + } + else break; + } + + Lextra_size = extra_size; + } + + Lsaved_end_subject = mb->end_subject; + Ltrue_end_extra = mb->true_end_subject - mb->end_subject; + Lsaved_eptr = Feptr; + Lsaved_moptions = mb->moptions; + + Feptr = mb->start_subject + Fovector[offset]; + mb->true_end_subject = mb->end_subject = + mb->start_subject + Fovector[offset + 1]; + mb->moptions &= ~PCRE2_NOTEOL; + + Lframe_type = GF_NOCAPTURE | Fop; + for (;;) + { + group_frame_type = Lframe_type; + RMATCH(Fecode + 1 + LINK_SIZE + Lextra_size, RM38); + if (rrc == MATCH_ACCEPT) + { + memcpy(Fovector, + (char *)assert_accept_frame + offsetof(heapframe, ovector), + assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); + Foffset_top = assert_accept_frame->offset_top; + Fmark = assert_accept_frame->mark; + break; + } + + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) + { + mb->end_subject = Lsaved_end_subject; + mb->true_end_subject = mb->end_subject + Ltrue_end_extra; + mb->moptions = Lsaved_moptions; + RRETURN(rrc); + } + + Fecode += GET(Fecode, 1); + if (*Fecode != OP_ALT) + { + mb->end_subject = Lsaved_end_subject; + mb->true_end_subject = mb->end_subject + Ltrue_end_extra; + mb->moptions = Lsaved_moptions; + RRETURN(MATCH_NOMATCH); + } + Lextra_size = 0; + } + + do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT); + Fecode += 1 + LINK_SIZE; + Feptr = Lsaved_eptr; + break; + +#undef Lframe_type +#undef Lextra_size +#undef Lsaved_end_subject +#undef Lsaved_eptr +#undef Ltrue_end_extra +#undef Lsave_moptions /* ===================================================================== */ /* The callout item calls an external function, if one is provided, passing @@ -5795,8 +6067,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #ifdef SUPPORT_UNICODE if (utf) { - while (number-- > 0) + /* We used to do a simpler `while (number-- > 0)` but that triggers + clang's unsigned integer overflow sanitizer. */ + while (number > 0) { + --number; if (Feptr <= mb->check_subject) RRETURN(MATCH_NOMATCH); Feptr--; BACKCHAR(Feptr); @@ -5869,7 +6144,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } /* Now try matching, moving forward one character on failure, until we - reach the mimimum back length. */ + reach the minimum back length. */ for (;;) { @@ -5881,7 +6156,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (utf) { FORWARDCHARTEST(Feptr, mb->end_subject); } #endif } - /* Control never reaches here */ + PCRE2_UNREACHABLE(); /* Control never reaches here */ #undef Lmin #undef Lmax @@ -5931,14 +6206,20 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, (char *)P->eptr - (char *)mb->start_subject); #endif - /* If we are at the end of an assertion that is a condition, return a - match, discarding any intermediate backtracking points. Copy back the - mark setting and the captures into the frame before N so that they are - set on return. Doing this for all assertions, both positive and negative, - seems to match what Perl does. */ + /* If we are at the end of an assertion that is a condition, first check + to see if we are at the end of a variable-length branch in a lookbehind. + If this is the case and we have not landed on the current character, + return no match. Compare code below for non-condition lookbehinds. In + other cases, return a match, discarding any intermediate backtracking + points. Copy back the mark setting and the captures into the frame before + N so that they are set on return. Doing this for all assertions, both + positive and negative, seems to match what Perl does. */ if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT) { + if ((*bracode == OP_ASSERTBACK || *bracode == OP_ASSERTBACK_NOT) && + branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) + RRETURN(MATCH_NOMATCH); memcpy((char *)P + offsetof(heapframe, ovector), Fovector, Foffset_top * sizeof(PCRE2_SIZE)); P->offset_top = Foffset_top; @@ -5967,7 +6248,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, /* It is the end of whole-pattern recursion. */ offset = Flast_group_offset; + + /* Corrupted heapframes?. Trigger an assert and return an error */ + PCRE2_ASSERT(offset != PCRE2_UNSET); if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; + N = (heapframe *)((char *)match_data->heapframes + offset); P = (heapframe *)((char *)N - frame_size); Flast_group_offset = P->last_group_offset; @@ -6042,6 +6327,23 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); + /* A scan substring group must preserve the current end_subject, + and restore it before the backtracking is performed into its sub + pattern. */ + + case OP_ASSERT_SCS: + F->temp_sptr[0] = mb->end_subject; + mb->end_subject = P->temp_sptr[0]; + mb->true_end_subject = mb->end_subject + P->temp_size; + Feptr = P->temp_sptr[1]; + + RMATCH(Fecode + 1 + LINK_SIZE, RM39); + + mb->end_subject = F->temp_sptr[0]; + mb->true_end_subject = mb->end_subject; + RRETURN(rrc); + break; + /* At the end of a script run, apply the script-checking rules. This code will never by exercised if Unicode support it not compiled, because in that environment script runs cause an error at compile time. */ @@ -6165,8 +6467,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_EODN: ASSERT_NL_OR_EOS: - if (Feptr < mb->end_subject && - (!IS_NEWLINE(Feptr) || Feptr != mb->end_subject - mb->nllen)) + if (Feptr < mb->true_end_subject && + (!IS_NEWLINE(Feptr) || Feptr != mb->true_end_subject - mb->nllen)) { if (mb->partial != 0 && Feptr + 1 >= mb->end_subject && @@ -6447,6 +6749,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, something seriously wrong in the code above or the OP_xxx definitions. */ default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -6455,8 +6758,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, loop. */ } /* End of main loop */ -/* Control never reaches here */ +PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ /* ========================================================================= */ /* The RRETURN() macro jumps here. The number that is saved in Freturn_id @@ -6482,20 +6785,21 @@ switch (Freturn_id) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16) LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24) LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32) - LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) + LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) LBL(38) LBL(39) #ifdef SUPPORT_WIDE_CHARS - LBL(100) LBL(101) + LBL(100) LBL(101) LBL(102) LBL(103) #endif #ifdef SUPPORT_UNICODE LBL(200) LBL(201) LBL(202) LBL(203) LBL(204) LBL(205) LBL(206) LBL(207) LBL(208) LBL(209) LBL(210) LBL(211) LBL(212) LBL(213) LBL(214) LBL(215) LBL(216) LBL(217) LBL(218) LBL(219) LBL(220) - LBL(221) LBL(222) LBL(223) LBL(224) LBL(225) + LBL(221) LBL(222) LBL(223) LBL(224) #endif default: + PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } #undef LBL @@ -6621,7 +6925,7 @@ if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) /* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the options variable for this function. Users of PCRE2 who are not calling the function directly would like to have a way of setting these flags, in the same -way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with +way that they can set pcre2_compile() flags like PCRE2_NO_AUTO_POSSESS with constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and (*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which we now transfer to the options for this function. The bits are guaranteed to be @@ -6703,9 +7007,6 @@ if (use_jit) #ifdef SUPPORT_UNICODE if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid) { -#if PCRE2_CODE_UNIT_WIDTH != 32 - unsigned int i; -#endif /* For 8-bit and 16-bit UTF, check that the first code unit is a valid character start. */ @@ -6726,7 +7027,7 @@ if (use_jit) start of matching. */ #if PCRE2_CODE_UNIT_WIDTH != 32 - for (i = re->max_lookbehind; i > 0 && start_match > subject; i--) + for (unsigned int i = re->max_lookbehind; i > 0 && start_match > subject; i--) { start_match--; while (start_match > subject && @@ -6973,10 +7274,10 @@ mb->mark = mb->nomatch_mark = NULL; /* In case never set */ /* The name table is needed for finding all the numbers associated with a given name, for condition testing. The code follows the name table. */ -mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)); +mb->name_table = (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code)); mb->name_count = re->name_count; mb->name_entry_size = re->name_entry_size; -mb->start_code = mb->name_table + re->name_count * re->name_entry_size; +mb->start_code = (PCRE2_SPTR)((const uint8_t *)re + re->code_start); /* Process the \R and newline settings. */ @@ -7013,7 +7314,9 @@ switch(re->newline_convention) mb->nltype = NLTYPE_ANYCRLF; break; - default: return PCRE2_ERROR_INTERNAL; + default: + PCRE2_DEBUG_UNREACHABLE(); + return PCRE2_ERROR_INTERNAL; } /* The backtracking frames have fixed data at the front, and a PCRE2_SIZE @@ -7159,7 +7462,7 @@ for(;;) However, there is an option (settable at compile time) that disables these, for testing and for ensuring that all callouts do actually occur. */ - if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) + if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) { /* If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. That is, the match must be before or at the diff --git a/ext/pcre/pcre2lib/pcre2_match_data.c b/ext/pcre/pcre2lib/pcre2_match_data.c index 757dab9df51d3..100e7c9d944cf 100644 --- a/ext/pcre/pcre2lib/pcre2_match_data.c +++ b/ext/pcre/pcre2lib/pcre2_match_data.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -77,14 +77,16 @@ return yield; * Create a match data block using pattern data * *************************************************/ -/* If no context is supplied, use the memory allocator from the code. */ +/* If no context is supplied, use the memory allocator from the code. This code +assumes that a general context contains nothing other than a memory allocator. +If that ever changes, this code will need fixing. */ PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION pcre2_match_data_create_from_pattern(const pcre2_code *code, pcre2_general_context *gcontext) { if (gcontext == NULL) gcontext = (pcre2_general_context *)code; -return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1, +return pcre2_match_data_create(((const pcre2_real_code *)code)->top_bracket + 1, gcontext); } diff --git a/ext/pcre/pcre2lib/pcre2_ord2utf.c b/ext/pcre/pcre2lib/pcre2_ord2utf.c index 1403730996d6b..a1e9e08803bc0 100644 --- a/ext/pcre/pcre2lib/pcre2_ord2utf.c +++ b/ext/pcre/pcre2lib/pcre2_ord2utf.c @@ -117,4 +117,4 @@ return 1; } #endif /* SUPPORT_UNICODE */ -/* End of pcre_ord2utf.c */ +/* End of pcre2_ord2utf.c */ diff --git a/ext/pcre/pcre2lib/pcre2_pattern_info.c b/ext/pcre/pcre2lib/pcre2_pattern_info.c index a29f5eff673be..fe4d3c661a01c 100644 --- a/ext/pcre/pcre2lib/pcre2_pattern_info.c +++ b/ext/pcre/pcre2lib/pcre2_pattern_info.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ Returns: 0 when data returned PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where) { -const pcre2_real_code *re = (pcre2_real_code *)code; +const pcre2_real_code *re = (const pcre2_real_code *)code; if (where == NULL) /* Requests field length */ { @@ -230,7 +230,8 @@ switch(what) break; case PCRE2_INFO_NAMETABLE: - *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((char *)re + sizeof(pcre2_real_code)); + *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((const char *)re + + sizeof(pcre2_real_code)); break; case PCRE2_INFO_NEWLINE: @@ -268,7 +269,7 @@ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_callout_enumerate(const pcre2_code *code, int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data) { -pcre2_real_code *re = (pcre2_real_code *)code; +const pcre2_real_code *re = (const pcre2_real_code *)code; pcre2_callout_enumerate_block cb; PCRE2_SPTR cc; #ifdef SUPPORT_UNICODE @@ -291,7 +292,7 @@ if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE; cb.version = 0; -cc = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) +cc = (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code)) + re->name_count * re->name_entry_size; while (TRUE) @@ -383,8 +384,9 @@ while (TRUE) #endif break; -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 +#ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: + case OP_ECLASS: cc += GET(cc, 1); break; #endif diff --git a/ext/pcre/pcre2lib/pcre2_printint.c b/ext/pcre/pcre2lib/pcre2_printint.c index 870e283b74565..84f84f82f733c 100644 --- a/ext/pcre/pcre2lib/pcre2_printint.c +++ b/ext/pcre/pcre2lib/pcre2_printint.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2023 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -53,6 +53,7 @@ pcre2_internal.h, which is #included by pcre2test before this file. */ #ifndef OP_LISTS_DEFINED static const char *OP_names[] = { OP_NAME_LIST }; +STATIC_ASSERT(sizeof(OP_names)/sizeof(*OP_names) == OP_TABLE_LENGTH, OP_names); #define OP_LISTS_DEFINED #endif @@ -65,13 +66,17 @@ static const char *OP_names[] = { OP_NAME_LIST }; #define print_custring PCRE2_SUFFIX(print_custring_) #define print_custring_bylen PCRE2_SUFFIX(print_custring_bylen_) #define print_prop PCRE2_SUFFIX(print_prop_) +#define print_char_list PCRE2_SUFFIX(print_char_list_) +#define print_map PCRE2_SUFFIX(print_map_) +#define print_class PCRE2_SUFFIX(print_class_) /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that the definition is next to the definition of the opcodes in pcre2_internal.h. The contents of the table are, however, mode-dependent. */ static const uint8_t OP_lengths[] = { OP_LENGTHS }; - +STATIC_ASSERT(sizeof(OP_lengths)/sizeof(*OP_lengths) == OP_TABLE_LENGTH, + PCRE2_SUFFIX(OP_lengths_)); /************************************************* @@ -245,7 +250,7 @@ const char *yield = "??"; size_t len = 0; unsigned int ptypex = (ptype == PT_SC)? PT_SCX : ptype; -for (int i = PRIV(utt_size) - 1; i >= 0; i--) +for (ptrdiff_t i = PRIV(utt_size) - 1; i >= 0; i--) { const ucp_type_table *u = PRIV(utt) + i; @@ -318,6 +323,298 @@ else +/************************************************* +* Print character list * +*************************************************/ + +/* Prints the characters and character ranges in a character list. + +Arguments: + f file to write to + code pointer in the compiled code +*/ + +static PCRE2_SPTR +print_char_list(FILE *f, PCRE2_SPTR code, const uint8_t *char_lists_end) +{ +uint32_t type, list_ind; +uint32_t char_list_add = XCL_CHAR_LIST_LOW_16_ADD; +uint32_t range_start = ~(uint32_t)0, range_end = 0; +const uint8_t *next_char; + +#if PCRE2_CODE_UNIT_WIDTH == 8 +type = (uint32_t)(code[0] << 8) | code[1]; +code += 2; +#else +type = code[0]; +code++; +#endif /* CODE_UNIT_WIDTH */ + +/* Align characters. */ +next_char = char_lists_end - (GET(code, 0) << 1); +type &= XCL_TYPE_MASK; +list_ind = 0; + +if ((type & XCL_BEGIN_WITH_RANGE) != 0) + range_start = XCL_CHAR_LIST_LOW_16_START; + +while (type > 0) + { + uint32_t item_count = type & XCL_ITEM_COUNT_MASK; + + if (item_count == XCL_ITEM_COUNT_MASK) + { + if (list_ind <= 1) + { + item_count = *(const uint16_t*)next_char; + next_char += 2; + } + else + { + item_count = *(const uint32_t*)next_char; + next_char += 4; + } + } + + while (item_count > 0) + { + if (list_ind <= 1) + { + range_end = *(const uint16_t*)next_char; + next_char += 2; + } + else + { + range_end = *(const uint32_t*)next_char; + next_char += 4; + } + + if ((range_end & XCL_CHAR_END) != 0) + { + range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT); + + if (range_start < range_end) + fprintf(f, "\\x{%x}-", range_start); + + fprintf(f, "\\x{%x}", range_end); + range_start = ~(uint32_t)0; + } + else + range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT); + + item_count--; + } + + list_ind++; + type >>= XCL_TYPE_BIT_LEN; + + /* The following code could be optimized to 8/16/32 bit, + but it is not worth it for a debugging function. */ + + if (range_start == ~(uint32_t)0) + { + if ((type & XCL_BEGIN_WITH_RANGE) != 0) + { + if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START; + else if (list_ind == 2) range_start = XCL_CHAR_LIST_LOW_32_START; + else range_start = XCL_CHAR_LIST_HIGH_32_START; + } + } + else if ((type & XCL_BEGIN_WITH_RANGE) == 0) + { + fprintf(f, "\\x{%x}-", range_start); + + if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END; + else if (list_ind == 2) range_end = XCL_CHAR_LIST_HIGH_16_END; + else if (list_ind == 3) range_end = XCL_CHAR_LIST_LOW_32_END; + else range_end = XCL_CHAR_LIST_HIGH_32_END; + + fprintf(f, "\\x{%x}", range_end); + range_start = ~(uint32_t)0; + } + + if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; + else if (list_ind == 2) char_list_add = XCL_CHAR_LIST_LOW_32_ADD; + else char_list_add = XCL_CHAR_LIST_HIGH_32_ADD; + } + +return code + LINK_SIZE; +} + + + +/************************************************* +* Print a character bitmap * +*************************************************/ + +/* Prints a 32-byte bitmap, which occurs within a character class opcode. + +Arguments: + f file to write to + map pointer to the bitmap + negated TRUE if the bitmap will be printed as negated + +Returns: nothing +*/ + +static void +print_map(FILE *f, const uint8_t *map, BOOL negated) +{ +BOOL first = TRUE; +uint8_t inverted_map[32]; +int i; + +if (negated) + { + /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ + for (i = 0; i < 32; i++) inverted_map[i] = 255 ^ map[i]; + map = inverted_map; + } + +for (i = 0; i < 256; i++) + { + if ((map[i/8] & (1u << (i&7))) != 0) + { + int j; + for (j = i+1; j < 256; j++) + if ((map[j/8] & (1u << (j&7))) == 0) break; + if (i == '-' || i == '\\' || i == ']' || (first && i == '^')) + fprintf(f, "\\"); + if (PRINTABLE(i)) fprintf(f, "%c", i); + else fprintf(f, "\\x%02x", i); + first = FALSE; + if (--j > i) + { + if (j != i + 1) fprintf(f, "-"); + if (j == '-' || j == '\\' || j == ']') fprintf(f, "\\"); + if (PRINTABLE(j)) fprintf(f, "%c", j); + else fprintf(f, "\\x%02x", j); + } + i = j; + } + } +} + + + +/************************************************* +* Print character class * +*************************************************/ + +/* Prints a character class, which must be either an OP_CLASS, OP_NCLASS, or +OP_XCLASS. + +Arguments: + f file to write to + type OP_CLASS, OP_NCLASS, or OP_XCLASS + code pointer in the compiled code (after the OP tag) + utf TRUE if re is UTF (will be FALSE if UTF is not supported) + before text to print before + after text to print after + +Returns: nothing +*/ + +static void +print_class(FILE *f, int type, PCRE2_SPTR code, const uint8_t *char_lists_end, + BOOL utf, const char *before, const char *after) +{ +BOOL printmap, negated; +PCRE2_SPTR ccode; + +/* Negative XCLASS and NCLASS both have a bitmap indicating which characters +are accepted. For clarity we print this inverted and prefixed by "^". */ +if (type == OP_XCLASS) + { + ccode = code + LINK_SIZE; + printmap = (*ccode & XCL_MAP) != 0; + negated = (*ccode & XCL_NOT) != 0; + ccode++; + } +else /* CLASS or NCLASS */ + { + printmap = TRUE; + negated = type == OP_NCLASS; + ccode = code; + } + +fprintf(f, "%s[%s", before, negated? "^" : ""); + +/* Print a bit map */ +if (printmap) + { + print_map(f, (const uint8_t *)ccode, negated); + ccode += 32 / sizeof(PCRE2_UCHAR); + } + +/* For an XCLASS there is always some additional data */ +if (type == OP_XCLASS) + { + PCRE2_UCHAR ch; + + while ((ch = *ccode++) != XCL_END) + { + const char *notch = ""; + + if (ch >= XCL_LIST) + { + ccode = print_char_list(f, ccode - 1, char_lists_end); + break; + } + + switch(ch) + { + case XCL_NOTPROP: + notch = "^"; + /* Fall through */ + case XCL_PROP: + { + unsigned int ptype = *ccode++; + unsigned int pvalue = *ccode++; + const char *s; + switch(ptype) + { + case PT_PXGRAPH: + fprintf(f, "[:%sgraph:]", notch); + break; + case PT_PXPRINT: + fprintf(f, "[:%sprint:]", notch); + break; + case PT_PXPUNCT: + fprintf(f, "[:%spunct:]", notch); + break; + case PT_PXXDIGIT: + fprintf(f, "[:%sxdigit:]", notch); + break; + default: + s = get_ucpname(ptype, pvalue); + fprintf(f, "\\%c{%c%s}", ((notch[0] == '^')? 'P':'p'), + toupper(s[0]), s+1); + break; + } + } + break; + + default: + ccode += 1 + print_char(f, ccode, utf); + if (ch == XCL_RANGE) + { + fprintf(f, "-"); + ccode += 1 + print_char(f, ccode, utf); + } + break; + } + } + + PCRE2_ASSERT(ccode == code + (GET(code, 0) - 1)); + } + +/* Indicate a non-UTF class which was created by negation */ +fprintf(f, "]%s", after); +} + + + /************************************************* * Print compiled pattern * *************************************************/ @@ -342,7 +639,7 @@ uint32_t nesize = re->name_entry_size; BOOL utf = (re->overall_options & PCRE2_UTF) != 0; nametable = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); -code = codestart = nametable + re->name_count * re->name_entry_size; +code = codestart = (PCRE2_SPTR)((uint8_t *)re + re->code_start); for(;;) { @@ -359,20 +656,6 @@ for(;;) switch(*code) { -/* ========================================================================== */ - /* These cases are never obeyed. This is a fudge that causes a compile- - time error if the vectors OP_names or OP_lengths, which are indexed - by opcode, are not the correct length. It seems to be the only way to do - such a check at compile time, as the sizeof() operator does not work in - the C preprocessor. */ - - case OP_TABLE_LENGTH: - case OP_TABLE_LENGTH + - ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) && - (sizeof(OP_lengths) == OP_TABLE_LENGTH)): - return; -/* ========================================================================== */ - case OP_END: fprintf(f, " %s\n", OP_names[*code]); fprintf(f, "------------------------------------------------------------------\n"); @@ -424,6 +707,7 @@ for(;;) case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_COND: @@ -457,7 +741,7 @@ for(;;) case OP_DNCREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; - fprintf(f, " %s Cond ref <", flag); + fprintf(f, " %s Capture ref <", flag); print_custring(f, entry); fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); } @@ -574,7 +858,7 @@ for(;;) case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); - fprintf(f, "]"); + fprintf(f, "] (not)"); break; case OP_NOTSTARI: @@ -600,7 +884,7 @@ for(;;) case OP_NOTPOSQUERY: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); - fprintf(f, "]%s", OP_names[*code]); + fprintf(f, "]%s (not)", OP_names[*code]); break; case OP_NOTEXACTI: @@ -622,6 +906,7 @@ for(;;) if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); else if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); + fprintf(f, " (not)"); break; case OP_RECURSE: @@ -632,14 +917,17 @@ for(;;) case OP_REFI: flag = "/i"; + extra = code[1 + IMM2_SIZE]; /* Fall through */ case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); + if (extra != 0) fprintf(f, " 0x%02x", extra); ccode = code + OP_lengths[*code]; goto CLASS_REF_REPEAT; case OP_DNREFI: flag = "/i"; + extra = code[1 + 2*IMM2_SIZE]; /* Fall through */ case OP_DNREF: { @@ -647,6 +935,7 @@ for(;;) fprintf(f, " %s \\k<", flag); print_custring(f, entry); fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); + if (extra != 0) fprintf(f, " 0x%02x", extra); } ccode = code + OP_lengths[*code]; goto CLASS_REF_REPEAT; @@ -676,141 +965,77 @@ for(;;) print_prop(f, code, " ", ""); break; - /* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm - in having this code always here, and it makes it less messy without all - those #ifdefs. */ - - case OP_CLASS: - case OP_NCLASS: - case OP_XCLASS: +#ifdef SUPPORT_WIDE_CHARS + case OP_ECLASS: + extra = GET(code, 1); + fprintf(f, " eclass[\n"); + /* We print the opcodes contained inside as well. */ + ccode = code + 1 + LINK_SIZE + 1; + if ((ccode[-1] & ECL_MAP) != 0) { - BOOL printmap, invertmap; - - fprintf(f, " ["); - - /* Negative XCLASS has an inverted map whereas the original opcodes have - already done the inversion. */ - - invertmap = FALSE; - if (*code == OP_XCLASS) - { - extra = GET(code, 1); - ccode = code + LINK_SIZE + 1; - printmap = (*ccode & XCL_MAP) != 0; - if ((*ccode & XCL_NOT) != 0) - { - invertmap = (*ccode & XCL_HASPROP) == 0; - fprintf(f, "^"); - } - ccode++; - } - else /* CLASS or NCLASS */ - { - printmap = TRUE; - ccode = code + 1; - } - - /* Print a bit map */ - - if (printmap) - { - uint8_t inverted_map[32]; - uint8_t *map = (uint8_t *)ccode; - - if (invertmap) - { - /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ - for (i = 0; i < 32; i++) inverted_map[i] = 255 ^ map[i]; - map = inverted_map; - } - - for (i = 0; i < 256; i++) - { - if ((map[i/8] & (1u << (i&7))) != 0) - { - int j; - for (j = i+1; j < 256; j++) - if ((map[j/8] & (1u << (j&7))) == 0) break; - if (i == '-' || i == ']') fprintf(f, "\\"); - if (PRINTABLE(i)) fprintf(f, "%c", i); - else fprintf(f, "\\x%02x", i); - if (--j > i) - { - if (j != i + 1) fprintf(f, "-"); - if (j == '-' || j == ']') fprintf(f, "\\"); - if (PRINTABLE(j)) fprintf(f, "%c", j); - else fprintf(f, "\\x%02x", j); - } - i = j; - } - } - ccode += 32 / sizeof(PCRE2_UCHAR); - } + const uint8_t *map = (const uint8_t *)ccode; + /* The first 6 ASCII characters (SOH...ACK) are totally, utterly useless. + If they're set in the bitmap, then it's clearly been formed by negation.*/ + BOOL print_negated = (map[0] & 0x7e) == 0x7e; + + fprintf(f, " bitmap: [%s", print_negated? "^" : ""); + print_map(f, map, print_negated); + fprintf(f, "]\n"); + ccode += 32 / sizeof(PCRE2_UCHAR); } - - /* For an XCLASS there is always some additional data */ - - if (*code == OP_XCLASS) + else + fprintf(f, " no bitmap\n"); + while (ccode < code + extra) { - PCRE2_UCHAR ch; - while ((ch = *ccode++) != XCL_END) + if (print_lengths) + fprintf(f, "%3d ", (int)(ccode - codestart)); + else + fprintf(f, " "); + + switch (*ccode) { - const char *notch = ""; + case ECL_AND: + fprintf(f, " AND\n"); + ccode += 1; + break; + case ECL_OR: + fprintf(f, " OR\n"); + ccode += 1; + break; + case ECL_XOR: + fprintf(f, " XOR\n"); + ccode += 1; + break; + case ECL_NOT: + fprintf(f, " NOT\n"); + ccode += 1; + break; - switch(ch) - { - case XCL_NOTPROP: - notch = "^"; - /* Fall through */ - - case XCL_PROP: - { - unsigned int ptype = *ccode++; - unsigned int pvalue = *ccode++; - const char *s; - - switch(ptype) - { - case PT_PXGRAPH: - fprintf(f, "[:%sgraph:]", notch); - break; - - case PT_PXPRINT: - fprintf(f, "[:%sprint:]", notch); - break; - - case PT_PXPUNCT: - fprintf(f, "[:%spunct:]", notch); - break; - - case PT_PXXDIGIT: - fprintf(f, "[:%sxdigit:]", notch); - break; - - default: - s = get_ucpname(ptype, pvalue); - fprintf(f, "\\%c{%c%s}", ((notch[0] == '^')? 'P':'p'), - toupper(s[0]), s+1); - break; - } - } - break; + case ECL_XCLASS: + print_class(f, OP_XCLASS, ccode+1, (uint8_t*)codestart, utf, + " xclass: ", "\n"); + ccode += GET(ccode, 1); + break; - default: - ccode += 1 + print_char(f, ccode, utf); - if (ch == XCL_RANGE) - { - fprintf(f, "-"); - ccode += 1 + print_char(f, ccode, utf); - } - break; - } + default: + fprintf(f, " UNEXPECTED\n"); + ccode += 1; + break; } } + fprintf(f, " ]"); + goto CLASS_REF_REPEAT; +#endif /* SUPPORT_WIDE_CHARS */ - /* Indicate a non-UTF class which was created by negation */ - - fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); + case OP_CLASS: + case OP_NCLASS: +#ifdef SUPPORT_WIDE_CHARS + case OP_XCLASS: + if (*code == OP_XCLASS) + extra = GET(code, 1); +#endif + print_class(f, *code, code+1, (uint8_t*)codestart, utf, " ", ""); + ccode = code + OP_lengths[*code] + extra; /* Handle repeats after a class or a back reference */ diff --git a/ext/pcre/pcre2lib/pcre2_serialize.c b/ext/pcre/pcre2lib/pcre2_serialize.c index ba17a26d2eeb2..a10e3020bbe9d 100644 --- a/ext/pcre/pcre2lib/pcre2_serialize.c +++ b/ext/pcre/pcre2lib/pcre2_serialize.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2020 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -127,25 +127,25 @@ dst_bytes += TABLES_LENGTH; for (i = 0; i < number_of_codes; i++) { re = (const pcre2_real_code *)(codes[i]); - (void)memcpy(dst_bytes, (char *)re, re->blocksize); - - /* Certain fields in the compiled code block are re-set during - deserialization. In order to ensure that the serialized data stream is always - the same for the same pattern, set them to zero here. We can't assume the - copy of the pattern is correctly aligned for accessing the fields as part of + (void)memcpy(dst_bytes, (const char *)re, re->blocksize); + + /* Certain fields in the compiled code block are re-set during + deserialization. In order to ensure that the serialized data stream is always + the same for the same pattern, set them to zero here. We can't assume the + copy of the pattern is correctly aligned for accessing the fields as part of a structure. Note the use of sizeof(void *) in the second of these, to - specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a - pointer to uint8_t), gcc gives a warning because the first argument is also a - pointer to uint8_t. Casting the first argument to (void *) can stop this, but + specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a + pointer to uint8_t), gcc gives a warning because the first argument is also a + pointer to uint8_t. Casting the first argument to (void *) can stop this, but it didn't stop Coverity giving the same complaint. */ - - (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0, + + (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0, sizeof(pcre2_memctl)); - (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0, + (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0, sizeof(void *)); (void)memset(dst_bytes + offsetof(pcre2_real_code, executable_jit), 0, - sizeof(void *)); - + sizeof(void *)); + dst_bytes += re->blocksize; } @@ -232,10 +232,10 @@ for (i = 0; i < number_of_codes; i++) if (dst_re->magic_number != MAGIC_NUMBER || dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 || dst_re->name_count > MAX_NAME_COUNT) - { - memctl->free(dst_re, memctl->memory_data); + { + memctl->free(dst_re, memctl->memory_data); return PCRE2_ERROR_BADSERIALIZEDDATA; - } + } /* At the moment only one table is supported. */ diff --git a/ext/pcre/pcre2lib/pcre2_study.c b/ext/pcre/pcre2lib/pcre2_study.c index 792e696dad74b..85764cea56533 100644 --- a/ext/pcre/pcre2lib/pcre2_study.c +++ b/ext/pcre/pcre2lib/pcre2_study.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2023 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -114,7 +114,7 @@ uint32_t once_fudge = 0; BOOL had_recurse = FALSE; BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0; PCRE2_SPTR nextbranch = code + GET(code, 1); -PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE; +PCRE2_SPTR cc = code + 1 + LINK_SIZE; recurse_check this_recurse; /* If this is a "could be empty" group, its minimum length is 0. */ @@ -136,12 +136,13 @@ passes 16-bits, reset to that value and skip the rest of the branch. */ for (;;) { int d, min, recno; - PCRE2_UCHAR op, *cs, *ce; + PCRE2_UCHAR op; + PCRE2_SPTR cs, ce; if (branchlength >= UINT16_MAX) { branchlength = UINT16_MAX; - cc = (PCRE2_UCHAR *)nextbranch; + cc = nextbranch; } op = *cc; @@ -249,6 +250,7 @@ for (;;) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: + case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); /* Fall through */ @@ -417,15 +419,14 @@ for (;;) case OP_NCLASS: #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: + case OP_ECLASS: /* The original code caused an unsigned overflow in 64 bit systems, so now we use a conditional statement. */ - if (op == OP_XCLASS) + if (op == OP_XCLASS || op == OP_ECLASS) cc += GET(cc, 1); else - cc += PRIV(OP_lengths)[OP_CLASS]; -#else - cc += PRIV(OP_lengths)[OP_CLASS]; #endif + cc += PRIV(OP_lengths)[OP_CLASS]; switch (*cc) { @@ -479,8 +480,8 @@ for (;;) if (!dupcapused && (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) { int count = GET2(cc, 1+IMM2_SIZE); - PCRE2_UCHAR *slot = - (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + + PCRE2_SPTR slot = + (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code)) + GET2(cc, 1) * re->name_entry_size; d = INT_MAX; @@ -496,13 +497,12 @@ for (;;) dd = backref_cache[recno]; else { - ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno); + ce = cs = PRIV(find_bracket)(startcode, utf, recno); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); dd = 0; - if (!dupcapused || - (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL) + if (!dupcapused || PRIV(find_bracket)(ce, utf, recno) == NULL) { if (cc > cs && cc < ce) /* Simple recursion */ { @@ -539,7 +539,7 @@ for (;;) } } else d = 0; - cc += 1 + 2*IMM2_SIZE; + cc += PRIV(OP_lengths)[*cc]; goto REPEAT_BACK_REFERENCE; /* Single back reference by number. References by name are converted to by @@ -557,12 +557,11 @@ for (;;) if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) { - ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno); + ce = cs = PRIV(find_bracket)(startcode, utf, recno); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); - if (!dupcapused || - (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL) + if (!dupcapused || PRIV(find_bracket)(ce, utf, recno) == NULL) { if (cc > cs && cc < ce) /* Simple recursion */ { @@ -593,7 +592,7 @@ for (;;) backref_cache[0] = recno; } - cc += 1 + IMM2_SIZE; + cc += PRIV(OP_lengths)[*cc]; /* Handle repeated back references */ @@ -643,7 +642,7 @@ for (;;) pattern contains multiple subpatterns with the same number. */ case OP_RECURSE: - cs = ce = (PCRE2_UCHAR *)startcode + GET(cc, 1); + cs = ce = startcode + GET(cc, 1); recno = GET2(cs, 1+LINK_SIZE); if (recno == prev_recurse_recno) { @@ -755,10 +754,13 @@ for (;;) new ones get added they are properly considered. */ default: + PCRE2_DEBUG_UNREACHABLE(); return -3; } } -/* Control never gets here */ + +PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ +return -3; /* Avoid compiler warnings */ } @@ -919,6 +921,138 @@ if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +/************************************************* +* Set starting bits for a character list. * +*************************************************/ + +/* This function sets starting bits for a character list. It enumerates +all characters and character ranges in the character list, and sets +the starting bits accordingly. + +Arguments: + code pointer to the code + start_bitmap pointer to the starting bitmap + +Returns: nothing +*/ +static void +study_char_list(PCRE2_SPTR code, uint8_t *start_bitmap, + const uint8_t *char_lists_end) +{ +uint32_t type, list_ind; +uint32_t char_list_add = XCL_CHAR_LIST_LOW_16_ADD; +uint32_t range_start = ~(uint32_t)0, range_end = 0; +const uint8_t *next_char; +PCRE2_UCHAR start_buffer[6], end_buffer[6]; +PCRE2_UCHAR start, end; + +/* Only needed in 8-bit mode at the moment. */ +type = (uint32_t)(code[0] << 8) | code[1]; +code += 2; + +/* Align characters. */ +next_char = char_lists_end - (GET(code, 0) << 1); +type &= XCL_TYPE_MASK; +list_ind = 0; + +if ((type & XCL_BEGIN_WITH_RANGE) != 0) + range_start = XCL_CHAR_LIST_LOW_16_START; + +while (type > 0) + { + uint32_t item_count = type & XCL_ITEM_COUNT_MASK; + + if (item_count == XCL_ITEM_COUNT_MASK) + { + if (list_ind <= 1) + { + item_count = *(const uint16_t*)next_char; + next_char += 2; + } + else + { + item_count = *(const uint32_t*)next_char; + next_char += 4; + } + } + + while (item_count > 0) + { + if (list_ind <= 1) + { + range_end = *(const uint16_t*)next_char; + next_char += 2; + } + else + { + range_end = *(const uint32_t*)next_char; + next_char += 4; + } + + if ((range_end & XCL_CHAR_END) != 0) + { + range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT); + + PRIV(ord2utf)(range_end, end_buffer); + end = end_buffer[0]; + + if (range_start < range_end) + { + PRIV(ord2utf)(range_start, start_buffer); + for (start = start_buffer[0]; start <= end; start++) + start_bitmap[start / 8] |= (1u << (start & 7)); + } + else + start_bitmap[end / 8] |= (1u << (end & 7)); + + range_start = ~(uint32_t)0; + } + else + range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT); + + item_count--; + } + + list_ind++; + type >>= XCL_TYPE_BIT_LEN; + + if (range_start == ~(uint32_t)0) + { + if ((type & XCL_BEGIN_WITH_RANGE) != 0) + { + /* In 8 bit mode XCL_CHAR_LIST_HIGH_32_START is not possible. */ + if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START; + else range_start = XCL_CHAR_LIST_LOW_32_START; + } + } + else if ((type & XCL_BEGIN_WITH_RANGE) == 0) + { + PRIV(ord2utf)(range_start, start_buffer); + + /* In 8 bit mode XCL_CHAR_LIST_LOW_32_END and + XCL_CHAR_LIST_HIGH_32_END are not possible. */ + if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END; + else range_end = XCL_CHAR_LIST_HIGH_16_END; + + PRIV(ord2utf)(range_end, end_buffer); + end = end_buffer[0]; + + for (start = start_buffer[0]; start <= end; start++) + start_bitmap[start / 8] |= (1u << (start & 7)); + + range_start = ~(uint32_t)0; + } + + /* In 8 bit mode XCL_CHAR_LIST_HIGH_32_ADD is not possible. */ + if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; + else char_list_add = XCL_CHAR_LIST_LOW_32_ADD; + } +} +#endif + + + /************************************************* * Create bitmap of starting code units * *************************************************/ @@ -980,7 +1114,7 @@ do { int rc; PCRE2_SPTR ncode; - uint8_t *classmap = NULL; + const uint8_t *classmap = NULL; #ifdef SUPPORT_WIDE_CHARS PCRE2_UCHAR xclassflags; #endif @@ -1134,6 +1268,7 @@ do case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: ncode += GET(ncode, 1); while (*ncode == OP_ALT) ncode += GET(ncode, 1); ncode += 1 + LINK_SIZE; @@ -1252,12 +1387,14 @@ do tcode += GET(tcode, 1 + 2*LINK_SIZE); break; - /* Skip over lookbehind and negative lookahead assertions */ + /* Skip over lookbehind, negative lookahead, and scan substring + assertions */ case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERTBACK_NA: + case OP_ASSERT_SCS: do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; @@ -1578,6 +1715,13 @@ do tcode += 2; break; + /* Set-based ECLASS: treat it the same as a "complex" XCLASS; give up. */ + +#ifdef SUPPORT_WIDE_CHARS + case OP_ECLASS: + return SSB_FAIL; +#endif + /* Extended class: if there are any property checks, or if this is a negative XCLASS without a map, give up. If there are no property checks, there must be wide characters on the XCLASS list, because otherwise an @@ -1596,7 +1740,7 @@ do map pointer if there is one, and fall through. */ classmap = ((xclassflags & XCL_MAP) == 0)? NULL : - (uint8_t *)(tcode + 1 + LINK_SIZE + 1); + (const uint8_t *)(tcode + 1 + LINK_SIZE + 1); /* In UTF-8 mode, scan the character list and set bits for leading bytes, then jump to handle the map. */ @@ -1608,6 +1752,13 @@ do PCRE2_SPTR p = tcode + 1 + LINK_SIZE + 1 + ((classmap == NULL)? 0:32); tcode += GET(tcode, 1); + if (*p >= XCL_LIST) + { + study_char_list(p, re->start_bitmap, + ((const uint8_t *)re + re->code_start)); + goto HANDLE_CLASSMAP; + } + for (;;) switch (*p++) { case XCL_SINGLE: @@ -1629,6 +1780,7 @@ do goto HANDLE_CLASSMAP; default: + PCRE2_DEBUG_UNREACHABLE(); return SSB_UNKNOWN; /* Internal error, should not occur */ } } @@ -1665,7 +1817,7 @@ do case OP_CLASS: if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else { - classmap = (uint8_t *)(++tcode); + classmap = (const uint8_t *)(++tcode); tcode += 32 / sizeof(PCRE2_UCHAR); } @@ -1768,8 +1920,7 @@ BOOL ucp = (re->overall_options & PCRE2_UCP) != 0; /* Find start of compiled code */ -code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + - re->name_entry_size * re->name_count; +code = (PCRE2_UCHAR *)((uint8_t *)re + re->code_start); /* For a pattern that has a first code unit, or a multiline pattern that matches only at "line start", there is no point in seeking a list of starting @@ -1779,7 +1930,11 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) { int depth = 0; int rc = set_start_bits(re, code, utf, ucp, &depth); - if (rc == SSB_UNKNOWN) return 1; + if (rc == SSB_UNKNOWN) + { + PCRE2_DEBUG_UNREACHABLE(); + return 1; + } /* If a list of starting code units was set up, scan the list to see if only one or two were listed. Having only one listed is rare because usually a @@ -1852,25 +2007,22 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) } } - /* Replace the start code unit bits with a first code unit, but only if it - is not the same as a required later code unit. This is because a search for - a required code unit starts after an explicit first code unit, but at a - code unit found from the bitmap. Patterns such as /a*a/ don't work - if both the start unit and required unit are the same. */ - - if (a >= 0 && - ( - (re->flags & PCRE2_LASTSET) == 0 || - ( - re->last_codeunit != (uint32_t)a && - (b < 0 || re->last_codeunit != (uint32_t)b) - ) - )) - { + /* Replace the start code unit bits with a first code unit. If it is the + same as a required later code unit, then clear the required later code + unit. This is because a search for a required code unit starts after an + explicit first code unit, but at a code unit found from the bitmap. + Patterns such as /a*a/ don't work if both the start unit and required + unit are the same. */ + + if (a >= 0) { + if ((re->flags & PCRE2_LASTSET) && (re->last_codeunit == (uint32_t)a || (b >= 0 && re->last_codeunit == (uint32_t)b))) { + re->flags &= ~(PCRE2_LASTSET | PCRE2_LASTCASELESS); + re->last_codeunit = 0; + } re->first_codeunit = a; flags = PCRE2_FIRSTSET; if (b >= 0) flags |= PCRE2_FIRSTCASELESS; - } + } DONE: re->flags |= flags; @@ -1898,9 +2050,11 @@ if ((re->flags & (PCRE2_MATCH_EMPTY|PCRE2_HASACCEPT)) == 0 && break; /* Leave minlength unchanged (will be zero) */ case -2: + PCRE2_DEBUG_UNREACHABLE(); return 2; /* missing capturing bracket */ case -3: + PCRE2_DEBUG_UNREACHABLE(); return 3; /* unrecognized opcode */ default: diff --git a/ext/pcre/pcre2lib/pcre2_substitute.c b/ext/pcre/pcre2lib/pcre2_substitute.c index edbb78c6d7867..17040ce5fd4c9 100644 --- a/ext/pcre/pcre2lib/pcre2_substitute.c +++ b/ext/pcre/pcre2lib/pcre2_substitute.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -130,17 +130,21 @@ for (; ptr < ptrend; ptr++) ptr += 1; /* Must point after \ */ erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode, - code->overall_options, code->extra_options, FALSE, NULL); + code->overall_options, code->extra_options, code->top_bracket, FALSE, NULL); ptr -= 1; /* Back to last code unit of escape */ if (errorcode != 0) { - rc = errorcode; + /* errorcode from check_escape is positive, so must not be returned by + pcre2_substitute(). */ + rc = PCRE2_ERROR_BADREPESCAPE; goto EXIT; } switch(erc) { case 0: /* Data character */ + case ESC_b: /* Data character */ + case ESC_v: /* Data character */ case ESC_E: /* Isolated \E is ignored */ break; @@ -148,7 +152,18 @@ for (; ptr < ptrend; ptr++) literal = TRUE; break; + case ESC_g: + /* The \g form (\g already handled by check_escape) + + Don't worry about finding the matching ">". We are super, super lenient + about validating ${} replacements inside find_text_end(), so we certainly + don't need to worry about other syntax. Importantly, a \g<..> or $<...> + sequence can't contain a '}' character. */ + break; + default: + if (erc < 0) + break; /* capture group reference */ rc = PCRE2_ERROR_BADREPESCAPE; goto EXIT; } @@ -163,6 +178,426 @@ return rc; } +/************************************************* +* Validate group name * +*************************************************/ + +/* This function scans for a capture group name, validating it +consists of legal characters, is not empty, and does not exceed +MAX_NAME_SIZE. + +Arguments: + ptrptr points to the pointer to the start of the text (updated) + ptrend end of the whole string + utf true if the input is UTF-encoded + ctypes pointer to the character types table + +Returns: TRUE if a name was read + FALSE otherwise +*/ + +static BOOL +read_name_subst(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf, + const uint8_t* ctypes) +{ +PCRE2_SPTR ptr = *ptrptr; +PCRE2_SPTR nameptr = ptr; + +if (ptr >= ptrend) /* No characters in name */ + goto FAILED; + +/* We do not need to check whether the name starts with a non-digit. +We are simply referencing names here, not defining them. */ + +/* See read_name in the pcre2_compile.c for the corresponding logic +restricting group names inside the pattern itself. */ + +#ifdef SUPPORT_UNICODE +if (utf) + { + uint32_t c, type; + + while (ptr < ptrend) + { + GETCHAR(c, ptr); + type = UCD_CHARTYPE(c); + if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L && + c != CHAR_UNDERSCORE) break; + ptr++; + FORWARDCHARTEST(ptr, ptrend); + } + } +else +#else +(void)utf; /* Avoid compiler warning */ +#endif /* SUPPORT_UNICODE */ + +/* Handle group names in non-UTF modes. */ + + { + while (ptr < ptrend && MAX_255(*ptr) && (ctypes[*ptr] & ctype_word) != 0) + { + ptr++; + } + } + +/* Check name length */ + +if (ptr - nameptr > MAX_NAME_SIZE) + goto FAILED; + +/* Subpattern names must not be empty */ +if (ptr == nameptr) + goto FAILED; + +*ptrptr = ptr; +return TRUE; + +FAILED: +*ptrptr = ptr; +return FALSE; +} + + +/************************************************* +* Case transformations * +*************************************************/ + +#define PCRE2_SUBSTITUTE_CASE_NONE 0 +// 1, 2, 3 are PCRE2_SUBSTITUTE_CASE_LOWER, UPPER, TITLE_FIRST. +#define PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST 4 + +typedef struct { + int to_case; /* One of PCRE2_SUBSTITUTE_CASE_xyz */ + BOOL single_char; +} case_state; + +/* Helper to guess how much a string is likely to increase in size when +case-transformed. Usually, strings don't change size at all, but some rare +characters do grow. Estimate +10%, plus another few characters. + +Performing this estimation is unfortunate, but inevitable, since we can't call +the callout if we ran out of buffer space to prepare its input. + +Because this estimate is inexact (and in pathological cases, underestimates the +required buffer size) we must document that when you have a +substitute_case_callout, and you are using PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, you +may need more than two calls to determine the final buffer size. */ + +static PCRE2_SIZE +pessimistic_case_inflation(PCRE2_SIZE len) +{ +return (len >> 3u) + 10; +} + +/* Case transformation behaviour if no callout is passed. */ + +static PCRE2_SIZE +default_substitute_case_callout( + PCRE2_SPTR input, PCRE2_SIZE input_len, + PCRE2_UCHAR *output, PCRE2_SIZE output_cap, + case_state *state, const pcre2_code *code) +{ +PCRE2_SPTR input_end = input + input_len; +#ifdef SUPPORT_UNICODE +BOOL utf; +BOOL ucp; +#endif +PCRE2_UCHAR temp[6]; +BOOL next_to_upper; +BOOL rest_to_upper; +BOOL single_char; +BOOL overflow = FALSE; +PCRE2_SIZE written = 0; + +/* Helpful simplifying invariant: input and output are disjoint buffers. +I believe that this code is technically undefined behaviour, because the two +pointers input/output are "unrelated" pointers and hence not comparable. Casting +via char* bypasses some but not all of those technical rules. It is not included +in release builds, in any case. */ +PCRE2_ASSERT((char *)(input + input_len) <= (char *)output || + (char *)(output + output_cap) <= (char *)input); + +#ifdef SUPPORT_UNICODE +utf = (code->overall_options & PCRE2_UTF) != 0; +ucp = (code->overall_options & PCRE2_UCP) != 0; +#endif + +if (input_len == 0) return 0; + +switch (state->to_case) + { + default: + PCRE2_DEBUG_UNREACHABLE(); + return 0; + + case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE + case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE + next_to_upper = rest_to_upper = (state->to_case == PCRE2_SUBSTITUTE_CASE_UPPER); + break; + + case PCRE2_SUBSTITUTE_CASE_TITLE_FIRST: // Can be single_char TRUE or FALSE + next_to_upper = TRUE; + rest_to_upper = FALSE; + state->to_case = PCRE2_SUBSTITUTE_CASE_LOWER; + break; + + case PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST: // Can only be single_char FALSE + next_to_upper = FALSE; + rest_to_upper = TRUE; + state->to_case = PCRE2_SUBSTITUTE_CASE_UPPER; + break; + } + +single_char = state->single_char; +if (single_char) + state->to_case = PCRE2_SUBSTITUTE_CASE_NONE; + +while (input < input_end) + { + uint32_t ch; + unsigned int chlen; + + GETCHARINCTEST(ch, input); + +#ifdef SUPPORT_UNICODE + if ((utf || ucp) && ch >= 128) + { + uint32_t type = UCD_CHARTYPE(ch); + if (PRIV(ucp_gentype)[type] == ucp_L && + type != (next_to_upper? ucp_Lu : ucp_Ll)) + ch = UCD_OTHERCASE(ch); + + /* TODO This is far from correct... it doesn't support the SpecialCasing.txt + mappings, but worse, it's not even correct for all the ordinary case + mappings. We should add support for those (at least), and then add the + SpecialCasing.txt mappings for Esszet and ligatures, and finally use the + Turkish casing flag on the match context. */ + } + else +#endif + if (MAX_255(ch)) + { + if (((code->tables + cbits_offset + + (next_to_upper? cbit_upper:cbit_lower) + )[ch/8] & (1u << (ch%8))) == 0) + ch = (code->tables + fcc_offset)[ch]; + } + +#ifdef SUPPORT_UNICODE + if (utf) chlen = PRIV(ord2utf)(ch, temp); else +#endif + { + temp[0] = ch; + chlen = 1; + } + + if (!overflow && chlen <= output_cap) + { + memcpy(output, temp, CU2BYTES(chlen)); + output += chlen; + output_cap -= chlen; + } + else + { + overflow = TRUE; + } + + if (chlen > ~(PCRE2_SIZE)0 - written) /* Integer overflow */ + return ~(PCRE2_SIZE)0; + written += chlen; + + next_to_upper = rest_to_upper; + + /* memcpy the remainder, if only transforming a single character. */ + + if (single_char) + { + PCRE2_SIZE rest_len = input_end - input; + + if (!overflow && rest_len <= output_cap) + memcpy(output, input, CU2BYTES(rest_len)); + + if (rest_len > ~(PCRE2_SIZE)0 - written) /* Integer overflow */ + return ~(PCRE2_SIZE)0; + written += rest_len; + + return written; + } + } + +return written; +} + +/* Helper to perform the call to the substitute_case_callout. We wrap the +user-provided callout because our internal arguments are slightly extended. We +don't want the user callout to handle the case of "\l" (first character only to +lowercase) or "\l\U" (first character to lowercase, rest to uppercase) because +those are not operations defined by Unicode. Instead the user callout simply +needs to provide the three Unicode primitives: lower, upper, titlecase. */ + +static PCRE2_SIZE +do_case_copy( + PCRE2_UCHAR *input_output, PCRE2_SIZE input_len, PCRE2_SIZE output_cap, + case_state *state, BOOL utf, + PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, + PCRE2_SIZE, int, void *), + void *substitute_case_callout_data) +{ +PCRE2_SPTR input = input_output; +PCRE2_UCHAR *output = input_output; +PCRE2_SIZE rc; +PCRE2_SIZE rc2; +int ch1_to_case; +int rest_to_case; +PCRE2_UCHAR ch1[6]; +PCRE2_SIZE ch1_len; +PCRE2_SPTR rest; +PCRE2_SIZE rest_len; +BOOL ch1_overflow = FALSE; +BOOL rest_overflow = FALSE; + +#if PCRE2_CODE_UNIT_WIDTH == 32 || !defined(SUPPORT_UNICODE) +(void)utf; /* Avoid compiler warning. */ +#endif + +PCRE2_ASSERT(input_len != 0); + +switch (state->to_case) + { + default: + PCRE2_DEBUG_UNREACHABLE(); + return 0; + + case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE + case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE + case PCRE2_SUBSTITUTE_CASE_TITLE_FIRST: // Can be single_char TRUE or FALSE + + /* The easy case, where our internal casing operations align with those of + the callout. */ + + if (state->single_char == FALSE) + { + rc = substitute_case_callout(input, input_len, output, output_cap, + state->to_case, substitute_case_callout_data); + + if (state->to_case == PCRE2_SUBSTITUTE_CASE_TITLE_FIRST) + state->to_case = PCRE2_SUBSTITUTE_CASE_LOWER; + + return rc; + } + + ch1_to_case = state->to_case; + rest_to_case = PCRE2_SUBSTITUTE_CASE_NONE; + break; + + case PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST: // Can only be single_char FALSE + ch1_to_case = PCRE2_SUBSTITUTE_CASE_LOWER; + rest_to_case = PCRE2_SUBSTITUTE_CASE_UPPER; + break; + } + +/* Identify the leading character. Take copy, because its storage overlaps with +`output`, and hence may be scrambled by the callout. */ + + { + PCRE2_SPTR ch_end = input; + uint32_t ch; + + GETCHARINCTEST(ch, ch_end); + (void) ch; + PCRE2_ASSERT(ch_end <= input + input_len && ch_end - input <= 6); + ch1_len = ch_end - input; + memcpy(ch1, input, CU2BYTES(ch1_len)); + } + +rest = input + ch1_len; +rest_len = input_len - ch1_len; + +/* Transform just ch1. The buffers are always in-place (input == output). With a +custom callout, we need a loop to discover its required buffer size. The loop +wouldn't be required if the callout were well-behaved, but it might be naughty +and return "5" the first time, then "10" the next time we call it using the +exact same input! */ + + { + PCRE2_SIZE ch1_cap; + PCRE2_SIZE max_ch1_cap; + + ch1_cap = ch1_len; /* First attempt uses the space vacated by ch1. */ + PCRE2_ASSERT(output_cap >= input_len && input_len >= rest_len); + max_ch1_cap = output_cap - rest_len; + + while (TRUE) + { + rc = substitute_case_callout(ch1, ch1_len, output, ch1_cap, ch1_to_case, + substitute_case_callout_data); + if (rc == ~(PCRE2_SIZE)0) return rc; + + if (rc <= ch1_cap) break; + + if (rc > max_ch1_cap) + { + ch1_overflow = TRUE; + break; + } + + /* Move the rest to the right, to make room for expanding ch1. */ + + memmove(input_output + rc, rest, CU2BYTES(rest_len)); + rest = input + rc; + + ch1_cap = rc; + + /* Proof of loop termination: `ch1_cap` is growing on each iteration, but + the loop ends if `rc` reaches the (unchanging) upper bound of output_cap. */ + } + } + +if (rest_to_case == PCRE2_SUBSTITUTE_CASE_NONE) + { + if (!ch1_overflow) + { + PCRE2_ASSERT(rest_len <= output_cap - rc); + memmove(output + rc, rest, CU2BYTES(rest_len)); + } + rc2 = rest_len; + + state->to_case = PCRE2_SUBSTITUTE_CASE_NONE; + } +else + { + PCRE2_UCHAR dummy[1]; + + rc2 = substitute_case_callout(rest, rest_len, + ch1_overflow? dummy : output + rc, + ch1_overflow? 0u : output_cap - rc, + rest_to_case, substitute_case_callout_data); + if (rc2 == ~(PCRE2_SIZE)0) return rc2; + + if (!ch1_overflow && rc2 > output_cap - rc) rest_overflow = TRUE; + + /* If ch1 grows so that `xform(ch1)+rest` can't fit in the buffer, but then + `rest` shrinks, it's actually possible for the total calculated length of + `xform(ch1)+xform(rest)` to come out at less than output_cap. But we can't + report that, because it would make it seem that the operation succeeded. + If either of xform(ch1) or xform(rest) won't fit in the buffer, our final + result must be > output_cap. */ + if (ch1_overflow && rc2 < rest_len) + rc2 = rest_len; + + state->to_case = PCRE2_SUBSTITUTE_CASE_UPPER; + } + +if (rc2 > ~(PCRE2_SIZE)0 - rc) /* Integer overflow */ + return ~(PCRE2_SIZE)0; + +PCRE2_ASSERT(!(ch1_overflow || rest_overflow) || rc + rc2 > output_cap); +(void)rest_overflow; + +return rc + rc2; +} + /************************************************* * Match and substitute * @@ -194,25 +629,107 @@ Returns: >= 0 number of substitutions made overflow, either give an error immediately, or keep on, accumulating the length. */ -#define CHECKMEMCPY(from,length) \ - { \ - if (!overflowed && lengthleft < length) \ - { \ - if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ - overflowed = TRUE; \ - extra_needed = length - lengthleft; \ - } \ - else if (overflowed) \ - { \ - extra_needed += length; \ - } \ - else \ - { \ - memcpy(buffer + buff_offset, from, CU2BYTES(length)); \ - buff_offset += length; \ - lengthleft -= length; \ - } \ - } +#define CHECKMEMCPY(from, length_) \ + do { \ + PCRE2_SIZE chkmc_length = length_; \ + if (overflowed) \ + { \ + if (chkmc_length > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ \ + goto TOOLARGEREPLACE; \ + extra_needed += chkmc_length; \ + } \ + else if (lengthleft < chkmc_length) \ + { \ + if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ + overflowed = TRUE; \ + extra_needed = chkmc_length - lengthleft; \ + } \ + else \ + { \ + memcpy(buffer + buff_offset, from, CU2BYTES(chkmc_length)); \ + buff_offset += chkmc_length; \ + lengthleft -= chkmc_length; \ + } \ + } \ + while (0) + +/* This macro checks for space and copies characters with casing modifications. +On overflow, it behaves as for CHECKMEMCPY(). + +When substitute_case_callout is NULL, the source and destination buffers must +not overlap, because our default handler does not support this. */ + +#define CHECKCASECPY_BASE(length_, do_call) \ + do { \ + PCRE2_SIZE chkcc_length = (PCRE2_SIZE)(length_); \ + PCRE2_SIZE chkcc_rc; \ + do_call \ + if (lengthleft < chkcc_rc) \ + { \ + if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ + overflowed = TRUE; \ + extra_needed = chkcc_rc - lengthleft; \ + } \ + else \ + { \ + buff_offset += chkcc_rc; \ + lengthleft -= chkcc_rc; \ + } \ + } \ + while (0) + +#define CHECKCASECPY_DEFAULT(from, length_) \ + CHECKCASECPY_BASE(length_, { \ + chkcc_rc = default_substitute_case_callout(from, chkcc_length, \ + buffer + buff_offset, \ + overflowed? 0 : lengthleft, \ + &forcecase, code); \ + if (overflowed) \ + { \ + if (chkcc_rc > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ \ + goto TOOLARGEREPLACE; \ + extra_needed += chkcc_rc; \ + break; \ + } \ + }) + +#define CHECKCASECPY_CALLOUT(length_) \ + CHECKCASECPY_BASE(length_, { \ + chkcc_rc = do_case_copy(buffer + buff_offset, chkcc_length, \ + lengthleft, &forcecase, utf, \ + substitute_case_callout, \ + substitute_case_callout_data); \ + if (chkcc_rc == ~(PCRE2_SIZE)0) goto CASEERROR; \ + }) + +/* This macro does a delayed case transformation, for the situation when we have +a case-forcing callout. */ + +#define DELAYEDFORCECASE() \ + do { \ + PCRE2_SIZE chars_outstanding = (buff_offset - casestart_offset) + \ + (extra_needed - casestart_extra_needed); \ + if (chars_outstanding > 0) \ + { \ + if (overflowed) \ + { \ + PCRE2_SIZE guess = pessimistic_case_inflation(chars_outstanding); \ + if (guess > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ \ + goto TOOLARGEREPLACE; \ + extra_needed += guess; \ + } \ + else \ + { \ + /* Rewind the buffer */ \ + lengthleft += (buff_offset - casestart_offset); \ + buff_offset = casestart_offset; \ + /* Care! In-place case transformation */ \ + CHECKCASECPY_CALLOUT(chars_outstanding); \ + } \ + } \ + } \ + while (0) + /* Here's the function */ @@ -224,8 +741,6 @@ pcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, { int rc; int subs; -int forcecase = 0; -int forcecasereset = 0; uint32_t ovector_count; uint32_t goptions = 0; uint32_t suboptions; @@ -234,18 +749,19 @@ BOOL escaped_literal = FALSE; BOOL overflowed = FALSE; BOOL use_existing_match; BOOL replacement_only; -#ifdef SUPPORT_UNICODE BOOL utf = (code->overall_options & PCRE2_UTF) != 0; -BOOL ucp = (code->overall_options & PCRE2_UCP) != 0; -#endif PCRE2_UCHAR temp[6]; PCRE2_SPTR ptr; -PCRE2_SPTR repend; +PCRE2_SPTR repend = NULL; PCRE2_SIZE extra_needed = 0; PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength; PCRE2_SIZE *ovector; PCRE2_SIZE ovecsave[3]; pcre2_substitute_callout_block scb; +PCRE2_SIZE sub_start_extra_needed; +PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, + PCRE2_SIZE, int, void *) = NULL; +void *substitute_case_callout_data = NULL; /* General initialization */ @@ -254,6 +770,12 @@ lengthleft = buff_length = *blength; *blength = PCRE2_UNSET; ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET; +if (mcontext != NULL) + { + substitute_case_callout = mcontext->substitute_case_callout; + substitute_case_callout_data = mcontext->substitute_case_callout_data; + } + /* Partial matching is not valid. This must come after setting *blength to PCRE2_UNSET, so as not to imply an offset in the replacement. */ @@ -286,27 +808,34 @@ case, we copy the existing match into the internal block, except for any cached heap frame size and pointer. This ensures that no changes are made to the external match data block. */ +/* WARNING: In both cases below a general context is constructed "by hand" +because calling pcre2_general_context_create() involves a memory allocation. If +the contents of a general context control block are ever changed there will +have to be changes below. */ + if (match_data == NULL) { - pcre2_general_context *gcontext; + pcre2_general_context gcontext; if (use_existing_match) return PCRE2_ERROR_NULL; - gcontext = (mcontext == NULL)? - (pcre2_general_context *)code : - (pcre2_general_context *)mcontext; + gcontext.memctl = (mcontext == NULL)? + ((const pcre2_real_code *)code)->memctl : + ((pcre2_real_match_context *)mcontext)->memctl; match_data = internal_match_data = - pcre2_match_data_create_from_pattern(code, gcontext); + pcre2_match_data_create_from_pattern(code, &gcontext); if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; } else if (use_existing_match) { - pcre2_general_context *gcontext = (mcontext == NULL)? - (pcre2_general_context *)code : - (pcre2_general_context *)mcontext; - int pairs = (code->top_bracket + 1 < match_data->oveccount)? + int pairs; + pcre2_general_context gcontext; + gcontext.memctl = (mcontext == NULL)? + ((const pcre2_real_code *)code)->memctl : + ((pcre2_real_match_context *)mcontext)->memctl; + pairs = (code->top_bracket + 1 < match_data->oveccount)? code->top_bracket + 1 : match_data->oveccount; internal_match_data = pcre2_match_data_create(match_data->oveccount, - gcontext); + &gcontext); if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector) + 2*pairs*sizeof(PCRE2_SIZE)); @@ -380,6 +909,9 @@ do { PCRE2_SPTR ptrstack[PTR_STACK_SIZE]; uint32_t ptrstackptr = 0; + case_state forcecase = { PCRE2_SUBSTITUTE_CASE_NONE, FALSE }; + PCRE2_SIZE casestart_offset = 0; + PCRE2_SIZE casestart_extra_needed = 0; if (use_existing_match) { @@ -412,8 +944,9 @@ do save_start = start_offset++; if (subject[start_offset-1] == CHAR_CR && - code->newline_convention != PCRE2_NEWLINE_CR && - code->newline_convention != PCRE2_NEWLINE_LF && + (code->newline_convention == PCRE2_NEWLINE_CRLF || + code->newline_convention == PCRE2_NEWLINE_ANY || + code->newline_convention == PCRE2_NEWLINE_ANYCRLF) && start_offset < length && subject[start_offset] == CHAR_LF) start_offset++; @@ -480,14 +1013,16 @@ do } subs++; - /* Copy the text leading up to the match (unless not required), and remember - where the insert begins and how many ovector pairs are set. */ + /* Copy the text leading up to the match (unless not required); remember + where the insert begins and how many ovector pairs are set; and remember how + much space we have requested in extra_needed. */ if (rc == 0) rc = ovector_count; fraglength = ovector[0] - start_offset; if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength); scb.output_offsets[0] = buff_offset; scb.oveccount = rc; + sub_start_extra_needed = extra_needed; /* Process the replacement string. If the entire replacement is literal, just copy it with length check. */ @@ -507,6 +1042,13 @@ do { uint32_t ch; unsigned int chlen; + int group; + uint32_t special; + PCRE2_SPTR text1_start = NULL; + PCRE2_SPTR text1_end = NULL; + PCRE2_SPTR text2_start = NULL; + PCRE2_SPTR text2_end = NULL; + PCRE2_UCHAR name[MAX_NAME_SIZE + 1]; /* If at the end of a nested substring, pop the stack. */ @@ -535,25 +1077,62 @@ do if (*ptr == CHAR_DOLLAR_SIGN) { - int group, n; - uint32_t special = 0; BOOL inparens; + BOOL inangle; BOOL star; PCRE2_SIZE sublength; - PCRE2_SPTR text1_start = NULL; - PCRE2_SPTR text1_end = NULL; - PCRE2_SPTR text2_start = NULL; - PCRE2_SPTR text2_end = NULL; PCRE2_UCHAR next; - PCRE2_UCHAR name[33]; + PCRE2_SPTR subptr, subptrend; if (++ptr >= repend) goto BAD; if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL; + special = 0; + text1_start = NULL; + text1_end = NULL; + text2_start = NULL; + text2_end = NULL; group = -1; - n = 0; inparens = FALSE; + inangle = FALSE; star = FALSE; + subptr = NULL; + subptrend = NULL; + + /* Special $ sequences, as supported by Perl, JavaScript, .NET and others. */ + if (next == CHAR_AMPERSAND) + { + ++ptr; + group = 0; + goto GROUP_SUBSTITUTE; + } + if (next == CHAR_GRAVE_ACCENT || next == CHAR_APOSTROPHE) + { + ++ptr; + rc = pcre2_substring_length_bynumber(match_data, 0, &sublength); + if (rc < 0) goto PTREXIT; /* (Sanity-check ovector before reading from it.) */ + + if (next == CHAR_GRAVE_ACCENT) + { + subptr = subject; + subptrend = subject + ovector[0]; + } + else + { + subptr = subject + ovector[1]; + subptrend = subject + length; + } + + goto SUBPTR_SUBSTITUTE; + } + if (next == CHAR_UNDERSCORE) + { + /* Java, .NET support $_ for "entire input string". */ + ++ptr; + subptr = subject; + subptrend = subject + length; + goto SUBPTR_SUBSTITUTE; + } if (next == CHAR_LEFT_CURLY_BRACKET) { @@ -561,22 +1140,31 @@ do next = *ptr; inparens = TRUE; } + else if (next == CHAR_LESS_THAN_SIGN) + { + /* JavaScript compatibility syntax, $. Processes only named + groups (not numbered) and does not support extensions such as star + (you can do ${name} and ${*name}, but not $<*name>). */ + if (++ptr >= repend) goto BAD; + next = *ptr; + inangle = TRUE; + } - if (next == CHAR_ASTERISK) + if (!inangle && next == CHAR_ASTERISK) { if (++ptr >= repend) goto BAD; next = *ptr; star = TRUE; } - if (!star && next >= CHAR_0 && next <= CHAR_9) + if (!star && !inangle && next >= CHAR_0 && next <= CHAR_9) { group = next - CHAR_0; while (++ptr < repend) { next = *ptr; if (next < CHAR_0 || next > CHAR_9) break; - group = group * 10 + next - CHAR_0; + group = group * 10 + (next - CHAR_0); /* A check for a number greater than the hightest captured group is sufficient here; no need for a separate overflow check. If unknown @@ -600,25 +1188,25 @@ do } else { - const uint8_t *ctypes = code->tables + ctypes_offset; - while (MAX_255(next) && (ctypes[next] & ctype_word) != 0) - { - name[n++] = next; - if (n > 32) goto BAD; - if (++ptr >= repend) break; - next = *ptr; - } - if (n == 0) goto BAD; - name[n] = 0; + PCRE2_SIZE name_len; + PCRE2_SPTR name_start = ptr; + if (!read_name_subst(&ptr, repend, utf, code->tables + ctypes_offset)) + goto BAD; + name_len = ptr - name_start; + memcpy(name, name_start, CU2BYTES(name_len)); + name[name_len] = 0; } + next = 0; /* not used or updated after this point */ + (void)next; + /* In extended mode we recognize ${name:+set text:unset text} and ${name:-default text}. */ if (inparens) { if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 && - !star && ptr < repend - 2 && next == CHAR_COLON) + !star && ptr < repend - 2 && *ptr == CHAR_COLON) { special = *(++ptr); if (special != CHAR_PLUS && special != CHAR_MINUS) @@ -653,6 +1241,13 @@ do ptr++; } + if (inangle) + { + if (ptr >= repend || *ptr != CHAR_GREATER_THAN_SIGN) + goto BAD; + ptr++; + } + /* Have found a syntactically correct group number or name, or *name. Only *MARK is currently recognized. */ @@ -663,10 +1258,14 @@ do PCRE2_SPTR mark = pcre2_get_mark(match_data); if (mark != NULL) { - PCRE2_SPTR mark_start = mark; - while (*mark != 0) mark++; - fraglength = mark - mark_start; - CHECKMEMCPY(mark_start, fraglength); + /* Peek backwards one code unit to obtain the length of the mark. + It can (theoretically) contain an embedded NUL. */ + fraglength = mark[-1]; + if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && + substitute_case_callout == NULL) + CHECKCASECPY_DEFAULT(mark, fraglength); + else + CHECKMEMCPY(mark, fraglength); } } else goto BAD; @@ -677,8 +1276,7 @@ do else { - PCRE2_SPTR subptr, subptrend; - + GROUP_SUBSTITUTE: /* Find a number for a named group. In case there are duplicate names, search for the first one that is set. If the name is not found when PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a @@ -775,41 +1373,14 @@ do /* Substitute a literal string, possibly forcing alphabetic case. */ - while (subptr < subptrend) - { - GETCHARINCTEST(ch, subptr); - if (forcecase != 0) - { -#ifdef SUPPORT_UNICODE - if (utf || ucp) - { - uint32_t type = UCD_CHARTYPE(ch); - if (PRIV(ucp_gentype)[type] == ucp_L && - type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) - ch = UCD_OTHERCASE(ch); - } - else -#endif - { - if (((code->tables + cbits_offset + - ((forcecase > 0)? cbit_upper:cbit_lower) - )[ch/8] & (1u << (ch%8))) == 0) - ch = (code->tables + fcc_offset)[ch]; - } - forcecase = forcecasereset; - } - -#ifdef SUPPORT_UNICODE - if (utf) chlen = PRIV(ord2utf)(ch, temp); else -#endif - { - temp[0] = ch; - chlen = 1; - } - CHECKMEMCPY(temp, chlen); - } + SUBPTR_SUBSTITUTE: + if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && + substitute_case_callout == NULL) + CHECKCASECPY_DEFAULT(subptr, subptrend - subptr); + else + CHECKMEMCPY(subptr, subptrend - subptr); } - } + } /* End of $ processing */ /* Handle an escape sequence in extended mode. We can use check_escape() to process \Q, \E, \c, \o, \x and \ followed by non-alphanumerics, but @@ -820,123 +1391,239 @@ do *ptr == CHAR_BACKSLASH) { int errorcode; + case_state new_forcecase = { PCRE2_SUBSTITUTE_CASE_NONE, FALSE }; if (ptr < repend - 1) switch (ptr[1]) { case CHAR_L: - forcecase = forcecasereset = -1; + new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_LOWER; + new_forcecase.single_char = FALSE; ptr += 2; - continue; + break; case CHAR_l: - forcecase = -1; - forcecasereset = 0; + new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_LOWER; + new_forcecase.single_char = TRUE; ptr += 2; - continue; + if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_U) + { + /* Perl reverse-title-casing feature for \l\U */ + new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST; + new_forcecase.single_char = FALSE; + ptr += 2; + } + break; case CHAR_U: - forcecase = forcecasereset = 1; + new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_UPPER; + new_forcecase.single_char = FALSE; ptr += 2; - continue; + break; case CHAR_u: - forcecase = 1; - forcecasereset = 0; + new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_TITLE_FIRST; + new_forcecase.single_char = TRUE; ptr += 2; - continue; + if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_L) + { + /* Perl title-casing feature for \u\L */ + new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_TITLE_FIRST; + new_forcecase.single_char = FALSE; + ptr += 2; + } + break; default: break; } + if (new_forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE) + { + SETFORCECASE: + + /* If the substitute_case_callout is unset, our case-forcing is done + immediately. If there is a callout however, then its action is delayed + until all the characters have been collected. + + Apply the callout now, before we set the new casing mode. */ + + if (substitute_case_callout != NULL && + forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE) + DELAYEDFORCECASE(); + + forcecase = new_forcecase; + casestart_offset = buff_offset; + casestart_extra_needed = extra_needed; + continue; + } + ptr++; /* Point after \ */ rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode, - code->overall_options, code->extra_options, FALSE, NULL); + code->overall_options, code->extra_options, code->top_bracket, FALSE, NULL); if (errorcode != 0) goto BADESCAPE; switch(rc) { case ESC_E: - forcecase = forcecasereset = 0; - continue; + goto SETFORCECASE; case ESC_Q: escaped_literal = TRUE; continue; case 0: /* Data character */ - goto LITERAL; + case ESC_b: /* \b is backspace in a substitution */ + case ESC_v: /* \v is vertical tab in a substitution */ + + if (rc == ESC_b) ch = CHAR_BS; + if (rc == ESC_v) ch = CHAR_VT; + +#ifdef SUPPORT_UNICODE + if (utf) chlen = PRIV(ord2utf)(ch, temp); else +#endif + { + temp[0] = ch; + chlen = 1; + } + + if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && + substitute_case_callout == NULL) + CHECKCASECPY_DEFAULT(temp, chlen); + else + CHECKMEMCPY(temp, chlen); + continue; + + case ESC_g: + { + PCRE2_SIZE name_len; + PCRE2_SPTR name_start; + + /* Parse the \g form (\g already handled by check_escape) */ + if (ptr >= repend || *ptr != CHAR_LESS_THAN_SIGN) + goto BADESCAPE; + ++ptr; + + name_start = ptr; + if (!read_name_subst(&ptr, repend, utf, code->tables + ctypes_offset)) + goto BADESCAPE; + name_len = ptr - name_start; + + if (ptr >= repend || *ptr != CHAR_GREATER_THAN_SIGN) + goto BADESCAPE; + ++ptr; + + special = 0; + group = -1; + memcpy(name, name_start, CU2BYTES(name_len)); + name[name_len] = 0; + goto GROUP_SUBSTITUTE; + } default: + if (rc < 0) + { + special = 0; + group = -rc - 1; + goto GROUP_SUBSTITUTE; + } goto BADESCAPE; } - } + } /* End of backslash processing */ /* Handle a literal code unit */ else { + PCRE2_SPTR ch_start; + LOADLITERAL: + ch_start = ptr; GETCHARINCTEST(ch, ptr); /* Get character value, increment pointer */ + (void) ch; - LITERAL: - if (forcecase != 0) - { -#ifdef SUPPORT_UNICODE - if (utf || ucp) - { - uint32_t type = UCD_CHARTYPE(ch); - if (PRIV(ucp_gentype)[type] == ucp_L && - type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) - ch = UCD_OTHERCASE(ch); - } - else -#endif - { - if (((code->tables + cbits_offset + - ((forcecase > 0)? cbit_upper:cbit_lower) - )[ch/8] & (1u << (ch%8))) == 0) - ch = (code->tables + fcc_offset)[ch]; - } - forcecase = forcecasereset; - } - -#ifdef SUPPORT_UNICODE - if (utf) chlen = PRIV(ord2utf)(ch, temp); else -#endif - { - temp[0] = ch; - chlen = 1; - } - CHECKMEMCPY(temp, chlen); + if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && + substitute_case_callout == NULL) + CHECKCASECPY_DEFAULT(ch_start, ptr - ch_start); + else + CHECKMEMCPY(ch_start, ptr - ch_start); } /* End handling a literal code unit */ } /* End of loop for scanning the replacement. */ + /* If the substitute_case_callout is unset, our case-forcing is done + immediately. If there is a callout however, then its action is delayed + until all the characters have been collected. + + We now clean up any trailing section of the replacement for which we deferred + the case-forcing. */ + + if (substitute_case_callout != NULL && + forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE) + DELAYEDFORCECASE(); + /* The replacement has been copied to the output, or its size has been - remembered. Do the callout if there is one and we have done an actual - replacement. */ + remembered. Handle the callout if there is one. */ - if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL) + if (mcontext != NULL && mcontext->substitute_callout != NULL) { - scb.subscount = subs; - scb.output_offsets[1] = buff_offset; - rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data); + /* If we an actual (non-simulated) replacement, do the callout. */ - /* A non-zero return means cancel this substitution. Instead, copy the - matched string fragment. */ + if (!overflowed) + { + scb.subscount = subs; + scb.output_offsets[1] = buff_offset; + rc = mcontext->substitute_callout(&scb, + mcontext->substitute_callout_data); - if (rc != 0) + /* A non-zero return means cancel this substitution. Instead, copy the + matched string fragment. */ + + if (rc != 0) + { + PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0]; + PCRE2_SIZE oldlength = ovector[1] - ovector[0]; + + buff_offset -= newlength; + lengthleft += newlength; + if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength); + + /* A negative return means do not do any more. */ + + if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL); + } + } + + /* In this interesting case, we cannot do the callout, so it's hard to + estimate the required buffer size. What callers want is to be able to make + two calls to pcre2_substitute(), once with PCRE2_SUBSTITUTE_OVERFLOW_LENGTH + to discover the buffer size, and then a second and final call. Older + versions of PCRE2 violated this assumption, by proceding as if the callout + had returned zero - but on the second call to pcre2_substitute() it could + return non-zero and then overflow the buffer again. Callers probably don't + want to keep on looping to incrementally discover the buffer size. */ + + else { - PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0]; + PCRE2_SIZE newlength_buf = buff_offset - scb.output_offsets[0]; + PCRE2_SIZE newlength_extra = extra_needed - sub_start_extra_needed; + PCRE2_SIZE newlength = + (newlength_extra > ~(PCRE2_SIZE)0 - newlength_buf)? /* Integer overflow */ + ~(PCRE2_SIZE)0 : newlength_buf + newlength_extra; /* Cap the addition */ PCRE2_SIZE oldlength = ovector[1] - ovector[0]; - buff_offset -= newlength; - lengthleft += newlength; - if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength); + /* Be pessimistic: request whichever buffer size is larger out of + accepting or rejecting the substitution. */ - /* A negative return means do not do any more. */ + if (oldlength > newlength) + { + PCRE2_SIZE additional = oldlength - newlength; + if (additional > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ + goto TOOLARGEREPLACE; + extra_needed += additional; + } - if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL); + /* Proceed as if the callout did not return a negative. A negative + effectively rejects all future substitutions, but we want to examine them + pessimistically. */ } } @@ -973,6 +1660,9 @@ needed. Otherwise, an overflow generates an immediate error return. */ if (overflowed) { rc = PCRE2_ERROR_NOMEMORY; + + if (extra_needed > ~(PCRE2_SIZE)0 - buff_length) /* Integer overflow */ + goto TOOLARGEREPLACE; *blength = buff_length + extra_needed; } @@ -994,6 +1684,14 @@ return rc; rc = PCRE2_ERROR_NOMEMORY; goto EXIT; +CASEERROR: +rc = PCRE2_ERROR_REPLACECASE; +goto EXIT; + +TOOLARGEREPLACE: +rc = PCRE2_ERROR_TOOLARGEREPLACE; +goto EXIT; + BAD: rc = PCRE2_ERROR_BADREPLACEMENT; goto PTREXIT; diff --git a/ext/pcre/pcre2lib/pcre2_substring.c b/ext/pcre/pcre2lib/pcre2_substring.c index 14e919dce9308..88afd2348bb3f 100644 --- a/ext/pcre/pcre2lib/pcre2_substring.c +++ b/ext/pcre/pcre2lib/pcre2_substring.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2023 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -486,7 +486,7 @@ pcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname, uint16_t bot = 0; uint16_t top = code->name_count; uint16_t entrysize = code->name_entry_size; -PCRE2_SPTR nametable = (PCRE2_SPTR)((char *)code + sizeof(pcre2_real_code)); +PCRE2_SPTR nametable = (PCRE2_SPTR)((const char *)code + sizeof(pcre2_real_code)); while (top > bot) { diff --git a/ext/pcre/pcre2lib/pcre2_ucd.c b/ext/pcre/pcre2lib/pcre2_ucd.c index 97dbc8b26f36a..4c5e5163b3a9a 100644 --- a/ext/pcre/pcre2lib/pcre2_ucd.c +++ b/ext/pcre/pcre2lib/pcre2_ucd.c @@ -72,11 +72,13 @@ const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0}}; const uint16_t PRIV(ucd_stage1)[] = {0}; const uint16_t PRIV(ucd_stage2)[] = {0}; const uint32_t PRIV(ucd_caseless_sets)[] = {0}; +const uint32_t PRIV(ucd_nocase_ranges)[] = {0}; +const uint32_t PRIV(ucd_nocase_ranges_size) = 0; #else -/* Total size: 112564 bytes, block size: 128. */ +/* Total size: 116564 bytes, block size: 128. */ -const char *PRIV(unicode_version) = "15.0.0"; +const char *PRIV(unicode_version) = "16.0.0"; /* When recompiling tables with a new Unicode version, please check the types in this structure definition with those in pcre2_internal.h (the actual field @@ -140,28 +142,87 @@ const uint32_t PRIV(ucd_caseless_sets)[] = { 0x004b, 0x006b, 0x212a, NOTACHAR, 0x00c5, 0x00e5, 0x212b, NOTACHAR, 0x1c88, 0xa64a, 0xa64b, NOTACHAR, + 0x0069, 0x0130, NOTACHAR, + 0x0049, 0x0131, NOTACHAR, }; +/* This is the index, within ucd_caseless_sets, of the additional +Turkish case-equivalences. The dotted I ones are this offset; the +dotless I are +3 from here. */ + +const uint32_t PRIV(ucd_turkish_dotted_i_caseset) = 112; + /* When #included in pcre2test, we don't need the table of digit sets, nor the the large main UCD tables. */ #ifndef PCRE2_PCRE2TEST +/* This table contains character ranges, where the characters in the range have +no other case. Both start and end values are excluded from the range. */ + +const uint32_t PRIV(ucd_nocase_ranges)[] = { + 0x0000, 0x0041, /* 64 */ + 0x007a, 0x00b5, /* 58 */ + 0x00b5, 0x00c0, /* 10 */ + 0x0292, 0x029d, /* 10 */ + 0x029e, 0x0345, /* 166 */ + 0x0345, 0x0370, /* 42 */ + 0x0481, 0x048a, /* 8 */ + 0x0556, 0x0561, /* 10 */ + 0x0586, 0x10a0, /* 2841 */ + 0x10ff, 0x13a0, /* 672 */ + 0x13fd, 0x1c80, /* 2178 */ + 0x1cbf, 0x1d79, /* 185 */ + 0x1d7d, 0x1d8e, /* 16 */ + 0x1d8e, 0x1e00, /* 113 */ + 0x1ffc, 0x2126, /* 297 */ + 0x2132, 0x214e, /* 27 */ + 0x214e, 0x2160, /* 17 */ + 0x2184, 0x24b6, /* 817 */ + 0x24e9, 0x2c00, /* 1814 */ + 0x2cf3, 0x2d00, /* 12 */ + 0x2d2d, 0xa640, /* 30994 */ + 0xa66d, 0xa680, /* 18 */ + 0xa69b, 0xa722, /* 134 */ + 0xa76f, 0xa779, /* 9 */ + 0xa7dc, 0xa7f5, /* 24 */ + 0xa7f6, 0xab53, /* 860 */ + 0xab53, 0xab70, /* 28 */ + 0xabbf, 0xfb05, /* 20293 */ + 0xfb06, 0xff21, /* 1050 */ + 0xff5a, 0x10400, /* 1189 */ + 0x1044f, 0x104b0, /* 96 */ + 0x104fb, 0x10570, /* 116 */ + 0x105bc, 0x10c80, /* 1731 */ + 0x10cb2, 0x10cc0, /* 13 */ + 0x10cf2, 0x10d50, /* 93 */ + 0x10d65, 0x10d70, /* 10 */ + 0x10d85, 0x118a0, /* 2842 */ + 0x118df, 0x16e40, /* 21856 */ + 0x16e7f, 0x1e900, /* 31360 */ + 0x1e943, 0x110000, /* 988860 */ + 0xffffffff, 0xffffffff /* terminator */ +}; + +/* Total: 1110933 characters. */ +const uint32_t PRIV(ucd_nocase_ranges_size) = 80; + /* This table lists the code points for the '9' characters in each set of decimal digits. It is used to ensure that all the digits in a script run come from the same set. */ const uint32_t PRIV(ucd_digit_sets)[] = { - 68, /* Number of subsequent values */ + 76, /* Number of subsequent values */ 0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef, 0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9, 0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89, 0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909, - 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f, - 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9, - 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x11f59, 0x16a69, - 0x16ac9, 0x16b59, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, - 0x1e2f9, 0x1e4f9, 0x1e959, 0x1fbf9, + 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x10d49, + 0x1106f, 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, + 0x116c9, 0x116d9, 0x116e3, 0x11739, 0x118e9, 0x11959, 0x11bf9, 0x11c59, + 0x11d59, 0x11da9, 0x11f59, 0x16139, 0x16a69, 0x16ac9, 0x16b59, 0x16d79, + 0x1ccf9, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, + 0x1e4f9, 0x1e5fa, 0x1e959, 0x1fbf9, }; /* This vector is a list of script bitsets for the Script Extension property. @@ -169,69 +230,117 @@ The number of 32-bit words in each bitset is #defined in pcre2_ucp.h as ucd_script_sets_item_size. */ const uint32_t PRIV(ucd_script_sets)[] = { - 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000080u, 0x00000000u, 0x00000000u, - 0x00000040u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00004000u, 0x00000000u, - 0x00000002u, 0x00000000u, 0x00000000u, - 0x00800000u, 0x00000000u, 0x00000000u, - 0x00000001u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00000000u, 0x00000001u, - 0x00000010u, 0x00000000u, 0x00000000u, - 0x00000008u, 0x00000004u, 0x00000000u, - 0x00000008u, 0x40000000u, 0x00000000u, - 0x00000008u, 0x00000040u, 0x00000000u, - 0x00000018u, 0x00000000u, 0x00000000u, - 0x00000028u, 0x00000000u, 0x00000000u, - 0x000000c0u, 0x00000000u, 0x00000000u, - 0x00c00000u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00000102u, 0x00000000u, - 0x80000000u, 0x00000001u, 0x00000000u, - 0x00000004u, 0x00000008u, 0x00000000u, - 0x00000005u, 0x00000000u, 0x00000000u, - 0x00000004u, 0x00200000u, 0x00000000u, - 0x00000014u, 0x00000000u, 0x00000000u, - 0x00000040u, 0x00008000u, 0x00000000u, - 0x00000040u, 0x00000000u, 0x00000001u, - 0x00000040u, 0x00001000u, 0x00000000u, - 0x00000840u, 0x00000000u, 0x00000000u, - 0x00020001u, 0x00000000u, 0x00000000u, - 0x00000800u, 0x00008000u, 0x00000000u, - 0x00000200u, 0x00010000u, 0x00000000u, - 0x00000100u, 0x02000000u, 0x00000000u, - 0x00800001u, 0x00000000u, 0x00000000u, - 0x00300000u, 0x00000000u, 0x00000000u, - 0x00002000u, 0x00000000u, 0x00000001u, - 0x00080001u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00080000u, 0x00000008u, - 0x00080000u, 0x00000020u, 0x00000000u, - 0x00000038u, 0x00000000u, 0x00000000u, - 0x00000028u, 0x00000000u, 0x00000002u, - 0x00000080u, 0x00000810u, 0x00000000u, - 0x40010000u, 0x00000800u, 0x00000000u, - 0x80000000u, 0x00000001u, 0x00000004u, - 0x80000000u, 0x00020001u, 0x00000000u, - 0x00002040u, 0x00008000u, 0x00000000u, - 0x00000041u, 0x00008000u, 0x00000000u, - 0x00b00000u, 0x00000000u, 0x00000000u, - 0x00010001u, 0x00000080u, 0x00000000u, - 0x000020c0u, 0x00008000u, 0x00000000u, - 0x1e000000u, 0x00000000u, 0x00000000u, - 0x00000040u, 0x10040200u, 0x00000000u, - 0x00f40000u, 0x00000000u, 0x00000000u, - 0x00000038u, 0x40000040u, 0x00000002u, - 0x01f40000u, 0x00000000u, 0x00000000u, - 0x00007c40u, 0x00000000u, 0x00000000u, - 0x00000038u, 0x44000040u, 0x00000002u, - 0x000034c0u, 0x01008000u, 0x00000001u, - 0x00000018u, 0xc4480400u, 0x00000008u, - 0x00000340u, 0x11952200u, 0x00000000u, - 0x00007fc1u, 0x01008000u, 0x00000000u, - 0x00007fc1u, 0x01009000u, 0x00000000u, - 0x00002340u, 0x11952200u, 0x00000001u, - 0x00006340u, 0x11952200u, 0x00000001u, - 0x0000ffc0u, 0x3984a010u, 0x00000001u, - 0x2000ffc0u, 0x3984a010u, 0x00000001u, + 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x40200003u, 0x00381901u, 0x00100246u, 0x00000000u, + 0x00040305u, 0x00800000u, 0x08000000u, 0x00000000u, + 0x20000001u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000001u, 0x00800000u, 0x00000000u, 0x00000000u, + 0x00040001u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x01000007u, 0x00000840u, 0x80000200u, 0x00000000u, + 0x01000007u, 0x00000040u, 0x80010000u, 0x00000001u, + 0x01000005u, 0x00002000u, 0x00000000u, 0x00000000u, + 0x00040041u, 0x00001000u, 0x80000000u, 0x00000000u, + 0x01000047u, 0x00002801u, 0x00010001u, 0x00000001u, + 0x10000001u, 0x00001801u, 0x00000004u, 0x00000000u, + 0x00000007u, 0x00000000u, 0x00000200u, 0x00000000u, + 0x00000051u, 0x00002840u, 0x00000202u, 0x00000001u, + 0x0000005fu, 0x00000041u, 0x00000202u, 0x00000000u, + 0x00000001u, 0x00002000u, 0x00000000u, 0x00000000u, + 0x00000041u, 0x00000000u, 0x00000002u, 0x00000000u, + 0x01000005u, 0x00000000u, 0x00010000u, 0x00000000u, + 0x01000001u, 0x00000040u, 0x00000000u, 0x00000000u, + 0x00000001u, 0x00000000u, 0x80000000u, 0x00000000u, + 0x00800001u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000005u, 0x00000000u, 0x00000000u, 0x00000001u, + 0x00000003u, 0x00000000u, 0x00000200u, 0x00000001u, + 0x00000041u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x11000041u, 0x00000000u, 0x00000002u, 0x00000000u, + 0x01000041u, 0x00000000u, 0x00000002u, 0x00000000u, + 0x00000041u, 0x00000000u, 0x80000000u, 0x00000000u, + 0x01000041u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x01040001u, 0x00000001u, 0x80000001u, 0x00000000u, + 0x00000002u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000001u, 0x00000000u, 0x00010000u, 0x00000000u, + 0x00000001u, 0x00000000u, 0x00000001u, 0x00000001u, + 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000002u, 0x00000800u, 0x00000000u, 0x00000000u, + 0x00000004u, 0x00000000u, 0x00000200u, 0x00000000u, + 0x00000004u, 0x00001000u, 0x00000000u, 0x00000000u, + 0x00000005u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00200008u, 0x00001000u, 0x00000000u, 0x00000000u, + 0x000000e0u, 0x00010000u, 0x11200000u, 0x00000000u, + 0x000000e0u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x000000e0u, 0x00010000u, 0x11208000u, 0x00000000u, + 0x00000060u, 0x08000000u, 0x04608480u, 0x00000000u, + 0x00000060u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x000000a0u, 0x00000000u, 0x01000000u, 0x00000000u, + 0x00000020u, 0x00000000u, 0x00200000u, 0x00000000u, + 0x0001ff01u, 0x40000000u, 0x00001008u, 0x00000000u, + 0x0001ff01u, 0x00000000u, 0x00001008u, 0x00000000u, + 0x0003ff00u, 0x80004000u, 0x409c1848u, 0x00000000u, + 0x0003ff00u, 0x80004020u, 0x609c1848u, 0x00000000u, + 0x00000100u, 0x04000000u, 0x00080040u, 0x00000000u, + 0x00000200u, 0x10004000u, 0x00000000u, 0x00000000u, + 0x00000400u, 0x00000000u, 0x00002000u, 0x00000000u, + 0x00000800u, 0x00000000u, 0x00000010u, 0x00000000u, + 0x00002000u, 0x00000000u, 0x00000008u, 0x00000000u, + 0x00008000u, 0x00000000u, 0x00800000u, 0x00000002u, + 0x00100000u, 0x10000040u, 0x00000000u, 0x00000000u, + 0x00200001u, 0x00001000u, 0x00000000u, 0x00000000u, + 0x02000000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x0000001eu, 0x00000000u, 0x00000000u, + 0x04000000u, 0x00008000u, 0x00000000u, 0x00000000u, + 0x00008300u, 0x00000000u, 0x00000008u, 0x00000000u, + 0x00000100u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00008100u, 0x00000000u, 0x00000008u, 0x00000000u, + 0x00000300u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000100u, 0x40000000u, 0x00000000u, 0x00000000u, + 0x0001f100u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000100u, 0x00000000u, 0x00800000u, 0x00000000u, + 0x0003d300u, 0x00000000u, 0x00801008u, 0x00000002u, + 0x00000100u, 0x00000000u, 0x00000008u, 0x00000000u, + 0x00008100u, 0x00000000u, 0x00000008u, 0x00000002u, + 0x00000200u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, 0x00800000u, 0x00000000u, + 0x00000045u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000040u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x04000001u, 0x00008000u, 0x00000000u, 0x00000000u, + 0x00000020u, 0x00000000u, 0x00008000u, 0x00000000u, + 0x00200000u, 0x020c1000u, 0x00004000u, 0x00000000u, + 0x00000002u, 0x20080000u, 0x00004000u, 0x00000000u, + 0x00000101u, 0x00000000u, 0x00000008u, 0x00000000u, + 0x00000001u, 0x00000800u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x02200000u, 0x00000000u, 0x00000000u, + 0x00200000u, 0x04780000u, 0x00004000u, 0x00000000u, + 0x00000000u, 0x00000000u, 0x00000002u, 0x00000000u, + 0x00000020u, 0x00000000u, 0x0000c000u, 0x00000000u, + 0x40000000u, 0x00000000u, 0x00020000u, 0x00000000u, + 0xfc400000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0xfc400000u, 0x00008000u, 0x00000000u, 0x00000000u, + 0x78400000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x40000000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0xfc480000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0xfc480000u, 0x00800000u, 0x00000000u, 0x00000000u, + 0xf8400000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x60000000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x18000000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x58000000u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x40000001u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00018d00u, 0xc4000000u, 0x00881950u, 0x00000002u, + 0x00008d00u, 0xc4000000u, 0x00881950u, 0x00000002u, + 0x00000d00u, 0x84000000u, 0x00081950u, 0x00000000u, + 0x00000d00u, 0xc4000000u, 0x00081950u, 0x00000000u, + 0x00000300u, 0x00000000u, 0x00000000u, 0x00000002u, + 0x00002100u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00100001u, 0x00020000u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x01000400u, 0x00000000u, 0x00000000u, + 0x00000020u, 0x00010000u, 0x00000000u, 0x00000000u, + 0x000000a0u, 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000280u, 0x02000000u, 0x00000000u, + 0x00000000u, 0x00000280u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000280u, 0x00000020u, 0x00000000u, + 0x00000020u, 0x00000800u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, 0x04000080u, 0x00000000u, }; /* This vector is a list of bitsets for Boolean properties. The number of @@ -241,181 +350,196 @@ pcre2_ucp.h. */ const uint32_t PRIV(ucd_boolprop_sets)[] = { 0x00000000u, 0x00000000u, 0x00000001u, 0x00000000u, - 0x00000001u, 0x00020040u, - 0x00800001u, 0x00020040u, - 0x00800001u, 0x00002820u, - 0x00800001u, 0x00000120u, - 0x00830001u, 0x00000020u, - 0x00800001u, 0x00000020u, - 0x00800021u, 0x00000120u, - 0x00800011u, 0x00000020u, - 0x00800001u, 0x00000028u, - 0x00800001u, 0x00002020u, - 0x00801001u, 0x00000020u, - 0x00800021u, 0x00002820u, - 0x24830003u, 0x00040000u, - 0x00800021u, 0x00002020u, - 0x00800011u, 0x00000028u, - 0x648003c7u, 0x000c8000u, - 0x608003c5u, 0x000c8000u, - 0x00808021u, 0x00000028u, - 0x20800001u, 0x00040000u, - 0x00808021u, 0x00000020u, - 0x64800d47u, 0x000c0004u, - 0x60800d45u, 0x000c0004u, - 0x60800d45u, 0x000c1004u, - 0x00000000u, 0x00020040u, - 0x00800000u, 0x00020000u, - 0x00800000u, 0x00000020u, + 0x00000001u, 0x00400800u, + 0x00800001u, 0x00400800u, + 0x00800001u, 0x00050400u, + 0x00800001u, 0x00002400u, + 0x00830001u, 0x00000400u, + 0x00800001u, 0x00000400u, + 0x00800021u, 0x00002400u, + 0x00800011u, 0x00000400u, + 0x00800001u, 0x00000480u, + 0x00800001u, 0x00040400u, + 0x00801001u, 0x00000400u, + 0x00800021u, 0x00050400u, + 0x04830003u, 0x00800001u, + 0x00800021u, 0x00040400u, + 0x00800011u, 0x00000480u, + 0x048003c7u, 0x01900003u, + 0x008003c5u, 0x01900003u, + 0x00808021u, 0x00000480u, + 0x00800001u, 0x00800001u, + 0x00808021u, 0x00000400u, + 0x04800d47u, 0x01800043u, + 0x00800d45u, 0x01800043u, + 0x00800d45u, 0x01820043u, + 0x00000000u, 0x00400800u, + 0x00800000u, 0x00400000u, + 0x00800000u, 0x00000400u, 0x00808020u, 0x00000000u, - 0x00a10000u, 0x00000020u, - 0x60800044u, 0x000c0004u, - 0x00800010u, 0x00000120u, - 0x00800000u, 0x00000028u, + 0x00a10000u, 0x00000400u, + 0x00800044u, 0x01800043u, + 0x00800010u, 0x00002400u, + 0x00800000u, 0x00000480u, 0x00002020u, 0x00000000u, + 0x40800000u, 0x00000000u, + 0x00800dc4u, 0x01800043u, + 0x00c08020u, 0x00800001u, 0x00800000u, 0x00000000u, - 0x60800dc4u, 0x000c0004u, - 0x20c08020u, 0x00040000u, - 0x608003c4u, 0x000c8000u, - 0x60800d44u, 0x000c0004u, - 0x60800d44u, 0x000c1004u, - 0x60804dc4u, 0x000c0004u, - 0x60800004u, 0x000c0000u, - 0x608007c4u, 0x000c8000u, - 0x60800bc4u, 0x000c0000u, - 0x60808064u, 0x000c0004u, - 0x60808064u, 0x000c1004u, - 0x60808024u, 0x000c0000u, - 0x60c08024u, 0x000c0000u, - 0x21008020u, 0x00040000u, - 0x21008de4u, 0x00040004u, - 0x21002020u, 0x00040000u, - 0x21000020u, 0x00040000u, - 0x60808064u, 0x00000004u, - 0x00800000u, 0x00002000u, - 0x20800020u, 0x00042000u, - 0x60800dc4u, 0x000c000cu, - 0x60800044u, 0x000c8008u, - 0x60800044u, 0x000c8000u, - 0x608003c4u, 0x000c8008u, - 0x00800000u, 0x00000008u, - 0x01000020u, 0x00000000u, + 0x008003c4u, 0x01900003u, + 0x00800d44u, 0x01800043u, + 0x00800d44u, 0x01820043u, + 0x00804dc4u, 0x01800043u, + 0x00800004u, 0x01800003u, + 0x008007c4u, 0x01900003u, + 0x00800bc4u, 0x01800003u, + 0x00808064u, 0x01800043u, + 0x00808064u, 0x01820043u, + 0x00808024u, 0x01800003u, + 0x00c08024u, 0x01800003u, + 0x01008020u, 0x00800009u, + 0x01008de4u, 0x00800049u, + 0x01002020u, 0x00800009u, + 0x01000020u, 0x00800009u, + 0x01000024u, 0x00800009u, + 0x00808064u, 0x00000043u, + 0x00800000u, 0x00040000u, + 0x00800020u, 0x00840001u, + 0x00800dc4u, 0x018000c3u, + 0x00800044u, 0x01900083u, + 0x00800044u, 0x01900003u, + 0x008003c4u, 0x01900083u, + 0x00800000u, 0x00000080u, + 0x01000020u, 0x00000008u, 0x00800020u, 0x00000000u, - 0x00800000u, 0x00002800u, + 0x00800000u, 0x00050000u, 0x00801000u, 0x00000000u, - 0x21008024u, 0x00040000u, - 0x21000024u, 0x00040000u, - 0x00000020u, 0x00000080u, + 0x01008024u, 0x00800009u, + 0x00000020u, 0x00001000u, 0x00002028u, 0x00000000u, - 0x60c00024u, 0x000c0000u, - 0x20800000u, 0x00040000u, - 0x60804004u, 0x000c0000u, - 0x60800024u, 0x000c0000u, - 0x20800004u, 0x00040000u, - 0x23008020u, 0x00040000u, - 0x21000004u, 0x00040000u, - 0x21408020u, 0x00040000u, - 0x60800004u, 0x00040000u, - 0x23000024u, 0x00040000u, - 0x60800004u, 0x000c0002u, + 0x00c00024u, 0x01800003u, + 0x01000024u, 0x00800109u, + 0x01008020u, 0x00800109u, + 0x00800000u, 0x00800001u, + 0x00804004u, 0x01800003u, + 0x00800024u, 0x01800003u, + 0x01000020u, 0x00800109u, + 0x01008024u, 0x00800109u, + 0x00800004u, 0x00800001u, + 0x00800004u, 0x0180000bu, + 0x03008020u, 0x00800009u, + 0x01000004u, 0x00800009u, + 0x01400024u, 0x00800009u, + 0x01408020u, 0x00800009u, + 0x00800004u, 0x00800003u, + 0x03008024u, 0x00800009u, + 0x00800004u, 0x01800023u, 0x00800010u, 0x00000000u, - 0x20808000u, 0x00040000u, - 0x21004024u, 0x00040000u, - 0x20808004u, 0x00040000u, - 0x60800944u, 0x000c0004u, - 0x60800064u, 0x000c0004u, - 0x60802004u, 0x000c0000u, - 0x60800344u, 0x000c8000u, - 0x22808000u, 0x00040000u, - 0x22800000u, 0x00040000u, + 0x00808000u, 0x00800001u, + 0x01004024u, 0x00800009u, + 0x00808004u, 0x00800001u, + 0x00800944u, 0x01800043u, + 0x00800064u, 0x01800043u, + 0x00802004u, 0x01800003u, + 0x00800344u, 0x01900003u, + 0x03008000u, 0x00800009u, 0x00c00000u, 0x00000000u, - 0x21002020u, 0x00050000u, - 0x61000024u, 0x000c0000u, - 0x23000020u, 0x00040000u, - 0x01008020u, 0x00000000u, - 0x21408024u, 0x00040000u, + 0x01002020u, 0x00a00009u, + 0x01000024u, 0x0180000bu, + 0x01008020u, 0x00000008u, + 0x01408024u, 0x00800009u, 0x00808000u, 0x00000000u, - 0x60800044u, 0x000c1004u, - 0x60800064u, 0x000c1004u, - 0x01002020u, 0x00000001u, - 0x00022020u, 0x00000001u, - 0x00002028u, 0x00000040u, - 0x00801000u, 0x00000020u, - 0x00800020u, 0x00000120u, - 0x00800000u, 0x00000120u, - 0x00800020u, 0x00000020u, - 0x00a10000u, 0x00002820u, - 0x00800000u, 0x00002820u, - 0x20800000u, 0x00040008u, - 0x00800010u, 0x00000020u, - 0x00002020u, 0x00000008u, + 0x00800044u, 0x01820043u, + 0x00800064u, 0x01820043u, + 0x01002020u, 0x00800011u, + 0x00022020u, 0x00800019u, + 0x00002028u, 0x00000800u, + 0x00801000u, 0x00000400u, + 0x00800020u, 0x00002400u, + 0x00800000u, 0x00002400u, + 0x00800020u, 0x00050400u, + 0x00800020u, 0x00000400u, + 0x00a10000u, 0x00050400u, + 0x00800000u, 0x00050400u, + 0x00800000u, 0x00800081u, + 0x00800010u, 0x00000400u, + 0x00002020u, 0x00000080u, 0x00002000u, 0x00000000u, 0x00006020u, 0x00000000u, - 0x00801000u, 0x00000008u, - 0x00800010u, 0x00000008u, - 0x21000020u, 0x00040008u, - 0x01020020u, 0x00000000u, - 0x60800044u, 0x000c000cu, - 0x60800000u, 0x000c0008u, + 0x40800000u, 0x00000080u, + 0x40801000u, 0x00000080u, + 0x40800010u, 0x00000080u, + 0x01000020u, 0x00800089u, + 0x01020020u, 0x00000008u, + 0x00800044u, 0x018000c3u, + 0x00800000u, 0x01800083u, 0x00a10000u, 0x00000000u, - 0x60800000u, 0x000c0000u, - 0x60800004u, 0x000c0008u, - 0x60a10044u, 0x000c0004u, - 0x60800044u, 0x000c100cu, - 0x00a10000u, 0x00000028u, - 0x00800010u, 0x00000028u, - 0x00801000u, 0x00000028u, - 0x00b10000u, 0x00000020u, - 0x00804010u, 0x00000020u, - 0x00a00000u, 0x00000020u, - 0x00000000u, 0x00000020u, - 0x008003c4u, 0x00008000u, - 0x00a103c4u, 0x00008000u, - 0x00800d44u, 0x00000004u, - 0x00b10000u, 0x00000028u, - 0x00a00000u, 0x00000028u, - 0x00a90000u, 0x00000020u, - 0x00b90000u, 0x00000020u, - 0x00808024u, 0x00000020u, - 0x00800000u, 0x00002020u, - 0x00800000u, 0x00000200u, + 0x00800000u, 0x01800003u, + 0x00800004u, 0x01800083u, + 0x00a10044u, 0x01800043u, + 0x00800044u, 0x018200c3u, + 0x00a10000u, 0x00000480u, + 0xc0800000u, 0x00000480u, + 0x00800010u, 0x00000480u, + 0x00801000u, 0x00000480u, + 0x00b10000u, 0x00000400u, + 0x00804010u, 0x00000400u, + 0x00a00000u, 0x00000400u, + 0x00000000u, 0x00000400u, + 0x008003c4u, 0x00100000u, + 0x00a103c4u, 0x00100000u, + 0x00800d44u, 0x00000040u, + 0x00b10000u, 0x00000480u, + 0x00a00000u, 0x00000480u, + 0x00a90000u, 0x00000400u, + 0x00b90000u, 0x00000400u, + 0x03000020u, 0x00800009u, + 0x00808024u, 0x00000400u, + 0x00800000u, 0x00040400u, + 0x00800000u, 0x00004000u, 0x08800000u, 0x00000000u, 0x10800000u, 0x00000000u, - 0xe0800004u, 0x000c0000u, - 0x21008000u, 0x00040000u, - 0x00a11000u, 0x00000020u, - 0x60808020u, 0x00000000u, - 0xe0800004u, 0x000c4000u, - 0x60808004u, 0x000c0000u, - 0x60800004u, 0x00000000u, - 0x00000000u, 0x00000010u, - 0x21022020u, 0x00050000u, - 0x00800000u, 0x00000100u, - 0x00800020u, 0x00002800u, + 0x20800000u, 0x00000000u, + 0x00800004u, 0x01800007u, + 0x01008000u, 0x00800009u, + 0x00a11000u, 0x00000400u, + 0x00808020u, 0x00000003u, + 0x00800004u, 0x01880007u, + 0x00808004u, 0x01800003u, + 0x00800004u, 0x00000003u, + 0x00000000u, 0x00000200u, + 0x01022020u, 0x00a00009u, + 0x00800000u, 0x00002000u, + 0x00800020u, 0x00050000u, + 0x00800020u, 0x00040000u, + 0x00801000u, 0x00000080u, + 0x00800010u, 0x00000080u, 0x00800020u, 0x00002000u, - 0x00800020u, 0x00000100u, - 0x24800000u, 0x00040000u, - 0x648003c4u, 0x000c8000u, - 0x00808020u, 0x00000008u, - 0x64800d44u, 0x000c0004u, - 0x00800010u, 0x00000100u, - 0x61008024u, 0x00040000u, + 0x04800000u, 0x00800001u, + 0x048003c4u, 0x01900003u, + 0x00808020u, 0x00000080u, + 0x04800d44u, 0x01800043u, + 0x00800010u, 0x00002000u, + 0x01008024u, 0x0080000bu, 0x00000020u, 0x00000000u, - 0x60c00004u, 0x000c0000u, - 0x21400020u, 0x00040000u, - 0xa1000020u, 0x00040000u, - 0x21000000u, 0x00040000u, + 0x00c00004u, 0x01800003u, + 0x00c08004u, 0x01800003u, + 0x01400020u, 0x00800009u, + 0x01000020u, 0x0080000du, + 0x01008004u, 0x00800009u, + 0x01000000u, 0x00800009u, + 0xc0800000u, 0x00000080u, 0x00a00000u, 0x00000000u, 0x00b10000u, 0x00000000u, 0x00200000u, 0x00000000u, - 0x00800044u, 0x00008000u, - 0x00a10044u, 0x00008000u, - 0x00930000u, 0x00000400u, + 0x00800044u, 0x00100000u, + 0x00a10044u, 0x00100000u, + 0x00930000u, 0x00008000u, 0x00b90000u, 0x00000000u, 0x00a90000u, 0x00000000u, - 0x00970020u, 0x00000000u, + 0x00970020u, 0x00000008u, 0x00b30000u, 0x00000000u, - 0x01022020u, 0x00000000u, + 0x01022020u, 0x00000008u, }; /* These are the main two-stage UCD tables. The fields in each record are: @@ -424,1430 +548,1550 @@ offset to multichar other cases or zero (8 bits), offset to other case or zero (32 bits, signed), bidi class (5 bits) and script extension (11 bits) packed into a 16-bit field, and offset in binary properties table (16 bits). */ -const ucd_record PRIV(ucd_records)[] = { /* 17076 bytes, record size 12 */ - { 69, 0, 2, 0, 0, 6144, 2, }, /* 0 */ - { 69, 0, 2, 0, 0, 43008, 4, }, /* 1 */ - { 69, 0, 1, 0, 0, 4096, 4, }, /* 2 */ - { 69, 0, 2, 0, 0, 45056, 4, }, /* 3 */ - { 69, 0, 0, 0, 0, 4096, 4, }, /* 4 */ - { 69, 0, 2, 0, 0, 4096, 2, }, /* 5 */ - { 69, 0, 2, 0, 0, 43008, 2, }, /* 6 */ - { 69, 29, 12, 0, 0, 45056, 6, }, /* 7 */ - { 69, 21, 12, 0, 0, 28672, 8, }, /* 8 */ - { 69, 21, 12, 0, 0, 28672, 10, }, /* 9 */ - { 69, 21, 12, 0, 0, 14336, 12, }, /* 10 */ - { 69, 23, 12, 0, 0, 14336, 14, }, /* 11 */ - { 69, 21, 12, 0, 0, 14336, 14, }, /* 12 */ - { 69, 21, 12, 0, 0, 28672, 14, }, /* 13 */ - { 69, 21, 12, 0, 0, 28672, 16, }, /* 14 */ - { 69, 22, 12, 0, 0, 28672, 18, }, /* 15 */ - { 69, 18, 12, 0, 0, 28672, 18, }, /* 16 */ - { 69, 21, 12, 0, 0, 28672, 12, }, /* 17 */ - { 69, 25, 12, 0, 0, 12288, 20, }, /* 18 */ - { 69, 21, 12, 0, 0, 8192, 22, }, /* 19 */ - { 69, 17, 12, 0, 0, 12288, 24, }, /* 20 */ - { 69, 21, 12, 0, 0, 8192, 26, }, /* 21 */ - { 69, 21, 12, 0, 0, 8192, 14, }, /* 22 */ - { 69, 13, 12, 0, 0, 10240, 28, }, /* 23 */ - { 69, 21, 12, 0, 0, 8192, 30, }, /* 24 */ - { 69, 21, 12, 0, 0, 28672, 22, }, /* 25 */ - { 69, 25, 12, 0, 0, 28672, 32, }, /* 26 */ - { 69, 25, 12, 0, 0, 28672, 20, }, /* 27 */ +const ucd_record PRIV(ucd_records)[] = { /* 18516 bytes, record size 12 */ + { 99, 0, 2, 0, 0, 6144, 2, }, /* 0 */ + { 99, 0, 2, 0, 0, 43008, 4, }, /* 1 */ + { 99, 0, 1, 0, 0, 4096, 4, }, /* 2 */ + { 99, 0, 2, 0, 0, 45056, 4, }, /* 3 */ + { 99, 0, 0, 0, 0, 4096, 4, }, /* 4 */ + { 99, 0, 2, 0, 0, 4096, 2, }, /* 5 */ + { 99, 0, 2, 0, 0, 43008, 2, }, /* 6 */ + { 99, 29, 12, 0, 0, 45056, 6, }, /* 7 */ + { 99, 21, 12, 0, 0, 28672, 8, }, /* 8 */ + { 99, 21, 12, 0, 0, 28672, 10, }, /* 9 */ + { 99, 21, 12, 0, 0, 14336, 12, }, /* 10 */ + { 99, 23, 12, 0, 0, 14336, 14, }, /* 11 */ + { 99, 21, 12, 0, 0, 14336, 14, }, /* 12 */ + { 99, 21, 12, 0, 0, 28672, 14, }, /* 13 */ + { 99, 21, 12, 0, 0, 28672, 16, }, /* 14 */ + { 99, 22, 12, 0, 0, 28672, 18, }, /* 15 */ + { 99, 18, 12, 0, 0, 28672, 18, }, /* 16 */ + { 99, 21, 12, 0, 0, 28672, 12, }, /* 17 */ + { 99, 25, 12, 0, 0, 12288, 20, }, /* 18 */ + { 99, 21, 12, 0, 0, 8192, 22, }, /* 19 */ + { 99, 17, 12, 0, 0, 12288, 24, }, /* 20 */ + { 99, 21, 12, 0, 0, 8192, 26, }, /* 21 */ + { 99, 21, 12, 0, 0, 8192, 14, }, /* 22 */ + { 99, 13, 12, 0, 0, 10240, 28, }, /* 23 */ + { 99, 21, 12, 0, 0, 8192, 30, }, /* 24 */ + { 99, 21, 12, 0, 0, 28672, 22, }, /* 25 */ + { 99, 25, 12, 0, 0, 28672, 32, }, /* 26 */ + { 99, 25, 12, 0, 0, 28672, 20, }, /* 27 */ { 0, 9, 12, 0, 32, 18432, 34, }, /* 28 */ { 0, 9, 12, 0, 32, 18432, 36, }, /* 29 */ { 0, 9, 12, 100, 32, 18432, 36, }, /* 30 */ { 0, 9, 12, 1, 32, 18432, 36, }, /* 31 */ - { 69, 24, 12, 0, 0, 28672, 38, }, /* 32 */ - { 69, 16, 12, 0, 0, 28672, 40, }, /* 33 */ - { 69, 24, 12, 0, 0, 28672, 42, }, /* 34 */ + { 99, 24, 12, 0, 0, 28672, 38, }, /* 32 */ + { 99, 16, 12, 0, 0, 28672, 40, }, /* 33 */ + { 99, 24, 12, 0, 0, 28672, 42, }, /* 34 */ { 0, 5, 12, 0, -32, 18432, 44, }, /* 35 */ { 0, 5, 12, 0, -32, 18432, 46, }, /* 36 */ { 0, 5, 12, 0, -32, 18432, 48, }, /* 37 */ { 0, 5, 12, 100, -32, 18432, 46, }, /* 38 */ { 0, 5, 12, 1, -32, 18432, 46, }, /* 39 */ - { 69, 0, 2, 0, 0, 6144, 0, }, /* 40 */ - { 69, 0, 2, 0, 0, 4096, 50, }, /* 41 */ - { 69, 29, 12, 0, 0, 8192, 52, }, /* 42 */ - { 69, 21, 12, 0, 0, 28672, 54, }, /* 43 */ - { 69, 23, 12, 0, 0, 14336, 54, }, /* 44 */ - { 69, 26, 12, 0, 0, 28672, 54, }, /* 45 */ - { 69, 24, 12, 0, 0, 28672, 56, }, /* 46 */ - { 69, 26, 14, 0, 0, 28672, 58, }, /* 47 */ + { 99, 0, 2, 0, 0, 6144, 0, }, /* 40 */ + { 99, 0, 2, 0, 0, 4096, 50, }, /* 41 */ + { 99, 29, 12, 0, 0, 8192, 52, }, /* 42 */ + { 99, 21, 12, 0, 0, 28672, 54, }, /* 43 */ + { 99, 23, 12, 0, 0, 14336, 54, }, /* 44 */ + { 99, 26, 12, 0, 0, 28672, 54, }, /* 45 */ + { 99, 24, 12, 0, 0, 28672, 56, }, /* 46 */ + { 99, 26, 14, 0, 0, 28672, 58, }, /* 47 */ { 0, 7, 12, 0, 0, 18432, 60, }, /* 48 */ - { 69, 20, 12, 0, 0, 28672, 62, }, /* 49 */ - { 69, 25, 12, 0, 0, 28672, 64, }, /* 50 */ - { 69, 1, 2, 0, 0, 6144, 66, }, /* 51 */ - { 69, 26, 12, 0, 0, 14336, 54, }, /* 52 */ - { 69, 25, 12, 0, 0, 14336, 64, }, /* 53 */ - { 69, 15, 12, 0, 0, 10240, 68, }, /* 54 */ - { 69, 5, 12, 26, 775, 18432, 70, }, /* 55 */ - { 69, 21, 12, 0, 0, 28672, 72, }, /* 56 */ - { 69, 19, 12, 0, 0, 28672, 62, }, /* 57 */ - { 69, 15, 12, 0, 0, 28672, 68, }, /* 58 */ - { 0, 9, 12, 0, 32, 18432, 74, }, /* 59 */ - { 0, 9, 12, 104, 32, 18432, 74, }, /* 60 */ + { 99, 20, 12, 0, 0, 28672, 62, }, /* 49 */ + { 99, 25, 12, 0, 0, 28672, 64, }, /* 50 */ + { 99, 1, 2, 0, 0, 6144, 66, }, /* 51 */ + { 99, 26, 12, 0, 0, 14336, 54, }, /* 52 */ + { 99, 25, 12, 0, 0, 14336, 64, }, /* 53 */ + { 99, 15, 12, 0, 0, 10240, 68, }, /* 54 */ + { 99, 5, 12, 26, 775, 18432, 70, }, /* 55 */ + { 99, 21, 12, 0, 0, 28676, 72, }, /* 56 */ + { 99, 19, 12, 0, 0, 28672, 62, }, /* 57 */ + { 99, 15, 12, 0, 0, 28672, 74, }, /* 58 */ + { 0, 9, 12, 0, 32, 18432, 76, }, /* 59 */ + { 0, 9, 12, 104, 32, 18432, 76, }, /* 60 */ { 0, 5, 12, 0, 7615, 18432, 70, }, /* 61 */ - { 0, 5, 12, 0, -32, 18432, 76, }, /* 62 */ - { 0, 5, 12, 104, -32, 18432, 76, }, /* 63 */ - { 0, 5, 12, 0, 121, 18432, 76, }, /* 64 */ - { 0, 9, 12, 0, 1, 18432, 74, }, /* 65 */ - { 0, 5, 12, 0, -1, 18432, 76, }, /* 66 */ - { 0, 5, 12, 0, -1, 18432, 78, }, /* 67 */ - { 0, 9, 12, 0, 0, 18432, 74, }, /* 68 */ - { 0, 5, 12, 0, 0, 18432, 76, }, /* 69 */ + { 0, 5, 12, 0, -32, 18432, 78, }, /* 62 */ + { 0, 5, 12, 104, -32, 18432, 78, }, /* 63 */ + { 0, 5, 12, 0, 121, 18432, 78, }, /* 64 */ + { 0, 9, 12, 0, 1, 18432, 76, }, /* 65 */ + { 0, 5, 12, 0, -1, 18432, 78, }, /* 66 */ + { 0, 5, 12, 0, -1, 18432, 80, }, /* 67 */ + { 0, 9, 12, 0, 0, 18432, 76, }, /* 68 */ + { 0, 5, 12, 0, 0, 18432, 78, }, /* 69 */ { 0, 5, 12, 0, 0, 18432, 60, }, /* 70 */ - { 0, 5, 12, 0, 0, 18432, 80, }, /* 71 */ - { 0, 9, 12, 0, -121, 18432, 74, }, /* 72 */ + { 0, 5, 12, 0, 0, 18432, 82, }, /* 71 */ + { 0, 9, 12, 0, -121, 18432, 76, }, /* 72 */ { 0, 5, 12, 1, 0, 18432, 70, }, /* 73 */ - { 0, 5, 12, 0, 195, 18432, 76, }, /* 74 */ - { 0, 9, 12, 0, 210, 18432, 74, }, /* 75 */ - { 0, 9, 12, 0, 206, 18432, 74, }, /* 76 */ - { 0, 9, 12, 0, 205, 18432, 74, }, /* 77 */ - { 0, 9, 12, 0, 79, 18432, 74, }, /* 78 */ - { 0, 9, 12, 0, 202, 18432, 74, }, /* 79 */ - { 0, 9, 12, 0, 203, 18432, 74, }, /* 80 */ - { 0, 9, 12, 0, 207, 18432, 74, }, /* 81 */ - { 0, 5, 12, 0, 97, 18432, 76, }, /* 82 */ - { 0, 9, 12, 0, 211, 18432, 74, }, /* 83 */ - { 0, 9, 12, 0, 209, 18432, 74, }, /* 84 */ - { 0, 5, 12, 0, 163, 18432, 76, }, /* 85 */ - { 0, 9, 12, 0, 213, 18432, 74, }, /* 86 */ - { 0, 5, 12, 0, 130, 18432, 76, }, /* 87 */ - { 0, 9, 12, 0, 214, 18432, 74, }, /* 88 */ - { 0, 9, 12, 0, 218, 18432, 74, }, /* 89 */ - { 0, 9, 12, 0, 217, 18432, 74, }, /* 90 */ - { 0, 9, 12, 0, 219, 18432, 74, }, /* 91 */ - { 0, 7, 12, 0, 0, 18432, 82, }, /* 92 */ - { 0, 5, 12, 0, 56, 18432, 76, }, /* 93 */ - { 0, 9, 12, 5, 2, 18432, 84, }, /* 94 */ - { 0, 8, 12, 5, 1, 18432, 86, }, /* 95 */ - { 0, 5, 12, 5, -2, 18432, 76, }, /* 96 */ - { 0, 9, 12, 9, 2, 18432, 84, }, /* 97 */ - { 0, 8, 12, 9, 1, 18432, 86, }, /* 98 */ - { 0, 5, 12, 9, -2, 18432, 76, }, /* 99 */ - { 0, 9, 12, 13, 2, 18432, 84, }, /* 100 */ - { 0, 8, 12, 13, 1, 18432, 86, }, /* 101 */ - { 0, 5, 12, 13, -2, 18432, 76, }, /* 102 */ - { 0, 5, 12, 0, -79, 18432, 76, }, /* 103 */ - { 0, 9, 12, 17, 2, 18432, 84, }, /* 104 */ - { 0, 8, 12, 17, 1, 18432, 86, }, /* 105 */ - { 0, 5, 12, 17, -2, 18432, 76, }, /* 106 */ - { 0, 9, 12, 0, -97, 18432, 74, }, /* 107 */ - { 0, 9, 12, 0, -56, 18432, 74, }, /* 108 */ - { 0, 9, 12, 0, -130, 18432, 74, }, /* 109 */ - { 0, 9, 12, 0, 10795, 18432, 74, }, /* 110 */ - { 0, 9, 12, 0, -163, 18432, 74, }, /* 111 */ - { 0, 9, 12, 0, 10792, 18432, 74, }, /* 112 */ - { 0, 5, 12, 0, 10815, 18432, 76, }, /* 113 */ - { 0, 9, 12, 0, -195, 18432, 74, }, /* 114 */ - { 0, 9, 12, 0, 69, 18432, 74, }, /* 115 */ - { 0, 9, 12, 0, 71, 18432, 74, }, /* 116 */ - { 0, 5, 12, 0, 10783, 18432, 76, }, /* 117 */ - { 0, 5, 12, 0, 10780, 18432, 76, }, /* 118 */ - { 0, 5, 12, 0, 10782, 18432, 76, }, /* 119 */ - { 0, 5, 12, 0, -210, 18432, 76, }, /* 120 */ - { 0, 5, 12, 0, -206, 18432, 76, }, /* 121 */ - { 0, 5, 12, 0, -205, 18432, 76, }, /* 122 */ - { 0, 5, 12, 0, -202, 18432, 76, }, /* 123 */ - { 0, 5, 12, 0, -203, 18432, 76, }, /* 124 */ - { 0, 5, 12, 0, 42319, 18432, 76, }, /* 125 */ - { 0, 5, 12, 0, 42315, 18432, 76, }, /* 126 */ - { 0, 5, 12, 0, -207, 18432, 76, }, /* 127 */ - { 0, 5, 12, 0, 42280, 18432, 76, }, /* 128 */ - { 0, 5, 12, 0, 42308, 18432, 76, }, /* 129 */ - { 0, 5, 12, 0, -209, 18432, 78, }, /* 130 */ - { 0, 5, 12, 0, -211, 18432, 76, }, /* 131 */ - { 0, 5, 12, 0, 10743, 18432, 76, }, /* 132 */ - { 0, 5, 12, 0, 42305, 18432, 76, }, /* 133 */ - { 0, 5, 12, 0, 10749, 18432, 76, }, /* 134 */ - { 0, 5, 12, 0, -213, 18432, 76, }, /* 135 */ - { 0, 5, 12, 0, -214, 18432, 76, }, /* 136 */ - { 0, 5, 12, 0, 10727, 18432, 76, }, /* 137 */ - { 0, 5, 12, 0, -218, 18432, 76, }, /* 138 */ - { 0, 5, 12, 0, 42307, 18432, 76, }, /* 139 */ - { 0, 5, 12, 0, 42282, 18432, 76, }, /* 140 */ - { 0, 5, 12, 0, -69, 18432, 76, }, /* 141 */ - { 0, 5, 12, 0, -217, 18432, 76, }, /* 142 */ - { 0, 5, 12, 0, -71, 18432, 76, }, /* 143 */ - { 0, 5, 12, 0, -219, 18432, 76, }, /* 144 */ - { 0, 5, 12, 0, 42261, 18432, 78, }, /* 145 */ - { 0, 5, 12, 0, 42258, 18432, 76, }, /* 146 */ - { 0, 6, 12, 0, 0, 18432, 88, }, /* 147 */ - { 0, 6, 12, 0, 0, 18432, 90, }, /* 148 */ - { 69, 6, 12, 0, 0, 28672, 92, }, /* 149 */ - { 69, 6, 12, 0, 0, 18432, 92, }, /* 150 */ - { 69, 6, 12, 0, 0, 18432, 88, }, /* 151 */ - { 69, 6, 12, 0, 0, 18432, 94, }, /* 152 */ - { 22, 24, 12, 0, 0, 28672, 56, }, /* 153 */ - { 84, 12, 3, 0, 0, 26624, 96, }, /* 154 */ - { 84, 12, 3, 0, 0, 26636, 96, }, /* 155 */ - { 84, 12, 3, 21, 116, 26636, 98, }, /* 156 */ - { 84, 12, 3, 0, 0, 26624, 100, }, /* 157 */ - { 84, 12, 3, 0, 0, 26624, 102, }, /* 158 */ - { 84, 12, 3, 0, 0, 26642, 102, }, /* 159 */ - { 1, 9, 12, 0, 1, 18432, 74, }, /* 160 */ - { 1, 5, 12, 0, -1, 18432, 76, }, /* 161 */ - { 1, 24, 12, 0, 0, 28672, 56, }, /* 162 */ - { 68, 2, 12, 0, 0, 18432, 0, }, /* 163 */ - { 1, 6, 12, 0, 0, 18432, 104, }, /* 164 */ - { 1, 5, 12, 0, 130, 18432, 76, }, /* 165 */ - { 69, 21, 12, 0, 0, 28672, 106, }, /* 166 */ - { 1, 9, 12, 0, 116, 18432, 74, }, /* 167 */ - { 1, 9, 12, 0, 38, 18432, 74, }, /* 168 */ - { 69, 21, 12, 0, 0, 28672, 108, }, /* 169 */ - { 1, 9, 12, 0, 37, 18432, 74, }, /* 170 */ - { 1, 9, 12, 0, 64, 18432, 74, }, /* 171 */ - { 1, 9, 12, 0, 63, 18432, 74, }, /* 172 */ - { 1, 5, 12, 0, 0, 18432, 76, }, /* 173 */ - { 1, 9, 12, 0, 32, 18432, 74, }, /* 174 */ - { 1, 9, 12, 34, 32, 18432, 74, }, /* 175 */ - { 1, 9, 12, 59, 32, 18432, 74, }, /* 176 */ - { 1, 9, 12, 38, 32, 18432, 74, }, /* 177 */ - { 1, 9, 12, 21, 32, 18432, 74, }, /* 178 */ - { 1, 9, 12, 51, 32, 18432, 74, }, /* 179 */ - { 1, 9, 12, 26, 32, 18432, 74, }, /* 180 */ - { 1, 9, 12, 47, 32, 18432, 74, }, /* 181 */ - { 1, 9, 12, 55, 32, 18432, 74, }, /* 182 */ - { 1, 9, 12, 30, 32, 18432, 74, }, /* 183 */ - { 1, 9, 12, 43, 32, 18432, 74, }, /* 184 */ - { 1, 9, 12, 96, 32, 18432, 74, }, /* 185 */ - { 1, 5, 12, 0, -38, 18432, 76, }, /* 186 */ - { 1, 5, 12, 0, -37, 18432, 76, }, /* 187 */ - { 1, 5, 12, 0, -32, 18432, 76, }, /* 188 */ - { 1, 5, 12, 34, -32, 18432, 76, }, /* 189 */ - { 1, 5, 12, 59, -32, 18432, 76, }, /* 190 */ - { 1, 5, 12, 38, -32, 18432, 76, }, /* 191 */ - { 1, 5, 12, 21, -116, 18432, 76, }, /* 192 */ - { 1, 5, 12, 51, -32, 18432, 76, }, /* 193 */ - { 1, 5, 12, 26, -775, 18432, 76, }, /* 194 */ - { 1, 5, 12, 47, -32, 18432, 76, }, /* 195 */ - { 1, 5, 12, 55, -32, 18432, 76, }, /* 196 */ - { 1, 5, 12, 30, 1, 18432, 70, }, /* 197 */ - { 1, 5, 12, 30, -32, 18432, 76, }, /* 198 */ - { 1, 5, 12, 43, -32, 18432, 76, }, /* 199 */ - { 1, 5, 12, 96, -32, 18432, 76, }, /* 200 */ - { 1, 5, 12, 0, -64, 18432, 76, }, /* 201 */ - { 1, 5, 12, 0, -63, 18432, 76, }, /* 202 */ - { 1, 9, 12, 0, 8, 18432, 74, }, /* 203 */ - { 1, 5, 12, 34, -30, 18432, 110, }, /* 204 */ - { 1, 5, 12, 38, -25, 18432, 110, }, /* 205 */ - { 1, 9, 12, 0, 0, 18432, 112, }, /* 206 */ - { 1, 9, 12, 0, 0, 18432, 114, }, /* 207 */ - { 1, 5, 12, 43, -15, 18432, 110, }, /* 208 */ - { 1, 5, 12, 47, -22, 18432, 70, }, /* 209 */ - { 1, 5, 12, 0, -8, 18432, 76, }, /* 210 */ - { 34, 9, 12, 0, 1, 18432, 74, }, /* 211 */ - { 34, 5, 12, 0, -1, 18432, 76, }, /* 212 */ - { 1, 5, 12, 51, -54, 18432, 110, }, /* 213 */ - { 1, 5, 12, 55, -48, 18432, 110, }, /* 214 */ - { 1, 5, 12, 0, 7, 18432, 76, }, /* 215 */ - { 1, 5, 12, 0, -116, 18432, 78, }, /* 216 */ - { 1, 9, 12, 38, -60, 18432, 116, }, /* 217 */ - { 1, 5, 12, 59, -64, 18432, 110, }, /* 218 */ - { 1, 25, 12, 0, 0, 28672, 118, }, /* 219 */ - { 1, 9, 12, 0, -7, 18432, 74, }, /* 220 */ - { 1, 5, 12, 0, 0, 18432, 60, }, /* 221 */ - { 1, 9, 12, 0, -130, 18432, 74, }, /* 222 */ - { 2, 9, 12, 0, 80, 18432, 74, }, /* 223 */ - { 2, 9, 12, 0, 32, 18432, 74, }, /* 224 */ - { 2, 9, 12, 63, 32, 18432, 74, }, /* 225 */ - { 2, 9, 12, 67, 32, 18432, 74, }, /* 226 */ - { 2, 9, 12, 71, 32, 18432, 74, }, /* 227 */ - { 2, 9, 12, 75, 32, 18432, 74, }, /* 228 */ - { 2, 9, 12, 79, 32, 18432, 74, }, /* 229 */ - { 2, 9, 12, 84, 32, 18432, 74, }, /* 230 */ - { 2, 5, 12, 0, -32, 18432, 76, }, /* 231 */ - { 2, 5, 12, 63, -32, 18432, 76, }, /* 232 */ - { 2, 5, 12, 67, -32, 18432, 76, }, /* 233 */ - { 2, 5, 12, 71, -32, 18432, 76, }, /* 234 */ - { 2, 5, 12, 75, -32, 18432, 76, }, /* 235 */ - { 2, 5, 12, 79, -32, 18432, 76, }, /* 236 */ - { 2, 5, 12, 84, -32, 18432, 76, }, /* 237 */ - { 2, 5, 12, 0, -80, 18432, 76, }, /* 238 */ - { 2, 5, 12, 0, -80, 18432, 78, }, /* 239 */ - { 2, 9, 12, 0, 1, 18432, 74, }, /* 240 */ - { 2, 5, 12, 0, -1, 18432, 76, }, /* 241 */ - { 2, 9, 12, 88, 1, 18432, 74, }, /* 242 */ - { 2, 5, 12, 88, -1, 18432, 76, }, /* 243 */ - { 2, 26, 12, 0, 0, 18432, 68, }, /* 244 */ - { 2, 12, 3, 0, 0, 26684, 96, }, /* 245 */ - { 2, 12, 3, 0, 0, 26678, 96, }, /* 246 */ - { 84, 12, 3, 0, 0, 26681, 96, }, /* 247 */ - { 2, 11, 3, 0, 0, 26624, 120, }, /* 248 */ - { 2, 9, 12, 0, 15, 18432, 74, }, /* 249 */ - { 2, 5, 12, 0, -15, 18432, 76, }, /* 250 */ - { 70, 9, 12, 0, 48, 18432, 74, }, /* 251 */ - { 70, 6, 12, 0, 0, 18432, 92, }, /* 252 */ - { 70, 21, 12, 0, 0, 18432, 68, }, /* 253 */ - { 70, 21, 12, 0, 0, 18432, 122, }, /* 254 */ - { 70, 5, 12, 0, 0, 18432, 60, }, /* 255 */ - { 70, 5, 12, 0, -48, 18432, 76, }, /* 256 */ - { 70, 5, 12, 0, 0, 18432, 70, }, /* 257 */ - { 70, 21, 12, 0, 0, 18432, 124, }, /* 258 */ - { 70, 17, 12, 0, 0, 28672, 126, }, /* 259 */ - { 70, 26, 12, 0, 0, 28672, 68, }, /* 260 */ - { 70, 23, 12, 0, 0, 14336, 68, }, /* 261 */ - { 68, 2, 12, 0, 0, 34816, 0, }, /* 262 */ - { 71, 12, 3, 0, 0, 26624, 96, }, /* 263 */ - { 71, 12, 3, 0, 0, 26624, 102, }, /* 264 */ - { 71, 12, 3, 0, 0, 26624, 128, }, /* 265 */ - { 71, 17, 12, 0, 0, 34816, 126, }, /* 266 */ - { 71, 21, 12, 0, 0, 34816, 68, }, /* 267 */ - { 71, 21, 12, 0, 0, 34816, 106, }, /* 268 */ - { 71, 12, 3, 0, 0, 26624, 130, }, /* 269 */ - { 71, 7, 12, 0, 0, 34816, 82, }, /* 270 */ - { 71, 21, 12, 0, 0, 34816, 122, }, /* 271 */ - { 3, 1, 4, 0, 0, 2048, 132, }, /* 272 */ - { 69, 1, 4, 0, 0, 2048, 132, }, /* 273 */ - { 3, 25, 12, 0, 0, 28672, 118, }, /* 274 */ - { 3, 25, 12, 0, 0, 0, 118, }, /* 275 */ - { 3, 21, 12, 0, 0, 14336, 68, }, /* 276 */ - { 3, 23, 12, 0, 0, 0, 68, }, /* 277 */ - { 69, 21, 12, 0, 0, 8342, 106, }, /* 278 */ - { 3, 21, 12, 0, 0, 0, 68, }, /* 279 */ - { 3, 26, 12, 0, 0, 28672, 68, }, /* 280 */ - { 3, 12, 3, 0, 0, 26624, 130, }, /* 281 */ - { 69, 21, 12, 0, 0, 150, 106, }, /* 282 */ - { 3, 1, 2, 0, 0, 108, 134, }, /* 283 */ - { 3, 21, 12, 0, 0, 0, 124, }, /* 284 */ - { 69, 21, 12, 0, 0, 159, 124, }, /* 285 */ - { 3, 7, 12, 0, 0, 0, 82, }, /* 286 */ - { 69, 6, 12, 0, 0, 165, 136, }, /* 287 */ - { 84, 12, 3, 0, 0, 26660, 128, }, /* 288 */ - { 84, 12, 3, 0, 0, 26660, 130, }, /* 289 */ - { 3, 12, 3, 0, 0, 26624, 128, }, /* 290 */ - { 3, 12, 3, 0, 0, 26624, 96, }, /* 291 */ - { 3, 13, 12, 0, 0, 2159, 138, }, /* 292 */ - { 3, 21, 12, 0, 0, 2048, 68, }, /* 293 */ - { 3, 7, 12, 0, 0, 0, 140, }, /* 294 */ - { 3, 21, 12, 0, 0, 30, 124, }, /* 295 */ - { 3, 6, 12, 0, 0, 0, 92, }, /* 296 */ - { 3, 13, 12, 0, 0, 10240, 138, }, /* 297 */ - { 3, 26, 12, 0, 0, 0, 68, }, /* 298 */ - { 4, 21, 12, 0, 0, 0, 124, }, /* 299 */ - { 4, 21, 12, 0, 0, 0, 106, }, /* 300 */ - { 4, 21, 12, 0, 0, 0, 68, }, /* 301 */ - { 68, 2, 12, 0, 0, 0, 0, }, /* 302 */ - { 4, 1, 4, 0, 0, 0, 132, }, /* 303 */ - { 4, 7, 12, 0, 0, 0, 82, }, /* 304 */ - { 4, 12, 3, 0, 0, 26624, 130, }, /* 305 */ - { 4, 12, 3, 0, 0, 26624, 128, }, /* 306 */ - { 4, 12, 3, 0, 0, 26624, 96, }, /* 307 */ - { 5, 7, 12, 0, 0, 0, 82, }, /* 308 */ - { 5, 12, 3, 0, 0, 26624, 128, }, /* 309 */ - { 38, 13, 12, 0, 0, 34816, 138, }, /* 310 */ - { 38, 7, 12, 0, 0, 34816, 82, }, /* 311 */ - { 38, 12, 3, 0, 0, 26624, 96, }, /* 312 */ - { 38, 6, 12, 0, 0, 34816, 92, }, /* 313 */ - { 38, 26, 12, 0, 0, 28672, 68, }, /* 314 */ - { 38, 21, 12, 0, 0, 28672, 68, }, /* 315 */ - { 38, 21, 12, 0, 0, 28672, 106, }, /* 316 */ - { 38, 21, 12, 0, 0, 28672, 124, }, /* 317 */ - { 38, 6, 12, 0, 0, 34816, 136, }, /* 318 */ - { 38, 12, 3, 0, 0, 26624, 102, }, /* 319 */ - { 38, 23, 12, 0, 0, 34816, 68, }, /* 320 */ - { 110, 7, 12, 0, 0, 34816, 82, }, /* 321 */ - { 110, 12, 3, 0, 0, 26624, 130, }, /* 322 */ - { 110, 12, 3, 0, 0, 26624, 96, }, /* 323 */ - { 110, 6, 12, 0, 0, 34816, 142, }, /* 324 */ - { 110, 12, 3, 0, 0, 26624, 102, }, /* 325 */ - { 110, 21, 12, 0, 0, 34816, 106, }, /* 326 */ - { 110, 21, 12, 0, 0, 34816, 124, }, /* 327 */ - { 42, 7, 12, 0, 0, 34816, 82, }, /* 328 */ - { 42, 12, 3, 0, 0, 26624, 102, }, /* 329 */ - { 42, 21, 12, 0, 0, 34816, 106, }, /* 330 */ - { 3, 24, 12, 0, 0, 0, 122, }, /* 331 */ - { 3, 12, 3, 0, 0, 26624, 102, }, /* 332 */ - { 6, 12, 3, 0, 0, 26624, 130, }, /* 333 */ - { 6, 10, 5, 0, 0, 18432, 144, }, /* 334 */ - { 6, 7, 12, 0, 0, 18432, 82, }, /* 335 */ - { 6, 12, 3, 0, 0, 26624, 96, }, /* 336 */ - { 6, 12, 3, 0, 0, 26624, 146, }, /* 337 */ - { 84, 12, 3, 0, 0, 26798, 96, }, /* 338 */ - { 84, 12, 3, 0, 0, 26795, 96, }, /* 339 */ - { 69, 21, 12, 0, 0, 18615, 124, }, /* 340 */ - { 69, 21, 12, 0, 0, 18618, 124, }, /* 341 */ - { 6, 13, 12, 0, 0, 18576, 138, }, /* 342 */ - { 6, 21, 12, 0, 0, 18432, 68, }, /* 343 */ - { 6, 6, 12, 0, 0, 18432, 92, }, /* 344 */ - { 7, 7, 12, 0, 0, 18432, 82, }, /* 345 */ - { 7, 12, 3, 0, 0, 26624, 130, }, /* 346 */ - { 7, 10, 5, 0, 0, 18432, 144, }, /* 347 */ - { 7, 12, 3, 0, 0, 26624, 96, }, /* 348 */ - { 7, 10, 3, 0, 0, 18432, 148, }, /* 349 */ - { 7, 12, 3, 0, 0, 26624, 146, }, /* 350 */ - { 7, 13, 12, 0, 0, 18546, 138, }, /* 351 */ - { 7, 23, 12, 0, 0, 14336, 68, }, /* 352 */ - { 7, 15, 12, 0, 0, 18432, 68, }, /* 353 */ - { 7, 26, 12, 0, 0, 18432, 68, }, /* 354 */ - { 7, 21, 12, 0, 0, 18432, 68, }, /* 355 */ - { 7, 12, 3, 0, 0, 26624, 102, }, /* 356 */ - { 8, 12, 3, 0, 0, 26624, 130, }, /* 357 */ - { 8, 10, 5, 0, 0, 18432, 144, }, /* 358 */ - { 8, 7, 12, 0, 0, 18432, 82, }, /* 359 */ - { 8, 12, 3, 0, 0, 26624, 96, }, /* 360 */ - { 8, 12, 3, 0, 0, 26624, 146, }, /* 361 */ - { 8, 13, 12, 0, 0, 18519, 138, }, /* 362 */ - { 8, 21, 12, 0, 0, 18432, 68, }, /* 363 */ - { 9, 12, 3, 0, 0, 26624, 130, }, /* 364 */ - { 9, 10, 5, 0, 0, 18432, 144, }, /* 365 */ - { 9, 7, 12, 0, 0, 18432, 82, }, /* 366 */ - { 9, 12, 3, 0, 0, 26624, 96, }, /* 367 */ - { 9, 12, 3, 0, 0, 26624, 146, }, /* 368 */ - { 9, 13, 12, 0, 0, 18516, 138, }, /* 369 */ - { 9, 21, 12, 0, 0, 18432, 68, }, /* 370 */ - { 9, 23, 12, 0, 0, 14336, 68, }, /* 371 */ - { 10, 12, 3, 0, 0, 26624, 130, }, /* 372 */ - { 10, 10, 5, 0, 0, 18432, 144, }, /* 373 */ - { 10, 7, 12, 0, 0, 18432, 82, }, /* 374 */ - { 10, 12, 3, 0, 0, 26624, 96, }, /* 375 */ - { 10, 10, 3, 0, 0, 18432, 148, }, /* 376 */ - { 10, 12, 3, 0, 0, 26624, 146, }, /* 377 */ - { 10, 12, 3, 0, 0, 26624, 150, }, /* 378 */ - { 10, 13, 12, 0, 0, 18432, 138, }, /* 379 */ - { 10, 26, 12, 0, 0, 18432, 68, }, /* 380 */ - { 10, 15, 12, 0, 0, 18432, 68, }, /* 381 */ - { 11, 12, 3, 0, 0, 26624, 130, }, /* 382 */ - { 11, 7, 12, 0, 0, 18432, 82, }, /* 383 */ - { 11, 10, 3, 0, 0, 18432, 148, }, /* 384 */ - { 11, 10, 5, 0, 0, 18432, 144, }, /* 385 */ - { 11, 12, 3, 0, 0, 26624, 146, }, /* 386 */ - { 11, 13, 12, 0, 0, 18513, 138, }, /* 387 */ - { 11, 15, 12, 0, 0, 18513, 68, }, /* 388 */ - { 11, 26, 12, 0, 0, 28753, 68, }, /* 389 */ - { 11, 26, 12, 0, 0, 28672, 68, }, /* 390 */ - { 11, 23, 12, 0, 0, 14336, 68, }, /* 391 */ - { 12, 12, 3, 0, 0, 26624, 130, }, /* 392 */ - { 12, 10, 5, 0, 0, 18432, 144, }, /* 393 */ - { 12, 7, 12, 0, 0, 18432, 82, }, /* 394 */ - { 12, 12, 3, 0, 0, 26624, 96, }, /* 395 */ - { 12, 12, 3, 0, 0, 26624, 146, }, /* 396 */ - { 12, 13, 12, 0, 0, 18432, 138, }, /* 397 */ - { 12, 21, 12, 0, 0, 18432, 68, }, /* 398 */ - { 12, 15, 12, 0, 0, 28672, 68, }, /* 399 */ - { 12, 26, 12, 0, 0, 18432, 68, }, /* 400 */ - { 13, 7, 12, 0, 0, 18432, 82, }, /* 401 */ - { 13, 12, 3, 0, 0, 26624, 130, }, /* 402 */ - { 13, 10, 5, 0, 0, 18432, 144, }, /* 403 */ - { 13, 21, 12, 0, 0, 18432, 68, }, /* 404 */ - { 13, 12, 3, 0, 0, 26624, 96, }, /* 405 */ - { 13, 12, 3, 0, 0, 18432, 130, }, /* 406 */ - { 13, 10, 3, 0, 0, 18432, 148, }, /* 407 */ - { 13, 12, 3, 0, 0, 26624, 146, }, /* 408 */ - { 13, 13, 12, 0, 0, 18528, 138, }, /* 409 */ - { 14, 12, 3, 0, 0, 26624, 130, }, /* 410 */ - { 14, 10, 5, 0, 0, 18432, 144, }, /* 411 */ - { 14, 7, 12, 0, 0, 18432, 82, }, /* 412 */ - { 14, 12, 3, 0, 0, 26624, 146, }, /* 413 */ - { 14, 10, 3, 0, 0, 18432, 148, }, /* 414 */ - { 14, 7, 4, 0, 0, 18432, 82, }, /* 415 */ - { 14, 26, 12, 0, 0, 18432, 68, }, /* 416 */ - { 14, 15, 12, 0, 0, 18432, 68, }, /* 417 */ - { 14, 13, 12, 0, 0, 18432, 138, }, /* 418 */ - { 15, 12, 3, 0, 0, 26624, 130, }, /* 419 */ - { 15, 10, 5, 0, 0, 18432, 144, }, /* 420 */ - { 15, 7, 12, 0, 0, 18432, 82, }, /* 421 */ - { 15, 12, 3, 0, 0, 26624, 146, }, /* 422 */ - { 15, 10, 3, 0, 0, 18432, 148, }, /* 423 */ - { 15, 13, 12, 0, 0, 18432, 138, }, /* 424 */ - { 15, 21, 12, 0, 0, 18432, 68, }, /* 425 */ - { 72, 7, 12, 0, 0, 18432, 82, }, /* 426 */ - { 72, 12, 3, 0, 0, 26624, 130, }, /* 427 */ - { 72, 7, 5, 0, 0, 18432, 152, }, /* 428 */ - { 72, 12, 3, 0, 0, 26624, 154, }, /* 429 */ - { 69, 23, 12, 0, 0, 14336, 68, }, /* 430 */ - { 72, 7, 12, 0, 0, 18432, 156, }, /* 431 */ - { 72, 6, 12, 0, 0, 18432, 136, }, /* 432 */ - { 72, 12, 3, 0, 0, 26624, 96, }, /* 433 */ - { 72, 21, 12, 0, 0, 18432, 68, }, /* 434 */ - { 72, 13, 12, 0, 0, 18432, 138, }, /* 435 */ - { 72, 21, 12, 0, 0, 18432, 106, }, /* 436 */ - { 73, 7, 12, 0, 0, 18432, 82, }, /* 437 */ - { 73, 12, 3, 0, 0, 26624, 130, }, /* 438 */ - { 73, 7, 5, 0, 0, 18432, 152, }, /* 439 */ - { 73, 12, 3, 0, 0, 26624, 146, }, /* 440 */ - { 73, 7, 12, 0, 0, 18432, 156, }, /* 441 */ - { 73, 6, 12, 0, 0, 18432, 136, }, /* 442 */ - { 73, 12, 3, 0, 0, 26624, 96, }, /* 443 */ - { 73, 12, 3, 0, 0, 26624, 102, }, /* 444 */ - { 73, 13, 12, 0, 0, 18432, 138, }, /* 445 */ - { 74, 7, 12, 0, 0, 18432, 82, }, /* 446 */ - { 74, 26, 12, 0, 0, 18432, 68, }, /* 447 */ - { 74, 21, 12, 0, 0, 18432, 68, }, /* 448 */ - { 74, 21, 12, 0, 0, 18432, 106, }, /* 449 */ - { 74, 12, 3, 0, 0, 26624, 96, }, /* 450 */ - { 74, 13, 12, 0, 0, 18432, 138, }, /* 451 */ - { 74, 15, 12, 0, 0, 18432, 68, }, /* 452 */ - { 74, 22, 12, 0, 0, 28672, 158, }, /* 453 */ - { 74, 18, 12, 0, 0, 28672, 158, }, /* 454 */ - { 74, 10, 5, 0, 0, 18432, 160, }, /* 455 */ - { 74, 12, 3, 0, 0, 26624, 130, }, /* 456 */ - { 74, 12, 3, 0, 0, 26624, 162, }, /* 457 */ - { 74, 10, 5, 0, 0, 18432, 144, }, /* 458 */ - { 74, 12, 3, 0, 0, 26624, 128, }, /* 459 */ - { 74, 12, 3, 0, 0, 26624, 146, }, /* 460 */ - { 69, 26, 12, 0, 0, 18432, 68, }, /* 461 */ - { 16, 7, 12, 0, 0, 18432, 82, }, /* 462 */ - { 16, 10, 12, 0, 0, 18432, 144, }, /* 463 */ - { 16, 12, 3, 0, 0, 26624, 130, }, /* 464 */ - { 16, 10, 5, 0, 0, 18432, 144, }, /* 465 */ - { 16, 12, 3, 0, 0, 26624, 96, }, /* 466 */ - { 16, 12, 3, 0, 0, 26624, 146, }, /* 467 */ - { 16, 13, 12, 0, 0, 18549, 138, }, /* 468 */ - { 16, 21, 12, 0, 0, 18432, 124, }, /* 469 */ - { 16, 21, 12, 0, 0, 18432, 68, }, /* 470 */ - { 16, 10, 12, 0, 0, 18432, 164, }, /* 471 */ - { 16, 12, 3, 0, 0, 26624, 128, }, /* 472 */ - { 16, 13, 12, 0, 0, 18432, 138, }, /* 473 */ - { 16, 26, 12, 0, 0, 18432, 68, }, /* 474 */ - { 17, 9, 12, 0, 7264, 18432, 74, }, /* 475 */ - { 17, 5, 12, 0, 3008, 18432, 166, }, /* 476 */ - { 69, 21, 12, 0, 0, 18510, 68, }, /* 477 */ - { 17, 6, 12, 0, 0, 18432, 168, }, /* 478 */ - { 18, 7, 6, 0, 0, 18432, 82, }, /* 479 */ - { 18, 7, 6, 0, 0, 18432, 170, }, /* 480 */ - { 18, 7, 7, 0, 0, 18432, 170, }, /* 481 */ - { 18, 7, 7, 0, 0, 18432, 82, }, /* 482 */ - { 18, 7, 8, 0, 0, 18432, 82, }, /* 483 */ - { 75, 7, 12, 0, 0, 18432, 82, }, /* 484 */ - { 75, 12, 3, 0, 0, 26624, 96, }, /* 485 */ - { 75, 21, 12, 0, 0, 18432, 68, }, /* 486 */ - { 75, 21, 12, 0, 0, 18432, 106, }, /* 487 */ - { 75, 21, 12, 0, 0, 18432, 124, }, /* 488 */ - { 75, 15, 12, 0, 0, 18432, 138, }, /* 489 */ - { 75, 15, 12, 0, 0, 18432, 68, }, /* 490 */ - { 75, 26, 12, 0, 0, 28672, 68, }, /* 491 */ - { 76, 9, 12, 0, 38864, 18432, 172, }, /* 492 */ - { 76, 9, 12, 0, 8, 18432, 172, }, /* 493 */ - { 76, 5, 12, 0, -8, 18432, 70, }, /* 494 */ - { 77, 17, 12, 0, 0, 28672, 126, }, /* 495 */ - { 77, 7, 12, 0, 0, 18432, 82, }, /* 496 */ - { 77, 26, 12, 0, 0, 18432, 68, }, /* 497 */ - { 77, 21, 12, 0, 0, 18432, 124, }, /* 498 */ - { 78, 29, 12, 0, 0, 45056, 52, }, /* 499 */ - { 78, 7, 12, 0, 0, 18432, 82, }, /* 500 */ - { 78, 22, 12, 0, 0, 28672, 158, }, /* 501 */ - { 78, 18, 12, 0, 0, 28672, 158, }, /* 502 */ - { 79, 7, 12, 0, 0, 18432, 82, }, /* 503 */ - { 69, 21, 12, 0, 0, 18432, 106, }, /* 504 */ - { 79, 14, 12, 0, 0, 18432, 82, }, /* 505 */ - { 25, 7, 12, 0, 0, 18432, 82, }, /* 506 */ - { 25, 12, 3, 0, 0, 26624, 130, }, /* 507 */ - { 25, 12, 3, 0, 0, 26624, 146, }, /* 508 */ - { 25, 10, 5, 0, 0, 18432, 174, }, /* 509 */ - { 26, 7, 12, 0, 0, 18432, 82, }, /* 510 */ - { 26, 12, 3, 0, 0, 26624, 130, }, /* 511 */ - { 26, 10, 5, 0, 0, 18432, 176, }, /* 512 */ - { 69, 21, 12, 0, 0, 18573, 124, }, /* 513 */ - { 27, 7, 12, 0, 0, 18432, 82, }, /* 514 */ - { 27, 12, 3, 0, 0, 26624, 130, }, /* 515 */ - { 28, 7, 12, 0, 0, 18432, 82, }, /* 516 */ - { 28, 12, 3, 0, 0, 26624, 130, }, /* 517 */ - { 80, 7, 12, 0, 0, 18432, 82, }, /* 518 */ - { 80, 7, 12, 0, 0, 18432, 140, }, /* 519 */ - { 80, 12, 3, 0, 0, 26624, 100, }, /* 520 */ - { 80, 10, 5, 0, 0, 18432, 144, }, /* 521 */ - { 80, 12, 3, 0, 0, 26624, 130, }, /* 522 */ - { 80, 12, 3, 0, 0, 26624, 96, }, /* 523 */ - { 80, 12, 3, 0, 0, 26624, 146, }, /* 524 */ - { 80, 21, 12, 0, 0, 18432, 106, }, /* 525 */ - { 80, 6, 12, 0, 0, 18432, 142, }, /* 526 */ - { 80, 21, 12, 0, 0, 18432, 68, }, /* 527 */ - { 80, 23, 12, 0, 0, 14336, 68, }, /* 528 */ - { 80, 13, 12, 0, 0, 18432, 138, }, /* 529 */ - { 80, 15, 12, 0, 0, 28672, 68, }, /* 530 */ - { 19, 21, 12, 0, 0, 28672, 68, }, /* 531 */ - { 69, 21, 12, 0, 0, 28777, 106, }, /* 532 */ - { 69, 21, 12, 0, 0, 28777, 124, }, /* 533 */ - { 19, 21, 12, 0, 0, 28672, 106, }, /* 534 */ - { 19, 17, 12, 0, 0, 28672, 126, }, /* 535 */ - { 19, 21, 12, 0, 0, 28672, 124, }, /* 536 */ - { 19, 21, 12, 0, 0, 28672, 178, }, /* 537 */ - { 19, 12, 3, 0, 0, 26624, 180, }, /* 538 */ - { 19, 1, 2, 0, 0, 6144, 66, }, /* 539 */ - { 19, 13, 12, 0, 0, 18432, 138, }, /* 540 */ - { 19, 7, 12, 0, 0, 18432, 82, }, /* 541 */ - { 19, 6, 12, 0, 0, 18432, 136, }, /* 542 */ - { 19, 12, 3, 0, 0, 26624, 182, }, /* 543 */ - { 19, 12, 3, 0, 0, 26624, 130, }, /* 544 */ - { 29, 7, 12, 0, 0, 18432, 82, }, /* 545 */ - { 29, 12, 3, 0, 0, 26624, 130, }, /* 546 */ - { 29, 10, 5, 0, 0, 18432, 144, }, /* 547 */ - { 29, 12, 3, 0, 0, 26624, 96, }, /* 548 */ - { 29, 26, 12, 0, 0, 28672, 68, }, /* 549 */ - { 29, 21, 12, 0, 0, 28672, 124, }, /* 550 */ - { 29, 13, 12, 0, 0, 18432, 138, }, /* 551 */ - { 30, 7, 12, 0, 0, 18432, 82, }, /* 552 */ - { 89, 7, 12, 0, 0, 18432, 82, }, /* 553 */ - { 89, 7, 12, 0, 0, 18432, 156, }, /* 554 */ - { 89, 13, 12, 0, 0, 18432, 138, }, /* 555 */ - { 89, 15, 12, 0, 0, 18432, 138, }, /* 556 */ - { 89, 26, 12, 0, 0, 28672, 68, }, /* 557 */ - { 80, 26, 12, 0, 0, 28672, 68, }, /* 558 */ - { 33, 7, 12, 0, 0, 18432, 82, }, /* 559 */ - { 33, 12, 3, 0, 0, 26624, 130, }, /* 560 */ - { 33, 10, 5, 0, 0, 18432, 144, }, /* 561 */ - { 33, 21, 12, 0, 0, 18432, 68, }, /* 562 */ - { 106, 7, 12, 0, 0, 18432, 82, }, /* 563 */ - { 106, 10, 5, 0, 0, 18432, 144, }, /* 564 */ - { 106, 12, 3, 0, 0, 26624, 130, }, /* 565 */ - { 106, 12, 3, 0, 0, 26624, 184, }, /* 566 */ - { 106, 10, 12, 0, 0, 18432, 144, }, /* 567 */ - { 106, 12, 3, 0, 0, 26624, 96, }, /* 568 */ - { 106, 13, 12, 0, 0, 18432, 138, }, /* 569 */ - { 106, 21, 12, 0, 0, 18432, 68, }, /* 570 */ - { 106, 6, 12, 0, 0, 18432, 136, }, /* 571 */ - { 106, 21, 12, 0, 0, 18432, 124, }, /* 572 */ - { 84, 11, 3, 0, 0, 26624, 186, }, /* 573 */ - { 84, 12, 3, 0, 0, 26624, 130, }, /* 574 */ - { 93, 12, 3, 0, 0, 26624, 130, }, /* 575 */ - { 93, 10, 5, 0, 0, 18432, 144, }, /* 576 */ - { 93, 7, 12, 0, 0, 18432, 82, }, /* 577 */ - { 93, 12, 3, 0, 0, 26624, 96, }, /* 578 */ - { 93, 10, 3, 0, 0, 18432, 148, }, /* 579 */ - { 93, 10, 5, 0, 0, 18432, 174, }, /* 580 */ - { 93, 13, 12, 0, 0, 18432, 138, }, /* 581 */ - { 93, 21, 12, 0, 0, 18432, 124, }, /* 582 */ - { 93, 21, 12, 0, 0, 18432, 68, }, /* 583 */ - { 93, 21, 12, 0, 0, 18432, 106, }, /* 584 */ - { 93, 26, 12, 0, 0, 18432, 68, }, /* 585 */ - { 96, 12, 3, 0, 0, 26624, 130, }, /* 586 */ - { 96, 10, 5, 0, 0, 18432, 144, }, /* 587 */ - { 96, 7, 12, 0, 0, 18432, 82, }, /* 588 */ - { 96, 10, 5, 0, 0, 18432, 174, }, /* 589 */ - { 96, 12, 3, 0, 0, 26624, 146, }, /* 590 */ - { 96, 13, 12, 0, 0, 18432, 138, }, /* 591 */ - { 119, 7, 12, 0, 0, 18432, 82, }, /* 592 */ - { 119, 12, 3, 0, 0, 26624, 102, }, /* 593 */ - { 119, 10, 5, 0, 0, 18432, 144, }, /* 594 */ - { 119, 12, 3, 0, 0, 26624, 130, }, /* 595 */ - { 119, 10, 5, 0, 0, 18432, 176, }, /* 596 */ - { 119, 21, 12, 0, 0, 18432, 68, }, /* 597 */ - { 97, 7, 12, 0, 0, 18432, 82, }, /* 598 */ - { 97, 10, 5, 0, 0, 18432, 144, }, /* 599 */ - { 97, 12, 3, 0, 0, 26624, 130, }, /* 600 */ - { 97, 12, 3, 0, 0, 26624, 188, }, /* 601 */ - { 97, 12, 3, 0, 0, 26624, 96, }, /* 602 */ - { 97, 21, 12, 0, 0, 18432, 124, }, /* 603 */ - { 97, 21, 12, 0, 0, 18432, 106, }, /* 604 */ - { 97, 13, 12, 0, 0, 18432, 138, }, /* 605 */ - { 98, 13, 12, 0, 0, 18432, 138, }, /* 606 */ - { 98, 7, 12, 0, 0, 18432, 82, }, /* 607 */ - { 98, 6, 12, 0, 0, 18432, 92, }, /* 608 */ - { 98, 6, 12, 0, 0, 18432, 94, }, /* 609 */ - { 98, 21, 12, 0, 0, 18432, 124, }, /* 610 */ - { 2, 5, 12, 63, -6222, 18432, 70, }, /* 611 */ - { 2, 5, 12, 67, -6221, 18432, 70, }, /* 612 */ - { 2, 5, 12, 71, -6212, 18432, 70, }, /* 613 */ - { 2, 5, 12, 75, -6210, 18432, 70, }, /* 614 */ - { 2, 5, 12, 79, -6210, 18432, 70, }, /* 615 */ - { 2, 5, 12, 79, -6211, 18432, 70, }, /* 616 */ - { 2, 5, 12, 84, -6204, 18432, 70, }, /* 617 */ - { 2, 5, 12, 88, -6180, 18432, 70, }, /* 618 */ - { 2, 5, 12, 108, 35267, 18432, 70, }, /* 619 */ - { 17, 9, 12, 0, -3008, 18432, 74, }, /* 620 */ - { 96, 21, 12, 0, 0, 18432, 68, }, /* 621 */ - { 84, 12, 3, 0, 0, 26762, 96, }, /* 622 */ - { 84, 12, 3, 0, 0, 26630, 96, }, /* 623 */ - { 69, 21, 12, 0, 0, 18498, 190, }, /* 624 */ - { 84, 12, 3, 0, 0, 26666, 96, }, /* 625 */ - { 84, 12, 3, 0, 0, 26696, 96, }, /* 626 */ - { 84, 12, 3, 0, 0, 26780, 96, }, /* 627 */ - { 69, 10, 5, 0, 0, 18474, 160, }, /* 628 */ - { 69, 7, 12, 0, 0, 18501, 82, }, /* 629 */ - { 69, 7, 12, 0, 0, 18474, 82, }, /* 630 */ - { 69, 7, 12, 0, 0, 18438, 82, }, /* 631 */ - { 69, 7, 12, 0, 0, 18594, 82, }, /* 632 */ - { 69, 7, 12, 0, 0, 18498, 82, }, /* 633 */ - { 84, 12, 3, 0, 0, 26750, 96, }, /* 634 */ - { 69, 10, 5, 0, 0, 18435, 160, }, /* 635 */ - { 84, 12, 3, 0, 0, 26690, 96, }, /* 636 */ - { 69, 7, 12, 0, 0, 18453, 82, }, /* 637 */ - { 2, 5, 12, 0, 0, 18432, 60, }, /* 638 */ - { 1, 6, 12, 0, 0, 18432, 88, }, /* 639 */ - { 2, 6, 12, 0, 0, 18432, 168, }, /* 640 */ - { 0, 5, 12, 0, 35332, 18432, 76, }, /* 641 */ - { 0, 5, 12, 0, 3814, 18432, 76, }, /* 642 */ - { 0, 5, 12, 0, 35384, 18432, 76, }, /* 643 */ - { 0, 5, 12, 0, 0, 18432, 192, }, /* 644 */ - { 0, 6, 12, 0, 0, 18432, 168, }, /* 645 */ - { 0, 6, 12, 0, 0, 18432, 194, }, /* 646 */ - { 1, 6, 12, 0, 0, 18432, 168, }, /* 647 */ - { 84, 12, 3, 0, 0, 26636, 102, }, /* 648 */ - { 84, 12, 3, 0, 0, 26687, 96, }, /* 649 */ - { 84, 12, 3, 0, 0, 26648, 96, }, /* 650 */ - { 0, 9, 12, 92, 1, 18432, 74, }, /* 651 */ - { 0, 5, 12, 92, -1, 18432, 76, }, /* 652 */ - { 0, 5, 12, 0, 0, 18432, 70, }, /* 653 */ - { 0, 5, 12, 92, -58, 18432, 70, }, /* 654 */ - { 0, 9, 12, 0, -7615, 18432, 74, }, /* 655 */ - { 1, 5, 12, 0, 8, 18432, 76, }, /* 656 */ - { 1, 9, 12, 0, -8, 18432, 74, }, /* 657 */ - { 1, 5, 12, 0, 74, 18432, 76, }, /* 658 */ - { 1, 5, 12, 0, 86, 18432, 76, }, /* 659 */ - { 1, 5, 12, 0, 100, 18432, 76, }, /* 660 */ - { 1, 5, 12, 0, 128, 18432, 76, }, /* 661 */ - { 1, 5, 12, 0, 112, 18432, 76, }, /* 662 */ - { 1, 5, 12, 0, 126, 18432, 76, }, /* 663 */ - { 1, 5, 12, 0, 8, 18432, 70, }, /* 664 */ - { 1, 8, 12, 0, -8, 18432, 86, }, /* 665 */ - { 1, 5, 12, 0, 0, 18432, 70, }, /* 666 */ - { 1, 5, 12, 0, 9, 18432, 70, }, /* 667 */ - { 1, 9, 12, 0, -74, 18432, 74, }, /* 668 */ - { 1, 8, 12, 0, -9, 18432, 86, }, /* 669 */ - { 1, 5, 12, 21, -7173, 18432, 76, }, /* 670 */ - { 1, 9, 12, 0, -86, 18432, 74, }, /* 671 */ - { 1, 9, 12, 0, -100, 18432, 74, }, /* 672 */ - { 1, 9, 12, 0, -112, 18432, 74, }, /* 673 */ - { 1, 9, 12, 0, -128, 18432, 74, }, /* 674 */ - { 1, 9, 12, 0, -126, 18432, 74, }, /* 675 */ - { 69, 29, 12, 0, 0, 45056, 52, }, /* 676 */ - { 84, 1, 3, 0, 0, 6144, 196, }, /* 677 */ - { 84, 1, 13, 0, 0, 6144, 198, }, /* 678 */ - { 69, 1, 2, 0, 0, 18432, 200, }, /* 679 */ - { 69, 1, 2, 0, 0, 34816, 200, }, /* 680 */ - { 69, 17, 12, 0, 0, 28672, 202, }, /* 681 */ - { 69, 21, 12, 0, 0, 28672, 64, }, /* 682 */ - { 69, 20, 12, 0, 0, 28672, 204, }, /* 683 */ - { 69, 19, 12, 0, 0, 28672, 204, }, /* 684 */ - { 69, 22, 12, 0, 0, 28672, 206, }, /* 685 */ - { 69, 20, 12, 0, 0, 28672, 206, }, /* 686 */ - { 69, 19, 12, 0, 0, 28672, 206, }, /* 687 */ - { 69, 21, 12, 0, 0, 28672, 208, }, /* 688 */ - { 69, 27, 2, 0, 0, 45056, 50, }, /* 689 */ - { 69, 28, 2, 0, 0, 4096, 50, }, /* 690 */ - { 69, 1, 2, 0, 0, 20480, 134, }, /* 691 */ - { 69, 1, 2, 0, 0, 36864, 134, }, /* 692 */ - { 69, 1, 2, 0, 0, 30720, 134, }, /* 693 */ - { 69, 1, 2, 0, 0, 24576, 134, }, /* 694 */ - { 69, 1, 2, 0, 0, 40960, 134, }, /* 695 */ - { 69, 29, 12, 0, 0, 8291, 52, }, /* 696 */ - { 69, 21, 12, 0, 0, 14336, 54, }, /* 697 */ - { 69, 21, 12, 0, 0, 14336, 64, }, /* 698 */ - { 69, 21, 14, 0, 0, 28672, 210, }, /* 699 */ - { 69, 21, 12, 0, 0, 28672, 212, }, /* 700 */ - { 69, 16, 12, 0, 0, 28672, 138, }, /* 701 */ - { 69, 16, 12, 0, 0, 28672, 214, }, /* 702 */ - { 69, 25, 12, 0, 0, 8192, 64, }, /* 703 */ - { 69, 22, 12, 0, 0, 28672, 216, }, /* 704 */ - { 69, 18, 12, 0, 0, 28672, 216, }, /* 705 */ - { 69, 21, 12, 0, 0, 28672, 202, }, /* 706 */ - { 69, 1, 2, 0, 0, 6144, 218, }, /* 707 */ - { 68, 2, 2, 0, 0, 6144, 220, }, /* 708 */ - { 69, 1, 2, 0, 0, 22528, 134, }, /* 709 */ - { 69, 1, 2, 0, 0, 38912, 134, }, /* 710 */ - { 69, 1, 2, 0, 0, 16384, 134, }, /* 711 */ - { 69, 1, 2, 0, 0, 32768, 134, }, /* 712 */ - { 69, 1, 2, 0, 0, 6144, 222, }, /* 713 */ - { 69, 25, 12, 0, 0, 12288, 118, }, /* 714 */ - { 69, 25, 12, 0, 0, 12288, 224, }, /* 715 */ - { 69, 25, 12, 0, 0, 28672, 118, }, /* 716 */ - { 69, 22, 12, 0, 0, 28672, 226, }, /* 717 */ - { 69, 18, 12, 0, 0, 28672, 226, }, /* 718 */ - { 68, 2, 12, 0, 0, 14336, 0, }, /* 719 */ - { 84, 12, 3, 0, 0, 26624, 228, }, /* 720 */ - { 84, 11, 3, 0, 0, 26624, 120, }, /* 721 */ - { 84, 11, 3, 0, 0, 26624, 230, }, /* 722 */ - { 84, 12, 3, 0, 0, 26753, 102, }, /* 723 */ - { 69, 26, 12, 0, 0, 28672, 68, }, /* 724 */ - { 69, 9, 12, 0, 0, 18432, 112, }, /* 725 */ - { 69, 5, 12, 0, 0, 18432, 232, }, /* 726 */ - { 69, 25, 12, 0, 0, 28672, 234, }, /* 727 */ - { 69, 26, 14, 0, 0, 28672, 236, }, /* 728 */ - { 1, 9, 12, 96, -7517, 18432, 74, }, /* 729 */ - { 69, 26, 12, 0, 0, 28672, 118, }, /* 730 */ - { 0, 9, 12, 100, 0, 18432, 74, }, /* 731 */ - { 0, 9, 12, 104, -8262, 18432, 74, }, /* 732 */ - { 69, 26, 12, 0, 0, 14336, 238, }, /* 733 */ - { 0, 9, 12, 0, 28, 18432, 74, }, /* 734 */ - { 69, 7, 12, 0, 0, 18432, 240, }, /* 735 */ - { 69, 5, 14, 0, 0, 18432, 242, }, /* 736 */ - { 69, 5, 12, 0, 0, 18432, 244, }, /* 737 */ - { 0, 5, 12, 0, -28, 18432, 76, }, /* 738 */ - { 0, 14, 12, 0, 16, 18432, 74, }, /* 739 */ - { 0, 14, 12, 0, -16, 18432, 76, }, /* 740 */ - { 0, 14, 12, 0, 0, 18432, 82, }, /* 741 */ - { 69, 25, 14, 0, 0, 28672, 246, }, /* 742 */ - { 69, 26, 14, 0, 0, 28672, 246, }, /* 743 */ - { 69, 26, 12, 0, 0, 28672, 64, }, /* 744 */ - { 69, 25, 12, 0, 0, 28672, 248, }, /* 745 */ - { 69, 25, 12, 0, 0, 12288, 250, }, /* 746 */ - { 69, 22, 12, 0, 0, 28672, 248, }, /* 747 */ - { 69, 18, 12, 0, 0, 28672, 248, }, /* 748 */ - { 69, 26, 14, 0, 0, 28672, 252, }, /* 749 */ - { 69, 22, 12, 0, 0, 28672, 254, }, /* 750 */ - { 69, 18, 12, 0, 0, 28672, 254, }, /* 751 */ - { 69, 26, 12, 0, 0, 18432, 54, }, /* 752 */ - { 69, 26, 14, 0, 0, 28672, 256, }, /* 753 */ - { 68, 2, 12, 0, 0, 18432, 258, }, /* 754 */ - { 69, 26, 12, 0, 26, 18432, 260, }, /* 755 */ - { 69, 26, 14, 0, 26, 18432, 262, }, /* 756 */ - { 69, 26, 12, 0, -26, 18432, 264, }, /* 757 */ - { 69, 25, 14, 0, 0, 28672, 266, }, /* 758 */ - { 69, 26, 14, 0, 0, 28672, 268, }, /* 759 */ - { 69, 26, 14, 0, 0, 28672, 270, }, /* 760 */ - { 69, 25, 14, 0, 0, 28672, 268, }, /* 761 */ - { 69, 26, 14, 0, 0, 18432, 256, }, /* 762 */ - { 69, 26, 14, 0, 0, 28672, 272, }, /* 763 */ - { 88, 26, 12, 0, 0, 18432, 54, }, /* 764 */ - { 69, 26, 12, 0, 0, 28672, 216, }, /* 765 */ - { 35, 9, 12, 0, 48, 18432, 74, }, /* 766 */ - { 35, 5, 12, 0, -48, 18432, 76, }, /* 767 */ - { 0, 9, 12, 0, -10743, 18432, 74, }, /* 768 */ - { 0, 9, 12, 0, -3814, 18432, 74, }, /* 769 */ - { 0, 9, 12, 0, -10727, 18432, 74, }, /* 770 */ - { 0, 5, 12, 0, -10795, 18432, 76, }, /* 771 */ - { 0, 5, 12, 0, -10792, 18432, 76, }, /* 772 */ - { 0, 9, 12, 0, -10780, 18432, 74, }, /* 773 */ - { 0, 9, 12, 0, -10749, 18432, 74, }, /* 774 */ - { 0, 9, 12, 0, -10783, 18432, 74, }, /* 775 */ - { 0, 9, 12, 0, -10782, 18432, 74, }, /* 776 */ - { 0, 9, 12, 0, -10815, 18432, 74, }, /* 777 */ - { 34, 5, 12, 0, 0, 18432, 60, }, /* 778 */ - { 34, 26, 12, 0, 0, 28672, 68, }, /* 779 */ - { 34, 12, 3, 0, 0, 26624, 96, }, /* 780 */ - { 34, 21, 12, 0, 0, 28672, 68, }, /* 781 */ - { 34, 15, 12, 0, 0, 28672, 68, }, /* 782 */ - { 17, 5, 12, 0, -7264, 18432, 76, }, /* 783 */ - { 90, 7, 12, 0, 0, 18432, 82, }, /* 784 */ - { 90, 6, 12, 0, 0, 18432, 142, }, /* 785 */ - { 90, 21, 12, 0, 0, 18432, 68, }, /* 786 */ - { 90, 12, 3, 0, 0, 26624, 184, }, /* 787 */ - { 2, 12, 3, 0, 0, 26624, 130, }, /* 788 */ - { 69, 20, 12, 0, 0, 28672, 216, }, /* 789 */ - { 69, 19, 12, 0, 0, 28672, 216, }, /* 790 */ - { 69, 6, 12, 0, 0, 28672, 274, }, /* 791 */ - { 69, 21, 12, 0, 0, 28672, 276, }, /* 792 */ - { 69, 21, 12, 0, 0, 28726, 54, }, /* 793 */ - { 23, 26, 12, 0, 0, 28672, 278, }, /* 794 */ - { 69, 26, 12, 0, 0, 28672, 280, }, /* 795 */ - { 69, 26, 12, 0, 0, 28672, 282, }, /* 796 */ - { 69, 21, 12, 0, 0, 28825, 276, }, /* 797 */ - { 69, 21, 12, 0, 0, 28825, 212, }, /* 798 */ - { 69, 21, 12, 0, 0, 28819, 54, }, /* 799 */ - { 23, 6, 12, 0, 0, 18432, 136, }, /* 800 */ - { 69, 7, 12, 0, 0, 18447, 284, }, /* 801 */ - { 23, 14, 12, 0, 0, 18432, 284, }, /* 802 */ - { 69, 22, 12, 0, 0, 28825, 216, }, /* 803 */ - { 69, 18, 12, 0, 0, 28825, 216, }, /* 804 */ - { 69, 22, 12, 0, 0, 28825, 62, }, /* 805 */ - { 69, 18, 12, 0, 0, 28825, 62, }, /* 806 */ - { 69, 26, 12, 0, 0, 28819, 54, }, /* 807 */ - { 69, 17, 12, 0, 0, 28819, 202, }, /* 808 */ - { 69, 22, 12, 0, 0, 28819, 206, }, /* 809 */ - { 69, 18, 12, 0, 0, 28819, 206, }, /* 810 */ - { 84, 12, 3, 0, 0, 26669, 96, }, /* 811 */ - { 18, 10, 3, 0, 0, 18432, 286, }, /* 812 */ - { 69, 17, 14, 0, 0, 28819, 288, }, /* 813 */ - { 69, 6, 12, 0, 0, 18525, 136, }, /* 814 */ - { 69, 26, 12, 0, 0, 28819, 68, }, /* 815 */ - { 23, 6, 12, 0, 0, 18432, 142, }, /* 816 */ - { 69, 7, 12, 0, 0, 18564, 82, }, /* 817 */ - { 69, 21, 14, 0, 0, 28804, 236, }, /* 818 */ - { 69, 26, 12, 0, 0, 28687, 68, }, /* 819 */ - { 20, 7, 12, 0, 0, 18432, 82, }, /* 820 */ - { 84, 12, 3, 0, 0, 26717, 96, }, /* 821 */ - { 69, 24, 12, 0, 0, 28765, 290, }, /* 822 */ - { 20, 6, 12, 0, 0, 18432, 136, }, /* 823 */ - { 69, 17, 12, 0, 0, 28765, 126, }, /* 824 */ - { 21, 7, 12, 0, 0, 18432, 82, }, /* 825 */ - { 69, 21, 12, 0, 0, 28825, 68, }, /* 826 */ - { 69, 6, 12, 0, 0, 18525, 94, }, /* 827 */ - { 21, 6, 12, 0, 0, 18432, 136, }, /* 828 */ - { 22, 7, 12, 0, 0, 18432, 82, }, /* 829 */ - { 18, 7, 12, 0, 0, 18432, 82, }, /* 830 */ - { 18, 7, 12, 0, 0, 18432, 170, }, /* 831 */ - { 69, 26, 12, 0, 0, 18447, 68, }, /* 832 */ - { 69, 15, 12, 0, 0, 18447, 68, }, /* 833 */ - { 18, 26, 12, 0, 0, 18432, 68, }, /* 834 */ - { 18, 26, 12, 0, 0, 28672, 68, }, /* 835 */ - { 69, 15, 12, 0, 0, 18432, 68, }, /* 836 */ - { 69, 26, 14, 0, 0, 18447, 236, }, /* 837 */ - { 21, 26, 12, 0, 0, 18432, 68, }, /* 838 */ - { 23, 7, 12, 0, 0, 18432, 292, }, /* 839 */ - { 24, 7, 12, 0, 0, 18432, 82, }, /* 840 */ - { 24, 6, 12, 0, 0, 18432, 136, }, /* 841 */ - { 24, 26, 12, 0, 0, 28672, 68, }, /* 842 */ - { 111, 7, 12, 0, 0, 18432, 82, }, /* 843 */ - { 111, 6, 12, 0, 0, 18432, 142, }, /* 844 */ - { 111, 21, 12, 0, 0, 18432, 106, }, /* 845 */ - { 111, 21, 12, 0, 0, 18432, 124, }, /* 846 */ - { 99, 7, 12, 0, 0, 18432, 82, }, /* 847 */ - { 99, 6, 12, 0, 0, 18432, 136, }, /* 848 */ - { 99, 21, 12, 0, 0, 28672, 106, }, /* 849 */ - { 99, 21, 12, 0, 0, 28672, 124, }, /* 850 */ - { 99, 13, 12, 0, 0, 18432, 138, }, /* 851 */ - { 2, 9, 12, 108, 1, 18432, 74, }, /* 852 */ - { 2, 5, 12, 108, -35267, 18432, 76, }, /* 853 */ - { 2, 7, 12, 0, 0, 18432, 82, }, /* 854 */ - { 2, 21, 12, 0, 0, 28672, 68, }, /* 855 */ - { 2, 12, 3, 0, 0, 26624, 96, }, /* 856 */ - { 2, 6, 12, 0, 0, 28672, 92, }, /* 857 */ - { 2, 6, 12, 0, 0, 18432, 88, }, /* 858 */ - { 112, 7, 12, 0, 0, 18432, 82, }, /* 859 */ - { 112, 14, 12, 0, 0, 18432, 82, }, /* 860 */ - { 112, 12, 3, 0, 0, 26624, 96, }, /* 861 */ - { 112, 21, 12, 0, 0, 18432, 68, }, /* 862 */ - { 112, 21, 12, 0, 0, 18432, 124, }, /* 863 */ - { 112, 21, 12, 0, 0, 18432, 106, }, /* 864 */ - { 69, 24, 12, 0, 0, 28762, 56, }, /* 865 */ - { 0, 9, 12, 0, -35332, 18432, 74, }, /* 866 */ - { 69, 24, 12, 0, 0, 18432, 56, }, /* 867 */ - { 0, 9, 12, 0, -42280, 18432, 74, }, /* 868 */ - { 0, 5, 12, 0, 48, 18432, 76, }, /* 869 */ - { 0, 9, 12, 0, -42308, 18432, 74, }, /* 870 */ - { 0, 9, 12, 0, -42319, 18432, 74, }, /* 871 */ - { 0, 9, 12, 0, -42315, 18432, 74, }, /* 872 */ - { 0, 9, 12, 0, -42305, 18432, 74, }, /* 873 */ - { 0, 9, 12, 0, -42258, 18432, 74, }, /* 874 */ - { 0, 9, 12, 0, -42282, 18432, 74, }, /* 875 */ - { 0, 9, 12, 0, -42261, 18432, 74, }, /* 876 */ - { 0, 9, 12, 0, 928, 18432, 74, }, /* 877 */ - { 0, 9, 12, 0, -48, 18432, 74, }, /* 878 */ - { 0, 9, 12, 0, -42307, 18432, 74, }, /* 879 */ - { 0, 9, 12, 0, -35384, 18432, 74, }, /* 880 */ - { 36, 7, 12, 0, 0, 18432, 82, }, /* 881 */ - { 36, 12, 3, 0, 0, 26624, 130, }, /* 882 */ - { 36, 12, 3, 0, 0, 26624, 184, }, /* 883 */ - { 36, 10, 5, 0, 0, 18432, 144, }, /* 884 */ - { 36, 26, 12, 0, 0, 28672, 68, }, /* 885 */ - { 69, 15, 12, 0, 0, 18612, 68, }, /* 886 */ - { 69, 15, 12, 0, 0, 18609, 68, }, /* 887 */ - { 69, 26, 12, 0, 0, 18600, 68, }, /* 888 */ - { 69, 23, 12, 0, 0, 14504, 68, }, /* 889 */ - { 69, 26, 12, 0, 0, 14504, 68, }, /* 890 */ - { 37, 7, 12, 0, 0, 18432, 82, }, /* 891 */ - { 37, 21, 12, 0, 0, 28672, 68, }, /* 892 */ - { 37, 21, 12, 0, 0, 28672, 124, }, /* 893 */ - { 100, 10, 5, 0, 0, 18432, 144, }, /* 894 */ - { 100, 7, 12, 0, 0, 18432, 82, }, /* 895 */ - { 100, 12, 3, 0, 0, 26624, 146, }, /* 896 */ - { 100, 12, 3, 0, 0, 26624, 130, }, /* 897 */ - { 100, 21, 12, 0, 0, 18432, 124, }, /* 898 */ - { 100, 13, 12, 0, 0, 18432, 138, }, /* 899 */ - { 6, 12, 3, 0, 0, 26666, 96, }, /* 900 */ - { 6, 7, 12, 0, 0, 18507, 82, }, /* 901 */ - { 39, 13, 12, 0, 0, 18432, 138, }, /* 902 */ - { 39, 7, 12, 0, 0, 18432, 82, }, /* 903 */ - { 39, 12, 3, 0, 0, 26624, 130, }, /* 904 */ - { 39, 12, 3, 0, 0, 26624, 96, }, /* 905 */ - { 69, 21, 12, 0, 0, 18567, 190, }, /* 906 */ - { 39, 21, 12, 0, 0, 18432, 124, }, /* 907 */ - { 101, 7, 12, 0, 0, 18432, 82, }, /* 908 */ - { 101, 12, 3, 0, 0, 26624, 130, }, /* 909 */ - { 101, 10, 5, 0, 0, 18432, 144, }, /* 910 */ - { 101, 10, 5, 0, 0, 18432, 174, }, /* 911 */ - { 101, 21, 12, 0, 0, 18432, 68, }, /* 912 */ - { 40, 12, 3, 0, 0, 26624, 130, }, /* 913 */ - { 40, 10, 5, 0, 0, 18432, 144, }, /* 914 */ - { 40, 7, 12, 0, 0, 18432, 82, }, /* 915 */ - { 40, 12, 3, 0, 0, 26624, 96, }, /* 916 */ - { 40, 10, 5, 0, 0, 18432, 174, }, /* 917 */ - { 40, 21, 12, 0, 0, 18432, 68, }, /* 918 */ - { 40, 21, 12, 0, 0, 18432, 106, }, /* 919 */ - { 40, 21, 12, 0, 0, 18432, 124, }, /* 920 */ - { 69, 6, 12, 0, 0, 18480, 136, }, /* 921 */ - { 40, 13, 12, 0, 0, 18432, 138, }, /* 922 */ - { 16, 6, 12, 0, 0, 18432, 136, }, /* 923 */ - { 105, 7, 12, 0, 0, 18432, 82, }, /* 924 */ - { 105, 12, 3, 0, 0, 26624, 130, }, /* 925 */ - { 105, 10, 5, 0, 0, 18432, 144, }, /* 926 */ - { 105, 13, 12, 0, 0, 18432, 138, }, /* 927 */ - { 105, 21, 12, 0, 0, 18432, 68, }, /* 928 */ - { 105, 21, 12, 0, 0, 18432, 124, }, /* 929 */ - { 107, 7, 12, 0, 0, 18432, 82, }, /* 930 */ - { 107, 12, 3, 0, 0, 26624, 130, }, /* 931 */ - { 107, 7, 12, 0, 0, 18432, 156, }, /* 932 */ - { 107, 12, 3, 0, 0, 26624, 96, }, /* 933 */ - { 107, 7, 12, 0, 0, 18432, 294, }, /* 934 */ - { 107, 6, 12, 0, 0, 18432, 136, }, /* 935 */ - { 107, 21, 12, 0, 0, 18432, 68, }, /* 936 */ - { 107, 21, 12, 0, 0, 18432, 106, }, /* 937 */ - { 113, 7, 12, 0, 0, 18432, 82, }, /* 938 */ - { 113, 10, 5, 0, 0, 18432, 144, }, /* 939 */ - { 113, 12, 3, 0, 0, 26624, 130, }, /* 940 */ - { 113, 21, 12, 0, 0, 18432, 124, }, /* 941 */ - { 113, 6, 12, 0, 0, 18432, 136, }, /* 942 */ - { 113, 12, 3, 0, 0, 26624, 146, }, /* 943 */ - { 0, 5, 12, 0, -928, 18432, 76, }, /* 944 */ - { 76, 5, 12, 0, -38864, 18432, 70, }, /* 945 */ - { 113, 10, 5, 0, 0, 18432, 160, }, /* 946 */ - { 113, 13, 12, 0, 0, 18432, 138, }, /* 947 */ - { 18, 7, 9, 0, 0, 18432, 82, }, /* 948 */ - { 18, 7, 10, 0, 0, 18432, 82, }, /* 949 */ - { 68, 4, 12, 0, 0, 18432, 0, }, /* 950 */ - { 68, 3, 12, 0, 0, 18432, 0, }, /* 951 */ - { 23, 7, 12, 0, 0, 18432, 284, }, /* 952 */ - { 71, 25, 12, 0, 0, 12288, 118, }, /* 953 */ - { 3, 7, 12, 0, 0, 0, 296, }, /* 954 */ - { 69, 18, 12, 0, 0, 28705, 54, }, /* 955 */ - { 69, 22, 12, 0, 0, 28705, 54, }, /* 956 */ - { 68, 2, 12, 0, 0, 6144, 298, }, /* 957 */ - { 3, 7, 12, 0, 0, 39, 82, }, /* 958 */ - { 3, 26, 12, 0, 0, 28711, 68, }, /* 959 */ - { 84, 12, 3, 0, 0, 26624, 180, }, /* 960 */ - { 84, 12, 3, 0, 0, 26624, 300, }, /* 961 */ - { 69, 21, 12, 0, 0, 28672, 68, }, /* 962 */ - { 69, 21, 12, 0, 0, 28672, 122, }, /* 963 */ - { 69, 22, 12, 0, 0, 28672, 68, }, /* 964 */ - { 69, 18, 12, 0, 0, 28672, 68, }, /* 965 */ - { 69, 17, 12, 0, 0, 28672, 126, }, /* 966 */ - { 69, 22, 12, 0, 0, 28672, 302, }, /* 967 */ - { 69, 18, 12, 0, 0, 28672, 302, }, /* 968 */ - { 69, 21, 12, 0, 0, 8192, 106, }, /* 969 */ - { 69, 21, 12, 0, 0, 8192, 304, }, /* 970 */ - { 69, 21, 12, 0, 0, 8192, 306, }, /* 971 */ - { 69, 21, 12, 0, 0, 28672, 124, }, /* 972 */ - { 69, 22, 12, 0, 0, 28672, 158, }, /* 973 */ - { 69, 18, 12, 0, 0, 28672, 158, }, /* 974 */ - { 69, 21, 12, 0, 0, 14336, 68, }, /* 975 */ - { 69, 21, 12, 0, 0, 28672, 118, }, /* 976 */ - { 69, 17, 12, 0, 0, 12288, 224, }, /* 977 */ - { 69, 25, 12, 0, 0, 28672, 226, }, /* 978 */ - { 69, 21, 12, 0, 0, 28672, 302, }, /* 979 */ - { 69, 21, 12, 0, 0, 28672, 308, }, /* 980 */ - { 69, 17, 12, 0, 0, 12288, 126, }, /* 981 */ - { 69, 21, 12, 0, 0, 8192, 68, }, /* 982 */ - { 69, 13, 12, 0, 0, 10240, 310, }, /* 983 */ - { 0, 9, 12, 0, 32, 18432, 312, }, /* 984 */ - { 69, 24, 12, 0, 0, 28672, 314, }, /* 985 */ - { 0, 5, 12, 0, -32, 18432, 316, }, /* 986 */ - { 69, 21, 12, 0, 0, 28825, 124, }, /* 987 */ - { 69, 22, 12, 0, 0, 28825, 318, }, /* 988 */ - { 69, 18, 12, 0, 0, 28825, 318, }, /* 989 */ - { 69, 21, 12, 0, 0, 28825, 106, }, /* 990 */ - { 69, 6, 3, 0, 0, 18525, 320, }, /* 991 */ - { 69, 1, 2, 0, 0, 28672, 322, }, /* 992 */ - { 31, 7, 12, 0, 0, 18432, 82, }, /* 993 */ - { 69, 21, 12, 0, 0, 18552, 68, }, /* 994 */ - { 69, 21, 12, 0, 0, 28792, 68, }, /* 995 */ - { 69, 21, 12, 0, 0, 18483, 68, }, /* 996 */ - { 69, 15, 12, 0, 0, 18555, 68, }, /* 997 */ - { 69, 26, 12, 0, 0, 18483, 68, }, /* 998 */ - { 1, 14, 12, 0, 0, 28672, 82, }, /* 999 */ - { 1, 15, 12, 0, 0, 28672, 68, }, /* 1000 */ - { 1, 26, 12, 0, 0, 28672, 68, }, /* 1001 */ - { 1, 26, 12, 0, 0, 18432, 68, }, /* 1002 */ - { 102, 7, 12, 0, 0, 18432, 82, }, /* 1003 */ - { 103, 7, 12, 0, 0, 18432, 82, }, /* 1004 */ - { 84, 12, 3, 0, 0, 26651, 96, }, /* 1005 */ - { 69, 15, 12, 0, 0, 10267, 68, }, /* 1006 */ - { 81, 7, 12, 0, 0, 18432, 82, }, /* 1007 */ - { 81, 15, 12, 0, 0, 18432, 68, }, /* 1008 */ - { 82, 7, 12, 0, 0, 18432, 82, }, /* 1009 */ - { 82, 14, 12, 0, 0, 18432, 82, }, /* 1010 */ - { 53, 7, 12, 0, 0, 18432, 82, }, /* 1011 */ - { 53, 12, 3, 0, 0, 26624, 130, }, /* 1012 */ - { 85, 7, 12, 0, 0, 18432, 82, }, /* 1013 */ - { 85, 21, 12, 0, 0, 18432, 106, }, /* 1014 */ - { 91, 7, 12, 0, 0, 18432, 82, }, /* 1015 */ - { 91, 21, 12, 0, 0, 18432, 106, }, /* 1016 */ - { 91, 14, 12, 0, 0, 18432, 82, }, /* 1017 */ - { 83, 9, 12, 0, 40, 18432, 74, }, /* 1018 */ - { 83, 5, 12, 0, -40, 18432, 76, }, /* 1019 */ - { 86, 7, 12, 0, 0, 18432, 82, }, /* 1020 */ - { 87, 7, 12, 0, 0, 18432, 82, }, /* 1021 */ - { 87, 13, 12, 0, 0, 18432, 138, }, /* 1022 */ - { 145, 9, 12, 0, 40, 18432, 74, }, /* 1023 */ - { 145, 5, 12, 0, -40, 18432, 76, }, /* 1024 */ - { 127, 7, 12, 0, 0, 18432, 82, }, /* 1025 */ - { 125, 7, 12, 0, 0, 18432, 82, }, /* 1026 */ - { 125, 21, 12, 0, 0, 18432, 68, }, /* 1027 */ - { 161, 9, 12, 0, 39, 18432, 74, }, /* 1028 */ - { 161, 5, 12, 0, -39, 18432, 76, }, /* 1029 */ - { 49, 7, 12, 0, 0, 18432, 82, }, /* 1030 */ - { 0, 6, 12, 0, 0, 18432, 94, }, /* 1031 */ - { 32, 7, 12, 0, 0, 34816, 82, }, /* 1032 */ - { 114, 7, 12, 0, 0, 34816, 82, }, /* 1033 */ - { 114, 21, 12, 0, 0, 34816, 106, }, /* 1034 */ - { 114, 15, 12, 0, 0, 34816, 68, }, /* 1035 */ - { 133, 7, 12, 0, 0, 34816, 82, }, /* 1036 */ - { 133, 26, 12, 0, 0, 34816, 68, }, /* 1037 */ - { 133, 15, 12, 0, 0, 34816, 68, }, /* 1038 */ - { 132, 7, 12, 0, 0, 34816, 82, }, /* 1039 */ - { 132, 15, 12, 0, 0, 34816, 68, }, /* 1040 */ - { 139, 7, 12, 0, 0, 34816, 82, }, /* 1041 */ - { 139, 15, 12, 0, 0, 34816, 68, }, /* 1042 */ - { 95, 7, 12, 0, 0, 34816, 82, }, /* 1043 */ - { 95, 15, 12, 0, 0, 34816, 68, }, /* 1044 */ - { 95, 21, 12, 0, 0, 28672, 106, }, /* 1045 */ - { 104, 7, 12, 0, 0, 34816, 82, }, /* 1046 */ - { 104, 21, 12, 0, 0, 34816, 68, }, /* 1047 */ - { 122, 7, 12, 0, 0, 34816, 82, }, /* 1048 */ - { 121, 7, 12, 0, 0, 34816, 82, }, /* 1049 */ - { 121, 15, 12, 0, 0, 34816, 68, }, /* 1050 */ - { 92, 7, 12, 0, 0, 34816, 82, }, /* 1051 */ - { 92, 12, 3, 0, 0, 26624, 130, }, /* 1052 */ - { 92, 12, 3, 0, 0, 26624, 102, }, /* 1053 */ - { 92, 12, 3, 0, 0, 26624, 184, }, /* 1054 */ - { 92, 15, 12, 0, 0, 34816, 68, }, /* 1055 */ - { 92, 21, 12, 0, 0, 34816, 68, }, /* 1056 */ - { 92, 21, 12, 0, 0, 34816, 124, }, /* 1057 */ - { 115, 7, 12, 0, 0, 34816, 82, }, /* 1058 */ - { 115, 15, 12, 0, 0, 34816, 68, }, /* 1059 */ - { 115, 21, 12, 0, 0, 34816, 68, }, /* 1060 */ - { 131, 7, 12, 0, 0, 34816, 82, }, /* 1061 */ - { 131, 15, 12, 0, 0, 34816, 68, }, /* 1062 */ - { 51, 7, 12, 0, 0, 34816, 82, }, /* 1063 */ - { 51, 26, 12, 0, 0, 34816, 68, }, /* 1064 */ - { 51, 12, 3, 0, 0, 26624, 96, }, /* 1065 */ - { 51, 15, 12, 0, 0, 34816, 68, }, /* 1066 */ - { 51, 21, 12, 0, 0, 34816, 106, }, /* 1067 */ - { 51, 21, 12, 0, 0, 34918, 106, }, /* 1068 */ - { 51, 21, 12, 0, 0, 34816, 68, }, /* 1069 */ - { 108, 7, 12, 0, 0, 34816, 82, }, /* 1070 */ - { 108, 21, 12, 0, 0, 28672, 68, }, /* 1071 */ - { 108, 21, 12, 0, 0, 28672, 106, }, /* 1072 */ - { 116, 7, 12, 0, 0, 34816, 82, }, /* 1073 */ - { 116, 15, 12, 0, 0, 34816, 68, }, /* 1074 */ - { 117, 7, 12, 0, 0, 34816, 82, }, /* 1075 */ - { 117, 15, 12, 0, 0, 34816, 68, }, /* 1076 */ - { 54, 7, 12, 0, 0, 34816, 82, }, /* 1077 */ - { 54, 21, 12, 0, 0, 34816, 106, }, /* 1078 */ - { 54, 15, 12, 0, 0, 34816, 68, }, /* 1079 */ - { 118, 7, 12, 0, 0, 34816, 82, }, /* 1080 */ - { 140, 9, 12, 0, 64, 34816, 74, }, /* 1081 */ - { 140, 5, 12, 0, -64, 34816, 76, }, /* 1082 */ - { 140, 15, 12, 0, 0, 34816, 68, }, /* 1083 */ - { 62, 7, 12, 0, 0, 0, 82, }, /* 1084 */ - { 62, 7, 12, 0, 0, 0, 294, }, /* 1085 */ - { 62, 12, 3, 0, 0, 26624, 128, }, /* 1086 */ - { 62, 13, 12, 0, 0, 2048, 138, }, /* 1087 */ - { 3, 15, 12, 0, 0, 2048, 68, }, /* 1088 */ - { 65, 7, 12, 0, 0, 34816, 82, }, /* 1089 */ - { 65, 12, 3, 0, 0, 26624, 130, }, /* 1090 */ - { 65, 17, 12, 0, 0, 34816, 126, }, /* 1091 */ - { 152, 7, 12, 0, 0, 34816, 82, }, /* 1092 */ - { 152, 15, 12, 0, 0, 34816, 68, }, /* 1093 */ - { 63, 7, 12, 0, 0, 0, 82, }, /* 1094 */ - { 63, 12, 3, 0, 0, 26624, 96, }, /* 1095 */ - { 63, 15, 12, 0, 0, 0, 68, }, /* 1096 */ - { 63, 21, 12, 0, 0, 0, 124, }, /* 1097 */ - { 67, 7, 12, 0, 0, 34816, 82, }, /* 1098 */ - { 67, 12, 3, 0, 0, 26624, 96, }, /* 1099 */ - { 67, 21, 12, 0, 0, 34816, 124, }, /* 1100 */ - { 156, 7, 12, 0, 0, 34816, 82, }, /* 1101 */ - { 156, 15, 12, 0, 0, 34816, 68, }, /* 1102 */ - { 153, 7, 12, 0, 0, 34816, 82, }, /* 1103 */ - { 120, 10, 5, 0, 0, 18432, 144, }, /* 1104 */ - { 120, 12, 3, 0, 0, 26624, 130, }, /* 1105 */ - { 120, 7, 12, 0, 0, 18432, 82, }, /* 1106 */ - { 120, 12, 3, 0, 0, 26624, 146, }, /* 1107 */ - { 120, 21, 12, 0, 0, 18432, 124, }, /* 1108 */ - { 120, 21, 12, 0, 0, 18432, 106, }, /* 1109 */ - { 120, 15, 12, 0, 0, 28672, 68, }, /* 1110 */ - { 120, 13, 12, 0, 0, 18432, 138, }, /* 1111 */ - { 120, 12, 3, 0, 0, 26624, 184, }, /* 1112 */ - { 41, 12, 3, 0, 0, 26624, 130, }, /* 1113 */ - { 41, 10, 5, 0, 0, 18432, 144, }, /* 1114 */ - { 41, 7, 12, 0, 0, 18432, 82, }, /* 1115 */ - { 41, 12, 3, 0, 0, 26624, 146, }, /* 1116 */ - { 41, 12, 3, 0, 0, 26624, 96, }, /* 1117 */ - { 41, 21, 12, 0, 0, 18432, 68, }, /* 1118 */ - { 41, 1, 4, 0, 0, 18432, 132, }, /* 1119 */ - { 41, 21, 12, 0, 0, 18432, 124, }, /* 1120 */ - { 124, 7, 12, 0, 0, 18432, 82, }, /* 1121 */ - { 124, 13, 12, 0, 0, 18432, 138, }, /* 1122 */ - { 43, 12, 3, 0, 0, 26624, 130, }, /* 1123 */ - { 43, 7, 12, 0, 0, 18432, 82, }, /* 1124 */ - { 43, 10, 5, 0, 0, 18432, 144, }, /* 1125 */ - { 43, 12, 3, 0, 0, 26624, 146, }, /* 1126 */ - { 43, 13, 12, 0, 0, 18432, 138, }, /* 1127 */ - { 43, 21, 12, 0, 0, 18432, 68, }, /* 1128 */ - { 43, 21, 12, 0, 0, 18432, 124, }, /* 1129 */ - { 50, 7, 12, 0, 0, 18432, 82, }, /* 1130 */ - { 50, 12, 3, 0, 0, 26624, 96, }, /* 1131 */ - { 50, 21, 12, 0, 0, 18432, 68, }, /* 1132 */ - { 44, 12, 3, 0, 0, 26624, 130, }, /* 1133 */ - { 44, 10, 5, 0, 0, 18432, 144, }, /* 1134 */ - { 44, 7, 12, 0, 0, 18432, 82, }, /* 1135 */ - { 44, 10, 5, 0, 0, 18432, 174, }, /* 1136 */ - { 44, 7, 4, 0, 0, 18432, 82, }, /* 1137 */ - { 44, 21, 12, 0, 0, 18432, 124, }, /* 1138 */ - { 44, 21, 12, 0, 0, 18432, 68, }, /* 1139 */ - { 44, 12, 3, 0, 0, 26624, 102, }, /* 1140 */ - { 44, 12, 3, 0, 0, 26624, 96, }, /* 1141 */ - { 44, 13, 12, 0, 0, 18432, 138, }, /* 1142 */ - { 15, 15, 12, 0, 0, 18432, 68, }, /* 1143 */ - { 48, 7, 12, 0, 0, 18432, 82, }, /* 1144 */ - { 48, 10, 5, 0, 0, 18432, 144, }, /* 1145 */ - { 48, 12, 3, 0, 0, 26624, 130, }, /* 1146 */ - { 48, 10, 5, 0, 0, 18432, 174, }, /* 1147 */ - { 48, 12, 3, 0, 0, 26624, 96, }, /* 1148 */ - { 48, 21, 12, 0, 0, 18432, 124, }, /* 1149 */ - { 48, 21, 12, 0, 0, 18432, 106, }, /* 1150 */ - { 48, 21, 12, 0, 0, 18432, 68, }, /* 1151 */ - { 57, 7, 12, 0, 0, 18432, 82, }, /* 1152 */ - { 57, 21, 12, 0, 0, 18432, 124, }, /* 1153 */ - { 55, 7, 12, 0, 0, 18432, 82, }, /* 1154 */ - { 55, 12, 3, 0, 0, 26624, 130, }, /* 1155 */ - { 55, 10, 5, 0, 0, 18432, 144, }, /* 1156 */ - { 55, 12, 3, 0, 0, 26624, 96, }, /* 1157 */ - { 55, 12, 3, 0, 0, 26624, 146, }, /* 1158 */ - { 55, 13, 12, 0, 0, 18432, 138, }, /* 1159 */ - { 47, 12, 3, 0, 0, 26624, 130, }, /* 1160 */ - { 47, 12, 3, 0, 0, 26705, 130, }, /* 1161 */ - { 47, 10, 5, 0, 0, 18432, 144, }, /* 1162 */ - { 47, 10, 5, 0, 0, 18513, 144, }, /* 1163 */ - { 47, 7, 12, 0, 0, 18432, 82, }, /* 1164 */ - { 84, 12, 3, 0, 0, 26705, 102, }, /* 1165 */ - { 47, 12, 3, 0, 0, 26705, 96, }, /* 1166 */ - { 47, 10, 3, 0, 0, 18432, 148, }, /* 1167 */ - { 47, 10, 5, 0, 0, 18432, 174, }, /* 1168 */ - { 47, 7, 12, 0, 0, 18432, 324, }, /* 1169 */ - { 47, 12, 3, 0, 0, 26624, 96, }, /* 1170 */ - { 144, 7, 12, 0, 0, 18432, 82, }, /* 1171 */ - { 144, 10, 5, 0, 0, 18432, 144, }, /* 1172 */ - { 144, 12, 3, 0, 0, 26624, 130, }, /* 1173 */ - { 144, 12, 3, 0, 0, 26624, 146, }, /* 1174 */ - { 144, 12, 3, 0, 0, 26624, 96, }, /* 1175 */ - { 144, 21, 12, 0, 0, 18432, 124, }, /* 1176 */ - { 144, 21, 12, 0, 0, 18432, 106, }, /* 1177 */ - { 144, 21, 12, 0, 0, 18432, 68, }, /* 1178 */ - { 144, 13, 12, 0, 0, 18432, 138, }, /* 1179 */ - { 144, 12, 3, 0, 0, 26624, 102, }, /* 1180 */ - { 56, 7, 12, 0, 0, 18432, 82, }, /* 1181 */ - { 56, 10, 3, 0, 0, 18432, 148, }, /* 1182 */ - { 56, 10, 5, 0, 0, 18432, 144, }, /* 1183 */ - { 56, 12, 3, 0, 0, 26624, 130, }, /* 1184 */ - { 56, 12, 3, 0, 0, 26624, 146, }, /* 1185 */ - { 56, 12, 3, 0, 0, 26624, 96, }, /* 1186 */ - { 56, 21, 12, 0, 0, 18432, 68, }, /* 1187 */ - { 56, 13, 12, 0, 0, 18432, 138, }, /* 1188 */ - { 135, 7, 12, 0, 0, 18432, 82, }, /* 1189 */ - { 135, 10, 3, 0, 0, 18432, 148, }, /* 1190 */ - { 135, 10, 5, 0, 0, 18432, 144, }, /* 1191 */ - { 135, 12, 3, 0, 0, 26624, 130, }, /* 1192 */ - { 135, 12, 3, 0, 0, 26624, 146, }, /* 1193 */ - { 135, 12, 3, 0, 0, 26624, 96, }, /* 1194 */ - { 135, 21, 12, 0, 0, 18432, 68, }, /* 1195 */ - { 135, 21, 12, 0, 0, 18432, 124, }, /* 1196 */ - { 135, 21, 12, 0, 0, 18432, 106, }, /* 1197 */ - { 135, 21, 12, 0, 0, 18432, 178, }, /* 1198 */ - { 52, 7, 12, 0, 0, 18432, 82, }, /* 1199 */ - { 52, 10, 5, 0, 0, 18432, 144, }, /* 1200 */ - { 52, 12, 3, 0, 0, 26624, 130, }, /* 1201 */ - { 52, 12, 3, 0, 0, 26624, 146, }, /* 1202 */ - { 52, 21, 12, 0, 0, 18432, 124, }, /* 1203 */ - { 52, 21, 12, 0, 0, 18432, 68, }, /* 1204 */ - { 52, 13, 12, 0, 0, 18432, 138, }, /* 1205 */ - { 45, 7, 12, 0, 0, 18432, 82, }, /* 1206 */ - { 45, 12, 3, 0, 0, 26624, 130, }, /* 1207 */ - { 45, 10, 5, 0, 0, 18432, 144, }, /* 1208 */ - { 45, 10, 5, 0, 0, 18432, 174, }, /* 1209 */ - { 45, 12, 3, 0, 0, 26624, 96, }, /* 1210 */ - { 45, 21, 12, 0, 0, 18432, 68, }, /* 1211 */ - { 45, 13, 12, 0, 0, 18432, 138, }, /* 1212 */ - { 137, 7, 12, 0, 0, 18432, 82, }, /* 1213 */ - { 137, 12, 3, 0, 0, 26624, 130, }, /* 1214 */ - { 137, 10, 12, 0, 0, 18432, 144, }, /* 1215 */ - { 137, 10, 5, 0, 0, 18432, 144, }, /* 1216 */ - { 137, 12, 3, 0, 0, 26624, 146, }, /* 1217 */ - { 137, 13, 12, 0, 0, 18432, 138, }, /* 1218 */ - { 137, 15, 12, 0, 0, 18432, 68, }, /* 1219 */ - { 137, 21, 12, 0, 0, 18432, 124, }, /* 1220 */ - { 137, 26, 12, 0, 0, 18432, 68, }, /* 1221 */ - { 60, 7, 12, 0, 0, 18432, 82, }, /* 1222 */ - { 60, 10, 5, 0, 0, 18432, 144, }, /* 1223 */ - { 60, 12, 3, 0, 0, 26624, 130, }, /* 1224 */ - { 60, 12, 3, 0, 0, 26624, 146, }, /* 1225 */ - { 60, 12, 3, 0, 0, 26624, 96, }, /* 1226 */ - { 60, 21, 12, 0, 0, 18432, 68, }, /* 1227 */ - { 136, 9, 12, 0, 32, 18432, 74, }, /* 1228 */ - { 136, 5, 12, 0, -32, 18432, 76, }, /* 1229 */ - { 136, 13, 12, 0, 0, 18432, 138, }, /* 1230 */ - { 136, 15, 12, 0, 0, 18432, 68, }, /* 1231 */ - { 136, 7, 12, 0, 0, 18432, 82, }, /* 1232 */ - { 157, 7, 12, 0, 0, 18432, 82, }, /* 1233 */ - { 157, 10, 3, 0, 0, 18432, 148, }, /* 1234 */ - { 157, 10, 5, 0, 0, 18432, 144, }, /* 1235 */ - { 157, 12, 3, 0, 0, 26624, 130, }, /* 1236 */ - { 157, 10, 5, 0, 0, 18432, 174, }, /* 1237 */ - { 157, 12, 3, 0, 0, 26624, 146, }, /* 1238 */ - { 157, 7, 4, 0, 0, 18432, 82, }, /* 1239 */ - { 157, 12, 3, 0, 0, 26624, 96, }, /* 1240 */ - { 157, 21, 12, 0, 0, 18432, 124, }, /* 1241 */ - { 157, 21, 12, 0, 0, 18432, 68, }, /* 1242 */ - { 157, 13, 12, 0, 0, 18432, 138, }, /* 1243 */ - { 64, 7, 12, 0, 0, 18432, 82, }, /* 1244 */ - { 64, 10, 5, 0, 0, 18432, 144, }, /* 1245 */ - { 64, 12, 3, 0, 0, 26624, 130, }, /* 1246 */ - { 64, 12, 3, 0, 0, 26624, 146, }, /* 1247 */ - { 64, 21, 12, 0, 0, 18432, 68, }, /* 1248 */ - { 149, 7, 12, 0, 0, 18432, 82, }, /* 1249 */ - { 149, 12, 3, 0, 0, 26624, 130, }, /* 1250 */ - { 149, 12, 3, 0, 0, 18432, 130, }, /* 1251 */ - { 149, 12, 3, 0, 0, 26624, 102, }, /* 1252 */ - { 149, 12, 3, 0, 0, 26624, 146, }, /* 1253 */ - { 149, 10, 5, 0, 0, 18432, 144, }, /* 1254 */ - { 149, 7, 4, 0, 0, 18432, 82, }, /* 1255 */ - { 149, 21, 12, 0, 0, 18432, 68, }, /* 1256 */ - { 149, 21, 12, 0, 0, 18432, 124, }, /* 1257 */ - { 148, 7, 12, 0, 0, 18432, 82, }, /* 1258 */ - { 148, 12, 3, 0, 0, 26624, 130, }, /* 1259 */ - { 148, 10, 5, 0, 0, 18432, 144, }, /* 1260 */ - { 148, 7, 4, 0, 0, 18432, 82, }, /* 1261 */ - { 148, 12, 3, 0, 0, 26624, 326, }, /* 1262 */ - { 148, 12, 3, 0, 0, 26624, 146, }, /* 1263 */ - { 148, 21, 12, 0, 0, 18432, 68, }, /* 1264 */ - { 148, 21, 12, 0, 0, 18432, 124, }, /* 1265 */ - { 148, 21, 12, 0, 0, 18432, 106, }, /* 1266 */ - { 134, 7, 12, 0, 0, 18432, 82, }, /* 1267 */ - { 142, 7, 12, 0, 0, 18432, 82, }, /* 1268 */ - { 142, 10, 5, 0, 0, 18432, 144, }, /* 1269 */ - { 142, 12, 3, 0, 0, 26624, 130, }, /* 1270 */ - { 142, 12, 3, 0, 0, 18432, 146, }, /* 1271 */ - { 142, 21, 12, 0, 0, 18432, 124, }, /* 1272 */ - { 142, 21, 12, 0, 0, 18432, 106, }, /* 1273 */ - { 142, 21, 12, 0, 0, 18432, 68, }, /* 1274 */ - { 142, 13, 12, 0, 0, 18432, 138, }, /* 1275 */ - { 142, 15, 12, 0, 0, 18432, 68, }, /* 1276 */ - { 143, 21, 12, 0, 0, 18432, 68, }, /* 1277 */ - { 143, 21, 12, 0, 0, 18432, 106, }, /* 1278 */ - { 143, 7, 12, 0, 0, 18432, 82, }, /* 1279 */ - { 143, 12, 3, 0, 0, 26624, 130, }, /* 1280 */ - { 143, 10, 5, 0, 0, 18432, 144, }, /* 1281 */ - { 59, 7, 12, 0, 0, 18432, 82, }, /* 1282 */ - { 59, 12, 3, 0, 0, 26624, 130, }, /* 1283 */ - { 59, 12, 3, 0, 0, 26624, 96, }, /* 1284 */ - { 59, 12, 3, 0, 0, 26624, 146, }, /* 1285 */ - { 59, 7, 4, 0, 0, 18432, 82, }, /* 1286 */ - { 59, 13, 12, 0, 0, 18432, 138, }, /* 1287 */ - { 61, 7, 12, 0, 0, 18432, 82, }, /* 1288 */ - { 61, 10, 5, 0, 0, 18432, 144, }, /* 1289 */ - { 61, 12, 3, 0, 0, 26624, 130, }, /* 1290 */ - { 61, 12, 3, 0, 0, 26624, 146, }, /* 1291 */ - { 61, 13, 12, 0, 0, 18432, 138, }, /* 1292 */ - { 150, 7, 12, 0, 0, 18432, 82, }, /* 1293 */ - { 150, 12, 3, 0, 0, 26624, 130, }, /* 1294 */ - { 150, 10, 5, 0, 0, 18432, 144, }, /* 1295 */ - { 150, 21, 12, 0, 0, 18432, 124, }, /* 1296 */ - { 162, 12, 3, 0, 0, 26624, 130, }, /* 1297 */ - { 162, 7, 4, 0, 0, 18432, 82, }, /* 1298 */ - { 162, 10, 5, 0, 0, 18432, 144, }, /* 1299 */ - { 162, 7, 12, 0, 0, 18432, 82, }, /* 1300 */ - { 162, 10, 5, 0, 0, 18432, 176, }, /* 1301 */ - { 162, 12, 3, 0, 0, 26624, 184, }, /* 1302 */ - { 162, 21, 12, 0, 0, 18432, 124, }, /* 1303 */ - { 162, 21, 12, 0, 0, 18432, 68, }, /* 1304 */ - { 162, 13, 12, 0, 0, 18432, 138, }, /* 1305 */ - { 11, 15, 12, 0, 0, 18432, 68, }, /* 1306 */ - { 11, 21, 12, 0, 0, 18432, 68, }, /* 1307 */ - { 94, 7, 12, 0, 0, 18432, 82, }, /* 1308 */ - { 94, 14, 12, 0, 0, 18432, 82, }, /* 1309 */ - { 94, 21, 12, 0, 0, 18432, 106, }, /* 1310 */ - { 66, 7, 12, 0, 0, 18432, 82, }, /* 1311 */ - { 66, 21, 12, 0, 0, 18432, 68, }, /* 1312 */ - { 109, 7, 12, 0, 0, 18432, 82, }, /* 1313 */ - { 109, 1, 2, 0, 0, 18432, 322, }, /* 1314 */ - { 109, 12, 3, 0, 0, 26624, 102, }, /* 1315 */ - { 109, 12, 3, 0, 0, 26624, 96, }, /* 1316 */ - { 138, 7, 12, 0, 0, 18432, 82, }, /* 1317 */ - { 130, 7, 12, 0, 0, 18432, 82, }, /* 1318 */ - { 130, 13, 12, 0, 0, 18432, 138, }, /* 1319 */ - { 130, 21, 12, 0, 0, 18432, 124, }, /* 1320 */ - { 159, 7, 12, 0, 0, 18432, 82, }, /* 1321 */ - { 159, 13, 12, 0, 0, 18432, 138, }, /* 1322 */ - { 126, 7, 12, 0, 0, 18432, 82, }, /* 1323 */ - { 126, 12, 3, 0, 0, 26624, 96, }, /* 1324 */ - { 126, 21, 12, 0, 0, 18432, 124, }, /* 1325 */ - { 128, 7, 12, 0, 0, 18432, 82, }, /* 1326 */ - { 128, 12, 3, 0, 0, 26624, 96, }, /* 1327 */ - { 128, 21, 12, 0, 0, 18432, 124, }, /* 1328 */ - { 128, 21, 12, 0, 0, 18432, 106, }, /* 1329 */ - { 128, 21, 12, 0, 0, 18432, 68, }, /* 1330 */ - { 128, 26, 12, 0, 0, 18432, 68, }, /* 1331 */ - { 128, 6, 12, 0, 0, 18432, 142, }, /* 1332 */ - { 128, 6, 12, 0, 0, 18432, 136, }, /* 1333 */ - { 128, 13, 12, 0, 0, 18432, 138, }, /* 1334 */ - { 128, 15, 12, 0, 0, 18432, 68, }, /* 1335 */ - { 151, 9, 12, 0, 32, 18432, 74, }, /* 1336 */ - { 151, 5, 12, 0, -32, 18432, 76, }, /* 1337 */ - { 151, 15, 12, 0, 0, 18432, 68, }, /* 1338 */ - { 151, 21, 12, 0, 0, 18432, 106, }, /* 1339 */ - { 151, 21, 12, 0, 0, 18432, 124, }, /* 1340 */ - { 151, 21, 12, 0, 0, 18432, 68, }, /* 1341 */ - { 123, 7, 12, 0, 0, 18432, 82, }, /* 1342 */ - { 123, 12, 3, 0, 0, 26624, 130, }, /* 1343 */ - { 123, 10, 5, 0, 0, 18432, 144, }, /* 1344 */ - { 123, 12, 3, 0, 0, 26624, 128, }, /* 1345 */ - { 123, 6, 12, 0, 0, 18432, 92, }, /* 1346 */ - { 146, 6, 12, 0, 0, 18432, 136, }, /* 1347 */ - { 147, 6, 12, 0, 0, 18432, 136, }, /* 1348 */ - { 23, 21, 12, 0, 0, 28672, 68, }, /* 1349 */ - { 158, 12, 3, 0, 0, 26624, 328, }, /* 1350 */ - { 23, 10, 5, 0, 0, 18432, 164, }, /* 1351 */ - { 146, 7, 12, 0, 0, 18432, 284, }, /* 1352 */ - { 158, 7, 12, 0, 0, 18432, 284, }, /* 1353 */ - { 21, 6, 12, 0, 0, 18432, 92, }, /* 1354 */ - { 147, 7, 12, 0, 0, 18432, 284, }, /* 1355 */ - { 46, 7, 12, 0, 0, 18432, 82, }, /* 1356 */ - { 46, 26, 12, 0, 0, 18432, 68, }, /* 1357 */ - { 46, 12, 3, 0, 0, 26624, 102, }, /* 1358 */ - { 46, 12, 3, 0, 0, 26624, 130, }, /* 1359 */ - { 46, 21, 12, 0, 0, 18432, 124, }, /* 1360 */ - { 69, 1, 2, 0, 0, 6153, 66, }, /* 1361 */ - { 69, 10, 3, 0, 0, 18432, 330, }, /* 1362 */ - { 69, 10, 5, 0, 0, 18432, 138, }, /* 1363 */ - { 69, 10, 5, 0, 0, 18432, 160, }, /* 1364 */ - { 69, 10, 3, 0, 0, 18432, 286, }, /* 1365 */ - { 1, 12, 3, 0, 0, 26624, 102, }, /* 1366 */ - { 69, 25, 12, 0, 0, 18432, 118, }, /* 1367 */ - { 69, 13, 12, 0, 0, 10240, 214, }, /* 1368 */ - { 141, 26, 12, 0, 0, 18432, 68, }, /* 1369 */ - { 141, 12, 3, 0, 0, 26624, 102, }, /* 1370 */ - { 141, 21, 12, 0, 0, 18432, 106, }, /* 1371 */ - { 141, 21, 12, 0, 0, 18432, 124, }, /* 1372 */ - { 141, 21, 12, 0, 0, 18432, 68, }, /* 1373 */ - { 35, 12, 3, 0, 0, 26624, 130, }, /* 1374 */ - { 2, 6, 12, 0, 0, 18432, 90, }, /* 1375 */ - { 154, 7, 12, 0, 0, 18432, 82, }, /* 1376 */ - { 154, 12, 3, 0, 0, 26624, 96, }, /* 1377 */ - { 154, 6, 12, 0, 0, 18432, 142, }, /* 1378 */ - { 154, 6, 12, 0, 0, 18432, 136, }, /* 1379 */ - { 154, 13, 12, 0, 0, 18432, 138, }, /* 1380 */ - { 154, 26, 12, 0, 0, 18432, 68, }, /* 1381 */ - { 160, 7, 12, 0, 0, 18432, 82, }, /* 1382 */ - { 160, 12, 3, 0, 0, 26624, 96, }, /* 1383 */ - { 155, 7, 12, 0, 0, 18432, 82, }, /* 1384 */ - { 155, 12, 3, 0, 0, 26624, 96, }, /* 1385 */ - { 155, 13, 12, 0, 0, 18432, 138, }, /* 1386 */ - { 155, 23, 12, 0, 0, 14336, 68, }, /* 1387 */ - { 163, 7, 12, 0, 0, 18432, 82, }, /* 1388 */ - { 163, 6, 12, 0, 0, 18432, 142, }, /* 1389 */ - { 163, 12, 3, 0, 0, 26624, 102, }, /* 1390 */ - { 163, 13, 12, 0, 0, 18432, 138, }, /* 1391 */ - { 129, 7, 12, 0, 0, 34816, 82, }, /* 1392 */ - { 129, 15, 12, 0, 0, 34816, 68, }, /* 1393 */ - { 129, 12, 3, 0, 0, 26624, 96, }, /* 1394 */ - { 58, 9, 12, 0, 34, 34816, 74, }, /* 1395 */ - { 58, 5, 12, 0, -34, 34816, 76, }, /* 1396 */ - { 58, 12, 3, 0, 0, 26624, 150, }, /* 1397 */ - { 58, 12, 3, 0, 0, 26624, 130, }, /* 1398 */ - { 58, 12, 3, 0, 0, 26624, 96, }, /* 1399 */ - { 58, 6, 12, 0, 0, 34816, 142, }, /* 1400 */ - { 58, 13, 12, 0, 0, 34816, 138, }, /* 1401 */ - { 58, 21, 12, 0, 0, 34816, 68, }, /* 1402 */ - { 69, 15, 12, 0, 0, 0, 68, }, /* 1403 */ - { 69, 26, 12, 0, 0, 0, 68, }, /* 1404 */ - { 69, 23, 12, 0, 0, 0, 68, }, /* 1405 */ - { 3, 7, 12, 0, 0, 0, 240, }, /* 1406 */ - { 69, 26, 14, 0, 0, 28672, 332, }, /* 1407 */ - { 69, 26, 14, 0, 0, 28672, 334, }, /* 1408 */ - { 68, 2, 14, 0, 0, 18432, 336, }, /* 1409 */ - { 69, 26, 12, 0, 0, 18432, 338, }, /* 1410 */ - { 69, 26, 14, 0, 0, 18432, 340, }, /* 1411 */ - { 69, 26, 14, 0, 0, 18432, 334, }, /* 1412 */ - { 69, 26, 11, 0, 0, 18432, 342, }, /* 1413 */ - { 20, 26, 12, 0, 0, 18432, 68, }, /* 1414 */ - { 69, 26, 14, 0, 0, 18432, 236, }, /* 1415 */ - { 69, 26, 14, 0, 0, 18447, 334, }, /* 1416 */ - { 69, 26, 14, 0, 0, 28672, 344, }, /* 1417 */ - { 69, 26, 14, 0, 0, 28672, 346, }, /* 1418 */ - { 69, 24, 3, 0, 0, 28672, 348, }, /* 1419 */ - { 69, 26, 14, 0, 0, 28672, 350, }, /* 1420 */ - { 69, 13, 12, 0, 0, 10240, 138, }, /* 1421 */ - { 69, 1, 3, 0, 0, 6144, 352, }, /* 1422 */ + { 0, 5, 12, 0, 195, 18432, 78, }, /* 74 */ + { 0, 9, 12, 0, 210, 18432, 76, }, /* 75 */ + { 0, 9, 12, 0, 206, 18432, 76, }, /* 76 */ + { 0, 9, 12, 0, 205, 18432, 76, }, /* 77 */ + { 0, 9, 12, 0, 79, 18432, 76, }, /* 78 */ + { 0, 9, 12, 0, 202, 18432, 76, }, /* 79 */ + { 0, 9, 12, 0, 203, 18432, 76, }, /* 80 */ + { 0, 9, 12, 0, 207, 18432, 76, }, /* 81 */ + { 0, 5, 12, 0, 97, 18432, 78, }, /* 82 */ + { 0, 9, 12, 0, 211, 18432, 76, }, /* 83 */ + { 0, 9, 12, 0, 209, 18432, 76, }, /* 84 */ + { 0, 5, 12, 0, 163, 18432, 78, }, /* 85 */ + { 0, 5, 12, 0, 42561, 18432, 78, }, /* 86 */ + { 0, 9, 12, 0, 213, 18432, 76, }, /* 87 */ + { 0, 5, 12, 0, 130, 18432, 78, }, /* 88 */ + { 0, 9, 12, 0, 214, 18432, 76, }, /* 89 */ + { 0, 9, 12, 0, 218, 18432, 76, }, /* 90 */ + { 0, 9, 12, 0, 217, 18432, 76, }, /* 91 */ + { 0, 9, 12, 0, 219, 18432, 76, }, /* 92 */ + { 0, 7, 12, 0, 0, 18432, 84, }, /* 93 */ + { 0, 5, 12, 0, 56, 18432, 78, }, /* 94 */ + { 0, 9, 12, 5, 2, 18432, 86, }, /* 95 */ + { 0, 8, 12, 5, 1, 18432, 88, }, /* 96 */ + { 0, 5, 12, 5, -2, 18432, 78, }, /* 97 */ + { 0, 9, 12, 9, 2, 18432, 86, }, /* 98 */ + { 0, 8, 12, 9, 1, 18432, 88, }, /* 99 */ + { 0, 5, 12, 9, -2, 18432, 78, }, /* 100 */ + { 0, 9, 12, 13, 2, 18432, 86, }, /* 101 */ + { 0, 8, 12, 13, 1, 18432, 88, }, /* 102 */ + { 0, 5, 12, 13, -2, 18432, 78, }, /* 103 */ + { 0, 5, 12, 0, -79, 18432, 78, }, /* 104 */ + { 0, 9, 12, 17, 2, 18432, 86, }, /* 105 */ + { 0, 8, 12, 17, 1, 18432, 88, }, /* 106 */ + { 0, 5, 12, 17, -2, 18432, 78, }, /* 107 */ + { 0, 9, 12, 0, -97, 18432, 76, }, /* 108 */ + { 0, 9, 12, 0, -56, 18432, 76, }, /* 109 */ + { 0, 9, 12, 0, -130, 18432, 76, }, /* 110 */ + { 0, 9, 12, 0, 10795, 18432, 76, }, /* 111 */ + { 0, 9, 12, 0, -163, 18432, 76, }, /* 112 */ + { 0, 9, 12, 0, 10792, 18432, 76, }, /* 113 */ + { 0, 5, 12, 0, 10815, 18432, 78, }, /* 114 */ + { 0, 9, 12, 0, -195, 18432, 76, }, /* 115 */ + { 0, 9, 12, 0, 69, 18432, 76, }, /* 116 */ + { 0, 9, 12, 0, 71, 18432, 76, }, /* 117 */ + { 0, 5, 12, 0, 10783, 18432, 78, }, /* 118 */ + { 0, 5, 12, 0, 10780, 18432, 78, }, /* 119 */ + { 0, 5, 12, 0, 10782, 18432, 78, }, /* 120 */ + { 0, 5, 12, 0, -210, 18432, 78, }, /* 121 */ + { 0, 5, 12, 0, -206, 18432, 78, }, /* 122 */ + { 0, 5, 12, 0, -205, 18432, 78, }, /* 123 */ + { 0, 5, 12, 0, -202, 18432, 78, }, /* 124 */ + { 0, 5, 12, 0, -203, 18432, 78, }, /* 125 */ + { 0, 5, 12, 0, 42319, 18432, 78, }, /* 126 */ + { 0, 5, 12, 0, 42315, 18432, 78, }, /* 127 */ + { 0, 5, 12, 0, -207, 18432, 78, }, /* 128 */ + { 0, 5, 12, 0, 42343, 18432, 78, }, /* 129 */ + { 0, 5, 12, 0, 42280, 18432, 78, }, /* 130 */ + { 0, 5, 12, 0, 42308, 18432, 78, }, /* 131 */ + { 0, 5, 12, 0, -209, 18432, 80, }, /* 132 */ + { 0, 5, 12, 0, -211, 18432, 78, }, /* 133 */ + { 0, 5, 12, 0, 10743, 18432, 78, }, /* 134 */ + { 0, 5, 12, 0, 42305, 18432, 78, }, /* 135 */ + { 0, 5, 12, 0, 10749, 18432, 78, }, /* 136 */ + { 0, 5, 12, 0, -213, 18432, 78, }, /* 137 */ + { 0, 5, 12, 0, -214, 18432, 78, }, /* 138 */ + { 0, 5, 12, 0, 10727, 18432, 78, }, /* 139 */ + { 0, 5, 12, 0, -218, 18432, 78, }, /* 140 */ + { 0, 5, 12, 0, 42307, 18432, 78, }, /* 141 */ + { 0, 5, 12, 0, 42282, 18432, 78, }, /* 142 */ + { 0, 5, 12, 0, -69, 18432, 78, }, /* 143 */ + { 0, 5, 12, 0, -217, 18432, 78, }, /* 144 */ + { 0, 5, 12, 0, -71, 18432, 78, }, /* 145 */ + { 0, 5, 12, 0, -219, 18432, 78, }, /* 146 */ + { 0, 5, 12, 0, 42261, 18432, 80, }, /* 147 */ + { 0, 5, 12, 0, 42258, 18432, 78, }, /* 148 */ + { 0, 6, 12, 0, 0, 18432, 90, }, /* 149 */ + { 0, 6, 12, 0, 0, 18432, 92, }, /* 150 */ + { 99, 6, 12, 0, 0, 28672, 94, }, /* 151 */ + { 99, 6, 12, 0, 0, 18432, 94, }, /* 152 */ + { 99, 6, 12, 0, 0, 18440, 94, }, /* 153 */ + { 99, 6, 12, 0, 0, 18432, 90, }, /* 154 */ + { 99, 6, 12, 0, 0, 28684, 94, }, /* 155 */ + { 99, 6, 12, 0, 0, 28688, 94, }, /* 156 */ + { 99, 6, 12, 0, 0, 18432, 96, }, /* 157 */ + { 99, 24, 12, 0, 0, 28692, 56, }, /* 158 */ + { 99, 24, 12, 0, 0, 28684, 56, }, /* 159 */ + { 29, 24, 12, 0, 0, 28672, 56, }, /* 160 */ + { 106, 12, 3, 0, 0, 26648, 98, }, /* 161 */ + { 106, 12, 3, 0, 0, 26652, 98, }, /* 162 */ + { 106, 12, 3, 0, 0, 26656, 98, }, /* 163 */ + { 106, 12, 3, 0, 0, 26660, 98, }, /* 164 */ + { 106, 12, 3, 0, 0, 26664, 98, }, /* 165 */ + { 106, 12, 3, 0, 0, 26668, 98, }, /* 166 */ + { 106, 12, 3, 0, 0, 26672, 98, }, /* 167 */ + { 106, 12, 3, 0, 0, 26676, 98, }, /* 168 */ + { 106, 12, 3, 0, 0, 26680, 98, }, /* 169 */ + { 106, 12, 3, 0, 0, 26684, 98, }, /* 170 */ + { 106, 12, 3, 0, 0, 26688, 98, }, /* 171 */ + { 106, 12, 3, 0, 0, 26692, 98, }, /* 172 */ + { 106, 12, 3, 0, 0, 26696, 98, }, /* 173 */ + { 106, 12, 3, 0, 0, 26700, 98, }, /* 174 */ + { 106, 12, 3, 0, 0, 26704, 98, }, /* 175 */ + { 106, 12, 3, 0, 0, 26624, 98, }, /* 176 */ + { 106, 12, 3, 0, 0, 26708, 98, }, /* 177 */ + { 106, 12, 3, 0, 0, 26712, 98, }, /* 178 */ + { 106, 12, 3, 0, 0, 26716, 98, }, /* 179 */ + { 106, 12, 3, 0, 0, 26720, 98, }, /* 180 */ + { 106, 12, 3, 0, 0, 26724, 98, }, /* 181 */ + { 106, 12, 3, 0, 0, 26728, 98, }, /* 182 */ + { 106, 12, 3, 0, 0, 26732, 98, }, /* 183 */ + { 106, 12, 3, 0, 0, 26736, 98, }, /* 184 */ + { 106, 12, 3, 0, 0, 26740, 98, }, /* 185 */ + { 106, 12, 3, 21, 116, 26740, 100, }, /* 186 */ + { 106, 12, 3, 0, 0, 26624, 102, }, /* 187 */ + { 106, 12, 3, 0, 0, 26744, 104, }, /* 188 */ + { 106, 12, 3, 0, 0, 26624, 104, }, /* 189 */ + { 106, 12, 3, 0, 0, 26748, 98, }, /* 190 */ + { 106, 12, 3, 0, 0, 26752, 106, }, /* 191 */ + { 1, 9, 12, 0, 1, 18432, 76, }, /* 192 */ + { 1, 5, 12, 0, -1, 18432, 78, }, /* 193 */ + { 99, 6, 12, 0, 0, 28804, 94, }, /* 194 */ + { 1, 24, 12, 0, 0, 28804, 56, }, /* 195 */ + { 98, 2, 12, 0, 0, 18432, 0, }, /* 196 */ + { 1, 6, 12, 0, 0, 18432, 108, }, /* 197 */ + { 1, 5, 12, 0, 130, 18432, 78, }, /* 198 */ + { 99, 21, 12, 0, 0, 28672, 110, }, /* 199 */ + { 1, 9, 12, 0, 116, 18432, 76, }, /* 200 */ + { 1, 24, 12, 0, 0, 28672, 56, }, /* 201 */ + { 1, 9, 12, 0, 38, 18432, 76, }, /* 202 */ + { 99, 21, 12, 0, 0, 28672, 112, }, /* 203 */ + { 1, 9, 12, 0, 37, 18432, 76, }, /* 204 */ + { 1, 9, 12, 0, 64, 18432, 76, }, /* 205 */ + { 1, 9, 12, 0, 63, 18432, 76, }, /* 206 */ + { 1, 5, 12, 0, 7235, 18432, 78, }, /* 207 */ + { 1, 9, 12, 0, 32, 18432, 76, }, /* 208 */ + { 1, 9, 12, 34, 32, 18432, 76, }, /* 209 */ + { 1, 9, 12, 59, 32, 18432, 76, }, /* 210 */ + { 1, 9, 12, 38, 32, 18432, 76, }, /* 211 */ + { 1, 9, 12, 21, 32, 18432, 76, }, /* 212 */ + { 1, 9, 12, 51, 32, 18432, 76, }, /* 213 */ + { 1, 9, 12, 26, 32, 18432, 76, }, /* 214 */ + { 1, 9, 12, 47, 32, 18432, 76, }, /* 215 */ + { 1, 9, 12, 55, 32, 18432, 76, }, /* 216 */ + { 1, 9, 12, 30, 32, 18432, 76, }, /* 217 */ + { 1, 9, 12, 43, 32, 18432, 76, }, /* 218 */ + { 1, 9, 12, 96, 32, 18432, 76, }, /* 219 */ + { 1, 5, 12, 0, -38, 18432, 78, }, /* 220 */ + { 1, 5, 12, 0, -37, 18432, 78, }, /* 221 */ + { 1, 5, 12, 0, 7219, 18432, 78, }, /* 222 */ + { 1, 5, 12, 0, -32, 18432, 78, }, /* 223 */ + { 1, 5, 12, 34, -32, 18432, 78, }, /* 224 */ + { 1, 5, 12, 59, -32, 18432, 78, }, /* 225 */ + { 1, 5, 12, 38, -32, 18432, 78, }, /* 226 */ + { 1, 5, 12, 21, -116, 18432, 78, }, /* 227 */ + { 1, 5, 12, 51, -32, 18432, 78, }, /* 228 */ + { 1, 5, 12, 26, -775, 18432, 78, }, /* 229 */ + { 1, 5, 12, 47, -32, 18432, 78, }, /* 230 */ + { 1, 5, 12, 55, -32, 18432, 78, }, /* 231 */ + { 1, 5, 12, 30, 1, 18432, 70, }, /* 232 */ + { 1, 5, 12, 30, -32, 18432, 78, }, /* 233 */ + { 1, 5, 12, 43, -32, 18432, 78, }, /* 234 */ + { 1, 5, 12, 96, -32, 18432, 78, }, /* 235 */ + { 1, 5, 12, 0, -64, 18432, 78, }, /* 236 */ + { 1, 5, 12, 0, -63, 18432, 78, }, /* 237 */ + { 1, 9, 12, 0, 8, 18432, 76, }, /* 238 */ + { 1, 5, 12, 34, -30, 18432, 114, }, /* 239 */ + { 1, 5, 12, 38, -25, 18432, 114, }, /* 240 */ + { 1, 9, 12, 0, 0, 18432, 116, }, /* 241 */ + { 1, 9, 12, 0, 0, 18432, 118, }, /* 242 */ + { 1, 5, 12, 43, -15, 18432, 114, }, /* 243 */ + { 1, 5, 12, 47, -22, 18432, 70, }, /* 244 */ + { 1, 5, 12, 0, -8, 18432, 78, }, /* 245 */ + { 43, 9, 12, 0, 1, 18432, 76, }, /* 246 */ + { 43, 5, 12, 0, -1, 18432, 78, }, /* 247 */ + { 1, 5, 12, 51, -54, 18432, 114, }, /* 248 */ + { 1, 5, 12, 55, -48, 18432, 114, }, /* 249 */ + { 1, 5, 12, 0, 7, 18432, 78, }, /* 250 */ + { 1, 5, 12, 0, -116, 18432, 80, }, /* 251 */ + { 1, 9, 12, 38, -60, 18432, 120, }, /* 252 */ + { 1, 5, 12, 59, -64, 18432, 114, }, /* 253 */ + { 1, 25, 12, 0, 0, 28672, 122, }, /* 254 */ + { 1, 9, 12, 0, -7, 18432, 76, }, /* 255 */ + { 1, 5, 12, 0, 0, 18432, 60, }, /* 256 */ + { 1, 9, 12, 0, -130, 18432, 76, }, /* 257 */ + { 2, 9, 12, 0, 80, 18432, 76, }, /* 258 */ + { 2, 9, 12, 0, 32, 18432, 76, }, /* 259 */ + { 2, 9, 12, 63, 32, 18432, 76, }, /* 260 */ + { 2, 9, 12, 67, 32, 18432, 76, }, /* 261 */ + { 2, 9, 12, 71, 32, 18432, 76, }, /* 262 */ + { 2, 9, 12, 75, 32, 18432, 76, }, /* 263 */ + { 2, 9, 12, 79, 32, 18432, 76, }, /* 264 */ + { 2, 9, 12, 84, 32, 18432, 76, }, /* 265 */ + { 2, 5, 12, 0, -32, 18432, 78, }, /* 266 */ + { 2, 5, 12, 63, -32, 18432, 78, }, /* 267 */ + { 2, 5, 12, 67, -32, 18432, 78, }, /* 268 */ + { 2, 5, 12, 71, -32, 18432, 78, }, /* 269 */ + { 2, 5, 12, 75, -32, 18432, 78, }, /* 270 */ + { 2, 5, 12, 79, -32, 18432, 78, }, /* 271 */ + { 2, 5, 12, 84, -32, 18432, 78, }, /* 272 */ + { 2, 5, 12, 0, -80, 18432, 78, }, /* 273 */ + { 2, 5, 12, 0, -80, 18432, 80, }, /* 274 */ + { 2, 9, 12, 0, 1, 18432, 76, }, /* 275 */ + { 2, 5, 12, 0, -1, 18432, 78, }, /* 276 */ + { 2, 9, 12, 88, 1, 18432, 76, }, /* 277 */ + { 2, 5, 12, 88, -1, 18432, 78, }, /* 278 */ + { 2, 26, 12, 0, 0, 18432, 74, }, /* 279 */ + { 2, 12, 3, 0, 0, 26760, 98, }, /* 280 */ + { 2, 12, 3, 0, 0, 26764, 98, }, /* 281 */ + { 106, 12, 3, 0, 0, 26768, 98, }, /* 282 */ + { 2, 11, 3, 0, 0, 26624, 124, }, /* 283 */ + { 2, 9, 12, 0, 15, 18432, 76, }, /* 284 */ + { 2, 5, 12, 0, -15, 18432, 78, }, /* 285 */ + { 3, 9, 12, 0, 48, 18432, 76, }, /* 286 */ + { 3, 6, 12, 0, 0, 18432, 94, }, /* 287 */ + { 3, 21, 12, 0, 0, 18432, 74, }, /* 288 */ + { 3, 21, 12, 0, 0, 18432, 126, }, /* 289 */ + { 3, 5, 12, 0, 0, 18432, 60, }, /* 290 */ + { 3, 5, 12, 0, -48, 18432, 78, }, /* 291 */ + { 3, 5, 12, 0, 0, 18432, 70, }, /* 292 */ + { 3, 21, 12, 0, 0, 18580, 128, }, /* 293 */ + { 3, 17, 12, 0, 0, 28672, 130, }, /* 294 */ + { 3, 26, 12, 0, 0, 28672, 74, }, /* 295 */ + { 3, 23, 12, 0, 0, 14336, 74, }, /* 296 */ + { 98, 2, 12, 0, 0, 34816, 0, }, /* 297 */ + { 4, 12, 3, 0, 0, 26624, 98, }, /* 298 */ + { 4, 12, 3, 0, 0, 26624, 104, }, /* 299 */ + { 4, 12, 3, 0, 0, 26624, 132, }, /* 300 */ + { 4, 17, 12, 0, 0, 34816, 130, }, /* 301 */ + { 4, 21, 12, 0, 0, 34816, 74, }, /* 302 */ + { 4, 21, 12, 0, 0, 34816, 110, }, /* 303 */ + { 4, 12, 3, 0, 0, 26624, 106, }, /* 304 */ + { 4, 7, 12, 0, 0, 34816, 84, }, /* 305 */ + { 4, 21, 12, 0, 0, 34816, 126, }, /* 306 */ + { 5, 1, 4, 0, 0, 2048, 134, }, /* 307 */ + { 99, 1, 4, 0, 0, 2048, 134, }, /* 308 */ + { 5, 25, 12, 0, 0, 28672, 122, }, /* 309 */ + { 5, 25, 12, 0, 0, 0, 122, }, /* 310 */ + { 5, 21, 12, 0, 0, 14336, 74, }, /* 311 */ + { 5, 23, 12, 0, 0, 0, 74, }, /* 312 */ + { 99, 21, 12, 0, 0, 8344, 110, }, /* 313 */ + { 5, 21, 12, 0, 0, 0, 74, }, /* 314 */ + { 5, 26, 12, 0, 0, 28672, 74, }, /* 315 */ + { 5, 12, 3, 0, 0, 26624, 106, }, /* 316 */ + { 99, 21, 12, 0, 0, 152, 110, }, /* 317 */ + { 5, 1, 2, 0, 0, 156, 136, }, /* 318 */ + { 5, 21, 12, 0, 0, 0, 128, }, /* 319 */ + { 99, 21, 12, 0, 0, 160, 128, }, /* 320 */ + { 5, 7, 12, 0, 0, 0, 84, }, /* 321 */ + { 99, 6, 12, 0, 0, 164, 138, }, /* 322 */ + { 106, 12, 3, 0, 0, 26792, 132, }, /* 323 */ + { 106, 12, 3, 0, 0, 26792, 106, }, /* 324 */ + { 106, 12, 3, 0, 0, 26792, 140, }, /* 325 */ + { 5, 12, 3, 0, 0, 26624, 132, }, /* 326 */ + { 5, 12, 3, 0, 0, 26624, 142, }, /* 327 */ + { 5, 13, 12, 0, 0, 2220, 144, }, /* 328 */ + { 5, 21, 12, 0, 0, 2048, 74, }, /* 329 */ + { 5, 7, 12, 0, 0, 0, 146, }, /* 330 */ + { 5, 21, 12, 0, 0, 176, 128, }, /* 331 */ + { 5, 12, 3, 0, 0, 26624, 140, }, /* 332 */ + { 5, 12, 3, 0, 0, 26624, 98, }, /* 333 */ + { 5, 6, 12, 0, 0, 0, 94, }, /* 334 */ + { 5, 13, 12, 0, 0, 10240, 144, }, /* 335 */ + { 5, 26, 12, 0, 0, 0, 74, }, /* 336 */ + { 6, 21, 12, 0, 0, 0, 128, }, /* 337 */ + { 6, 21, 12, 0, 0, 0, 110, }, /* 338 */ + { 6, 21, 12, 0, 0, 0, 74, }, /* 339 */ + { 98, 2, 12, 0, 0, 0, 0, }, /* 340 */ + { 6, 1, 4, 0, 0, 0, 134, }, /* 341 */ + { 6, 7, 12, 0, 0, 0, 84, }, /* 342 */ + { 6, 12, 3, 0, 0, 26624, 106, }, /* 343 */ + { 6, 12, 3, 0, 0, 26624, 132, }, /* 344 */ + { 6, 12, 3, 0, 0, 26624, 98, }, /* 345 */ + { 7, 7, 12, 0, 0, 0, 84, }, /* 346 */ + { 7, 12, 3, 0, 0, 26624, 132, }, /* 347 */ + { 48, 13, 12, 0, 0, 34816, 144, }, /* 348 */ + { 48, 7, 12, 0, 0, 34816, 84, }, /* 349 */ + { 48, 12, 3, 0, 0, 26624, 98, }, /* 350 */ + { 48, 6, 12, 0, 0, 34816, 94, }, /* 351 */ + { 48, 26, 12, 0, 0, 28672, 74, }, /* 352 */ + { 48, 21, 12, 0, 0, 28672, 74, }, /* 353 */ + { 48, 21, 12, 0, 0, 28672, 110, }, /* 354 */ + { 48, 21, 12, 0, 0, 28672, 128, }, /* 355 */ + { 48, 6, 12, 0, 0, 34816, 138, }, /* 356 */ + { 48, 12, 3, 0, 0, 26624, 104, }, /* 357 */ + { 48, 23, 12, 0, 0, 34816, 74, }, /* 358 */ + { 54, 7, 12, 0, 0, 34816, 84, }, /* 359 */ + { 54, 12, 3, 0, 0, 26624, 106, }, /* 360 */ + { 54, 12, 3, 0, 0, 26624, 98, }, /* 361 */ + { 54, 6, 12, 0, 0, 34816, 148, }, /* 362 */ + { 54, 12, 3, 0, 0, 26624, 104, }, /* 363 */ + { 54, 21, 12, 0, 0, 34816, 110, }, /* 364 */ + { 54, 21, 12, 0, 0, 34816, 74, }, /* 365 */ + { 54, 21, 12, 0, 0, 34816, 128, }, /* 366 */ + { 59, 7, 12, 0, 0, 34816, 84, }, /* 367 */ + { 59, 12, 3, 0, 0, 26624, 104, }, /* 368 */ + { 59, 21, 12, 0, 0, 34816, 110, }, /* 369 */ + { 5, 24, 12, 0, 0, 0, 126, }, /* 370 */ + { 5, 12, 3, 0, 0, 26624, 150, }, /* 371 */ + { 5, 12, 3, 0, 0, 26624, 104, }, /* 372 */ + { 5, 12, 3, 0, 0, 26624, 152, }, /* 373 */ + { 8, 12, 3, 0, 0, 26624, 106, }, /* 374 */ + { 8, 10, 5, 0, 0, 18432, 154, }, /* 375 */ + { 8, 7, 12, 0, 0, 18432, 84, }, /* 376 */ + { 8, 7, 12, 0, 0, 18432, 156, }, /* 377 */ + { 8, 12, 3, 0, 0, 26624, 98, }, /* 378 */ + { 8, 12, 3, 0, 0, 26624, 158, }, /* 379 */ + { 106, 12, 3, 0, 0, 26804, 98, }, /* 380 */ + { 106, 12, 3, 0, 0, 26808, 98, }, /* 381 */ + { 99, 21, 12, 0, 0, 18620, 128, }, /* 382 */ + { 99, 21, 12, 0, 0, 18624, 128, }, /* 383 */ + { 8, 13, 12, 0, 0, 18628, 144, }, /* 384 */ + { 8, 21, 12, 0, 0, 18432, 74, }, /* 385 */ + { 8, 6, 12, 0, 0, 18432, 94, }, /* 386 */ + { 9, 7, 12, 0, 0, 18432, 84, }, /* 387 */ + { 9, 12, 3, 0, 0, 26624, 106, }, /* 388 */ + { 9, 10, 5, 0, 0, 18432, 154, }, /* 389 */ + { 9, 7, 12, 0, 0, 18432, 156, }, /* 390 */ + { 9, 12, 3, 0, 0, 26624, 98, }, /* 391 */ + { 9, 10, 3, 0, 0, 18432, 160, }, /* 392 */ + { 9, 12, 3, 0, 0, 26624, 158, }, /* 393 */ + { 9, 13, 12, 0, 0, 18632, 144, }, /* 394 */ + { 9, 23, 12, 0, 0, 14336, 74, }, /* 395 */ + { 9, 15, 12, 0, 0, 18432, 74, }, /* 396 */ + { 9, 26, 12, 0, 0, 18432, 74, }, /* 397 */ + { 9, 21, 12, 0, 0, 18432, 74, }, /* 398 */ + { 9, 12, 3, 0, 0, 26624, 104, }, /* 399 */ + { 10, 12, 3, 0, 0, 26624, 106, }, /* 400 */ + { 10, 10, 5, 0, 0, 18432, 154, }, /* 401 */ + { 10, 7, 12, 0, 0, 18432, 84, }, /* 402 */ + { 10, 12, 3, 0, 0, 26624, 98, }, /* 403 */ + { 10, 12, 3, 0, 0, 26624, 158, }, /* 404 */ + { 10, 13, 12, 0, 0, 18636, 144, }, /* 405 */ + { 10, 12, 3, 0, 0, 26624, 162, }, /* 406 */ + { 10, 21, 12, 0, 0, 18432, 74, }, /* 407 */ + { 11, 12, 3, 0, 0, 26624, 106, }, /* 408 */ + { 11, 10, 5, 0, 0, 18432, 154, }, /* 409 */ + { 11, 7, 12, 0, 0, 18432, 84, }, /* 410 */ + { 11, 7, 12, 0, 0, 18432, 156, }, /* 411 */ + { 11, 12, 3, 0, 0, 26624, 98, }, /* 412 */ + { 11, 12, 3, 0, 0, 26624, 158, }, /* 413 */ + { 11, 13, 12, 0, 0, 18640, 144, }, /* 414 */ + { 11, 21, 12, 0, 0, 18432, 74, }, /* 415 */ + { 11, 23, 12, 0, 0, 14336, 74, }, /* 416 */ + { 11, 12, 3, 0, 0, 26624, 162, }, /* 417 */ + { 12, 12, 3, 0, 0, 26624, 106, }, /* 418 */ + { 12, 10, 5, 0, 0, 18432, 154, }, /* 419 */ + { 12, 7, 12, 0, 0, 18432, 84, }, /* 420 */ + { 12, 7, 12, 0, 0, 18432, 156, }, /* 421 */ + { 12, 12, 3, 0, 0, 26624, 98, }, /* 422 */ + { 12, 10, 3, 0, 0, 18432, 160, }, /* 423 */ + { 12, 12, 3, 0, 0, 26624, 158, }, /* 424 */ + { 12, 12, 3, 0, 0, 26624, 164, }, /* 425 */ + { 12, 13, 12, 0, 0, 18432, 144, }, /* 426 */ + { 12, 26, 12, 0, 0, 18432, 74, }, /* 427 */ + { 12, 15, 12, 0, 0, 18432, 74, }, /* 428 */ + { 13, 12, 3, 0, 0, 26624, 106, }, /* 429 */ + { 13, 7, 12, 0, 0, 18432, 84, }, /* 430 */ + { 13, 10, 3, 0, 0, 18432, 160, }, /* 431 */ + { 13, 10, 5, 0, 0, 18432, 154, }, /* 432 */ + { 13, 12, 3, 0, 0, 26624, 158, }, /* 433 */ + { 13, 13, 12, 0, 0, 18644, 144, }, /* 434 */ + { 13, 15, 12, 0, 0, 18644, 74, }, /* 435 */ + { 13, 26, 12, 0, 0, 28884, 74, }, /* 436 */ + { 13, 26, 12, 0, 0, 28672, 74, }, /* 437 */ + { 13, 23, 12, 0, 0, 14336, 74, }, /* 438 */ + { 14, 12, 3, 0, 0, 26624, 106, }, /* 439 */ + { 14, 10, 5, 0, 0, 18432, 154, }, /* 440 */ + { 14, 7, 12, 0, 0, 18432, 84, }, /* 441 */ + { 14, 7, 12, 0, 0, 18432, 156, }, /* 442 */ + { 14, 12, 3, 0, 0, 26624, 98, }, /* 443 */ + { 14, 12, 3, 0, 0, 26624, 158, }, /* 444 */ + { 14, 13, 12, 0, 0, 18432, 144, }, /* 445 */ + { 14, 21, 12, 0, 0, 18432, 74, }, /* 446 */ + { 14, 15, 12, 0, 0, 28672, 74, }, /* 447 */ + { 14, 26, 12, 0, 0, 18432, 74, }, /* 448 */ + { 15, 7, 12, 0, 0, 18432, 84, }, /* 449 */ + { 15, 12, 3, 0, 0, 26624, 106, }, /* 450 */ + { 15, 10, 5, 0, 0, 18432, 154, }, /* 451 */ + { 15, 21, 12, 0, 0, 18432, 74, }, /* 452 */ + { 15, 12, 3, 0, 0, 26624, 98, }, /* 453 */ + { 15, 12, 3, 0, 0, 18432, 106, }, /* 454 */ + { 15, 10, 3, 0, 0, 18432, 160, }, /* 455 */ + { 15, 12, 3, 0, 0, 26624, 158, }, /* 456 */ + { 15, 13, 12, 0, 0, 18648, 144, }, /* 457 */ + { 16, 12, 3, 0, 0, 26624, 106, }, /* 458 */ + { 16, 10, 5, 0, 0, 18432, 154, }, /* 459 */ + { 16, 7, 12, 0, 0, 18432, 84, }, /* 460 */ + { 16, 7, 12, 0, 0, 18432, 156, }, /* 461 */ + { 16, 12, 3, 0, 0, 26624, 158, }, /* 462 */ + { 16, 10, 3, 0, 0, 18432, 160, }, /* 463 */ + { 16, 7, 4, 0, 0, 18432, 84, }, /* 464 */ + { 16, 26, 12, 0, 0, 18432, 74, }, /* 465 */ + { 16, 15, 12, 0, 0, 18432, 74, }, /* 466 */ + { 16, 13, 12, 0, 0, 18432, 144, }, /* 467 */ + { 17, 12, 3, 0, 0, 26624, 106, }, /* 468 */ + { 17, 10, 5, 0, 0, 18432, 154, }, /* 469 */ + { 17, 7, 12, 0, 0, 18432, 84, }, /* 470 */ + { 17, 12, 3, 0, 0, 26624, 158, }, /* 471 */ + { 17, 10, 3, 0, 0, 18432, 160, }, /* 472 */ + { 17, 13, 12, 0, 0, 18432, 144, }, /* 473 */ + { 17, 21, 12, 0, 0, 18432, 74, }, /* 474 */ + { 18, 7, 12, 0, 0, 18432, 84, }, /* 475 */ + { 18, 12, 3, 0, 0, 26624, 106, }, /* 476 */ + { 18, 7, 5, 0, 0, 18432, 166, }, /* 477 */ + { 18, 12, 3, 0, 0, 26624, 168, }, /* 478 */ + { 99, 23, 12, 0, 0, 14336, 74, }, /* 479 */ + { 18, 7, 12, 0, 0, 18432, 170, }, /* 480 */ + { 18, 6, 12, 0, 0, 18432, 138, }, /* 481 */ + { 18, 12, 3, 0, 0, 26624, 98, }, /* 482 */ + { 18, 21, 12, 0, 0, 18432, 74, }, /* 483 */ + { 18, 13, 12, 0, 0, 18432, 144, }, /* 484 */ + { 18, 21, 12, 0, 0, 18432, 110, }, /* 485 */ + { 100, 7, 12, 0, 0, 18432, 84, }, /* 486 */ + { 100, 12, 3, 0, 0, 26624, 106, }, /* 487 */ + { 100, 7, 5, 0, 0, 18432, 166, }, /* 488 */ + { 100, 12, 3, 0, 0, 26624, 158, }, /* 489 */ + { 100, 7, 12, 0, 0, 18432, 170, }, /* 490 */ + { 100, 6, 12, 0, 0, 18432, 138, }, /* 491 */ + { 100, 12, 3, 0, 0, 26624, 98, }, /* 492 */ + { 100, 12, 3, 0, 0, 26624, 104, }, /* 493 */ + { 100, 13, 12, 0, 0, 18432, 144, }, /* 494 */ + { 19, 7, 12, 0, 0, 18432, 84, }, /* 495 */ + { 19, 26, 12, 0, 0, 18432, 74, }, /* 496 */ + { 19, 21, 12, 0, 0, 18432, 74, }, /* 497 */ + { 19, 21, 12, 0, 0, 18432, 110, }, /* 498 */ + { 19, 12, 3, 0, 0, 26624, 98, }, /* 499 */ + { 19, 13, 12, 0, 0, 18432, 144, }, /* 500 */ + { 19, 15, 12, 0, 0, 18432, 74, }, /* 501 */ + { 19, 22, 12, 0, 0, 28672, 172, }, /* 502 */ + { 19, 18, 12, 0, 0, 28672, 172, }, /* 503 */ + { 19, 10, 5, 0, 0, 18432, 174, }, /* 504 */ + { 19, 12, 3, 0, 0, 26624, 106, }, /* 505 */ + { 19, 12, 3, 0, 0, 26624, 176, }, /* 506 */ + { 19, 10, 5, 0, 0, 18432, 154, }, /* 507 */ + { 19, 12, 3, 0, 0, 26624, 132, }, /* 508 */ + { 19, 12, 3, 0, 0, 26624, 158, }, /* 509 */ + { 99, 26, 12, 0, 0, 18432, 74, }, /* 510 */ + { 20, 7, 12, 0, 0, 18432, 84, }, /* 511 */ + { 20, 10, 12, 0, 0, 18432, 154, }, /* 512 */ + { 20, 12, 3, 0, 0, 26624, 106, }, /* 513 */ + { 20, 10, 5, 0, 0, 18432, 154, }, /* 514 */ + { 20, 12, 3, 0, 0, 26624, 98, }, /* 515 */ + { 20, 12, 3, 0, 0, 26624, 158, }, /* 516 */ + { 20, 13, 12, 0, 0, 18652, 144, }, /* 517 */ + { 20, 21, 12, 0, 0, 18432, 128, }, /* 518 */ + { 20, 21, 12, 0, 0, 18432, 74, }, /* 519 */ + { 20, 10, 12, 0, 0, 18432, 178, }, /* 520 */ + { 20, 12, 3, 0, 0, 26624, 132, }, /* 521 */ + { 20, 13, 12, 0, 0, 18432, 144, }, /* 522 */ + { 20, 26, 12, 0, 0, 18432, 74, }, /* 523 */ + { 21, 9, 12, 0, 7264, 18432, 76, }, /* 524 */ + { 21, 5, 12, 0, 3008, 18432, 180, }, /* 525 */ + { 99, 21, 12, 0, 0, 18656, 74, }, /* 526 */ + { 21, 6, 12, 0, 0, 18432, 182, }, /* 527 */ + { 22, 7, 6, 0, 0, 18432, 84, }, /* 528 */ + { 22, 7, 6, 0, 0, 18432, 184, }, /* 529 */ + { 22, 7, 7, 0, 0, 18432, 184, }, /* 530 */ + { 22, 7, 7, 0, 0, 18432, 84, }, /* 531 */ + { 22, 7, 8, 0, 0, 18432, 84, }, /* 532 */ + { 23, 7, 12, 0, 0, 18432, 84, }, /* 533 */ + { 23, 12, 3, 0, 0, 26624, 98, }, /* 534 */ + { 23, 21, 12, 0, 0, 18432, 74, }, /* 535 */ + { 23, 21, 12, 0, 0, 18432, 110, }, /* 536 */ + { 23, 21, 12, 0, 0, 18432, 128, }, /* 537 */ + { 23, 15, 12, 0, 0, 18432, 144, }, /* 538 */ + { 23, 15, 12, 0, 0, 18432, 74, }, /* 539 */ + { 23, 26, 12, 0, 0, 28672, 74, }, /* 540 */ + { 24, 9, 12, 0, 38864, 18432, 186, }, /* 541 */ + { 24, 9, 12, 0, 8, 18432, 186, }, /* 542 */ + { 24, 5, 12, 0, -8, 18432, 70, }, /* 543 */ + { 101, 17, 12, 0, 0, 28672, 130, }, /* 544 */ + { 101, 7, 12, 0, 0, 18432, 84, }, /* 545 */ + { 101, 26, 12, 0, 0, 18432, 74, }, /* 546 */ + { 101, 21, 12, 0, 0, 18432, 128, }, /* 547 */ + { 102, 29, 12, 0, 0, 45056, 52, }, /* 548 */ + { 102, 7, 12, 0, 0, 18432, 84, }, /* 549 */ + { 102, 22, 12, 0, 0, 28672, 172, }, /* 550 */ + { 102, 18, 12, 0, 0, 28672, 172, }, /* 551 */ + { 25, 7, 12, 0, 0, 18432, 84, }, /* 552 */ + { 99, 21, 12, 0, 0, 18660, 110, }, /* 553 */ + { 25, 14, 12, 0, 0, 18432, 84, }, /* 554 */ + { 33, 7, 12, 0, 0, 18432, 84, }, /* 555 */ + { 33, 12, 3, 0, 0, 26624, 106, }, /* 556 */ + { 33, 12, 3, 0, 0, 26624, 158, }, /* 557 */ + { 33, 10, 3, 0, 0, 18432, 188, }, /* 558 */ + { 34, 7, 12, 0, 0, 18432, 84, }, /* 559 */ + { 34, 12, 3, 0, 0, 26624, 106, }, /* 560 */ + { 34, 10, 3, 0, 0, 18432, 188, }, /* 561 */ + { 99, 21, 12, 0, 0, 18664, 128, }, /* 562 */ + { 35, 7, 12, 0, 0, 18432, 84, }, /* 563 */ + { 35, 12, 3, 0, 0, 26624, 106, }, /* 564 */ + { 36, 7, 12, 0, 0, 18432, 84, }, /* 565 */ + { 36, 12, 3, 0, 0, 26624, 106, }, /* 566 */ + { 103, 7, 12, 0, 0, 18432, 84, }, /* 567 */ + { 103, 7, 12, 0, 0, 18432, 146, }, /* 568 */ + { 103, 12, 3, 0, 0, 26624, 102, }, /* 569 */ + { 103, 10, 5, 0, 0, 18432, 154, }, /* 570 */ + { 103, 12, 3, 0, 0, 26624, 106, }, /* 571 */ + { 103, 12, 3, 0, 0, 26624, 98, }, /* 572 */ + { 103, 12, 3, 0, 0, 26624, 158, }, /* 573 */ + { 103, 21, 12, 0, 0, 18432, 128, }, /* 574 */ + { 103, 21, 12, 0, 0, 18432, 110, }, /* 575 */ + { 103, 6, 12, 0, 0, 18432, 148, }, /* 576 */ + { 103, 21, 12, 0, 0, 18432, 74, }, /* 577 */ + { 103, 23, 12, 0, 0, 14336, 74, }, /* 578 */ + { 103, 13, 12, 0, 0, 18432, 144, }, /* 579 */ + { 103, 15, 12, 0, 0, 28672, 74, }, /* 580 */ + { 26, 21, 12, 0, 0, 28672, 74, }, /* 581 */ + { 99, 21, 12, 0, 0, 28908, 110, }, /* 582 */ + { 99, 21, 12, 0, 0, 28908, 128, }, /* 583 */ + { 26, 21, 12, 0, 0, 28672, 110, }, /* 584 */ + { 26, 17, 12, 0, 0, 28672, 130, }, /* 585 */ + { 26, 21, 12, 0, 0, 28672, 128, }, /* 586 */ + { 26, 21, 12, 0, 0, 28672, 190, }, /* 587 */ + { 26, 12, 3, 0, 0, 26624, 192, }, /* 588 */ + { 26, 1, 2, 0, 0, 6144, 66, }, /* 589 */ + { 26, 13, 12, 0, 0, 18432, 144, }, /* 590 */ + { 26, 7, 12, 0, 0, 18432, 84, }, /* 591 */ + { 26, 6, 12, 0, 0, 18432, 138, }, /* 592 */ + { 26, 12, 3, 0, 0, 26624, 194, }, /* 593 */ + { 26, 12, 3, 0, 0, 26624, 106, }, /* 594 */ + { 37, 7, 12, 0, 0, 18432, 84, }, /* 595 */ + { 37, 12, 3, 0, 0, 26624, 106, }, /* 596 */ + { 37, 10, 5, 0, 0, 18432, 154, }, /* 597 */ + { 37, 12, 3, 0, 0, 26624, 98, }, /* 598 */ + { 37, 26, 12, 0, 0, 28672, 74, }, /* 599 */ + { 37, 21, 12, 0, 0, 28672, 128, }, /* 600 */ + { 37, 13, 12, 0, 0, 18432, 144, }, /* 601 */ + { 38, 7, 12, 0, 0, 18432, 84, }, /* 602 */ + { 110, 7, 12, 0, 0, 18432, 84, }, /* 603 */ + { 110, 7, 12, 0, 0, 18432, 170, }, /* 604 */ + { 110, 13, 12, 0, 0, 18432, 144, }, /* 605 */ + { 110, 15, 12, 0, 0, 18432, 144, }, /* 606 */ + { 110, 26, 12, 0, 0, 28672, 74, }, /* 607 */ + { 103, 26, 12, 0, 0, 28672, 74, }, /* 608 */ + { 42, 7, 12, 0, 0, 18432, 84, }, /* 609 */ + { 42, 12, 3, 0, 0, 26624, 106, }, /* 610 */ + { 42, 10, 5, 0, 0, 18432, 154, }, /* 611 */ + { 42, 21, 12, 0, 0, 18432, 74, }, /* 612 */ + { 123, 7, 12, 0, 0, 18432, 84, }, /* 613 */ + { 123, 10, 5, 0, 0, 18432, 154, }, /* 614 */ + { 123, 12, 3, 0, 0, 26624, 106, }, /* 615 */ + { 123, 12, 3, 0, 0, 26624, 158, }, /* 616 */ + { 123, 10, 12, 0, 0, 18432, 154, }, /* 617 */ + { 123, 12, 3, 0, 0, 26624, 98, }, /* 618 */ + { 123, 13, 12, 0, 0, 18432, 144, }, /* 619 */ + { 123, 21, 12, 0, 0, 18432, 74, }, /* 620 */ + { 123, 6, 12, 0, 0, 18432, 138, }, /* 621 */ + { 123, 21, 12, 0, 0, 18432, 128, }, /* 622 */ + { 106, 11, 3, 0, 0, 26624, 196, }, /* 623 */ + { 106, 12, 3, 0, 0, 26624, 106, }, /* 624 */ + { 113, 12, 3, 0, 0, 26624, 106, }, /* 625 */ + { 113, 10, 5, 0, 0, 18432, 154, }, /* 626 */ + { 113, 7, 12, 0, 0, 18432, 84, }, /* 627 */ + { 113, 12, 3, 0, 0, 26624, 98, }, /* 628 */ + { 113, 10, 3, 0, 0, 18432, 160, }, /* 629 */ + { 113, 10, 3, 0, 0, 18432, 188, }, /* 630 */ + { 113, 21, 12, 0, 0, 18432, 128, }, /* 631 */ + { 113, 13, 12, 0, 0, 18432, 144, }, /* 632 */ + { 113, 21, 12, 0, 0, 18432, 74, }, /* 633 */ + { 113, 21, 12, 0, 0, 18432, 110, }, /* 634 */ + { 113, 26, 12, 0, 0, 18432, 74, }, /* 635 */ + { 116, 12, 3, 0, 0, 26624, 106, }, /* 636 */ + { 116, 10, 5, 0, 0, 18432, 154, }, /* 637 */ + { 116, 7, 12, 0, 0, 18432, 84, }, /* 638 */ + { 116, 10, 3, 0, 0, 18432, 188, }, /* 639 */ + { 116, 12, 3, 0, 0, 26624, 158, }, /* 640 */ + { 116, 13, 12, 0, 0, 18432, 144, }, /* 641 */ + { 132, 7, 12, 0, 0, 18432, 84, }, /* 642 */ + { 132, 12, 3, 0, 0, 26624, 98, }, /* 643 */ + { 132, 10, 5, 0, 0, 18432, 154, }, /* 644 */ + { 132, 12, 3, 0, 0, 26624, 106, }, /* 645 */ + { 132, 10, 3, 0, 0, 18432, 188, }, /* 646 */ + { 132, 21, 12, 0, 0, 18432, 74, }, /* 647 */ + { 117, 7, 12, 0, 0, 18432, 84, }, /* 648 */ + { 117, 10, 5, 0, 0, 18432, 154, }, /* 649 */ + { 117, 12, 3, 0, 0, 26624, 106, }, /* 650 */ + { 117, 12, 3, 0, 0, 26624, 198, }, /* 651 */ + { 117, 12, 3, 0, 0, 26624, 98, }, /* 652 */ + { 117, 21, 12, 0, 0, 18432, 128, }, /* 653 */ + { 117, 21, 12, 0, 0, 18432, 110, }, /* 654 */ + { 117, 13, 12, 0, 0, 18432, 144, }, /* 655 */ + { 118, 13, 12, 0, 0, 18432, 144, }, /* 656 */ + { 118, 7, 12, 0, 0, 18432, 84, }, /* 657 */ + { 118, 6, 12, 0, 0, 18432, 94, }, /* 658 */ + { 118, 6, 12, 0, 0, 18432, 96, }, /* 659 */ + { 118, 21, 12, 0, 0, 18432, 128, }, /* 660 */ + { 2, 5, 12, 63, -6222, 18432, 70, }, /* 661 */ + { 2, 5, 12, 67, -6221, 18432, 70, }, /* 662 */ + { 2, 5, 12, 71, -6212, 18432, 70, }, /* 663 */ + { 2, 5, 12, 75, -6210, 18432, 70, }, /* 664 */ + { 2, 5, 12, 79, -6210, 18432, 70, }, /* 665 */ + { 2, 5, 12, 79, -6211, 18432, 70, }, /* 666 */ + { 2, 5, 12, 84, -6204, 18432, 70, }, /* 667 */ + { 2, 5, 12, 88, -6180, 18432, 70, }, /* 668 */ + { 2, 5, 12, 108, 35267, 18432, 70, }, /* 669 */ + { 21, 9, 12, 0, -3008, 18432, 76, }, /* 670 */ + { 116, 21, 12, 0, 0, 18432, 74, }, /* 671 */ + { 106, 12, 3, 0, 0, 26864, 98, }, /* 672 */ + { 106, 12, 3, 0, 0, 26868, 98, }, /* 673 */ + { 99, 21, 12, 0, 0, 18680, 200, }, /* 674 */ + { 106, 12, 3, 0, 0, 26876, 98, }, /* 675 */ + { 106, 12, 3, 0, 0, 26880, 98, }, /* 676 */ + { 106, 12, 3, 0, 0, 26884, 98, }, /* 677 */ + { 99, 10, 5, 0, 0, 18684, 174, }, /* 678 */ + { 99, 7, 12, 0, 0, 18696, 84, }, /* 679 */ + { 99, 7, 12, 0, 0, 18684, 84, }, /* 680 */ + { 99, 7, 12, 0, 0, 18676, 84, }, /* 681 */ + { 99, 7, 12, 0, 0, 18700, 84, }, /* 682 */ + { 99, 7, 12, 0, 0, 18704, 84, }, /* 683 */ + { 106, 12, 3, 0, 0, 26900, 98, }, /* 684 */ + { 99, 10, 5, 0, 0, 18712, 174, }, /* 685 */ + { 106, 12, 3, 0, 0, 26896, 98, }, /* 686 */ + { 99, 7, 12, 0, 0, 18716, 84, }, /* 687 */ + { 2, 5, 12, 0, 0, 18432, 60, }, /* 688 */ + { 1, 6, 12, 0, 0, 18432, 90, }, /* 689 */ + { 2, 6, 12, 0, 0, 18432, 182, }, /* 690 */ + { 0, 5, 12, 0, 35332, 18432, 78, }, /* 691 */ + { 0, 5, 12, 0, 3814, 18432, 78, }, /* 692 */ + { 0, 5, 12, 0, 35384, 18432, 78, }, /* 693 */ + { 0, 5, 12, 0, 0, 18432, 202, }, /* 694 */ + { 0, 6, 12, 0, 0, 18432, 182, }, /* 695 */ + { 0, 6, 12, 0, 0, 18432, 204, }, /* 696 */ + { 1, 6, 12, 0, 0, 18432, 182, }, /* 697 */ + { 106, 12, 3, 0, 0, 26740, 104, }, /* 698 */ + { 106, 12, 3, 0, 0, 26912, 98, }, /* 699 */ + { 106, 12, 3, 0, 0, 26916, 98, }, /* 700 */ + { 0, 9, 12, 92, 1, 18432, 76, }, /* 701 */ + { 0, 5, 12, 92, -1, 18432, 78, }, /* 702 */ + { 0, 5, 12, 0, 0, 18432, 70, }, /* 703 */ + { 0, 5, 12, 92, -58, 18432, 70, }, /* 704 */ + { 0, 9, 12, 0, -7615, 18432, 76, }, /* 705 */ + { 1, 5, 12, 0, 8, 18432, 78, }, /* 706 */ + { 1, 9, 12, 0, -8, 18432, 76, }, /* 707 */ + { 1, 5, 12, 0, 0, 18432, 78, }, /* 708 */ + { 1, 5, 12, 0, 74, 18432, 78, }, /* 709 */ + { 1, 5, 12, 0, 86, 18432, 78, }, /* 710 */ + { 1, 5, 12, 0, 100, 18432, 78, }, /* 711 */ + { 1, 5, 12, 0, 128, 18432, 78, }, /* 712 */ + { 1, 5, 12, 0, 112, 18432, 78, }, /* 713 */ + { 1, 5, 12, 0, 126, 18432, 78, }, /* 714 */ + { 1, 5, 12, 0, 8, 18432, 70, }, /* 715 */ + { 1, 8, 12, 0, -8, 18432, 88, }, /* 716 */ + { 1, 5, 12, 0, 0, 18432, 70, }, /* 717 */ + { 1, 5, 12, 0, 9, 18432, 70, }, /* 718 */ + { 1, 9, 12, 0, -74, 18432, 76, }, /* 719 */ + { 1, 8, 12, 0, -9, 18432, 88, }, /* 720 */ + { 1, 5, 12, 21, -7173, 18432, 78, }, /* 721 */ + { 1, 9, 12, 0, -86, 18432, 76, }, /* 722 */ + { 1, 5, 12, 0, -7235, 18432, 78, }, /* 723 */ + { 1, 9, 12, 0, -100, 18432, 76, }, /* 724 */ + { 1, 5, 12, 0, -7219, 18432, 78, }, /* 725 */ + { 1, 9, 12, 0, -112, 18432, 76, }, /* 726 */ + { 1, 9, 12, 0, -128, 18432, 76, }, /* 727 */ + { 1, 9, 12, 0, -126, 18432, 76, }, /* 728 */ + { 99, 29, 12, 0, 0, 45056, 52, }, /* 729 */ + { 106, 1, 3, 0, 0, 6144, 206, }, /* 730 */ + { 106, 1, 13, 0, 0, 6144, 208, }, /* 731 */ + { 99, 1, 2, 0, 0, 18432, 210, }, /* 732 */ + { 99, 1, 2, 0, 0, 34816, 210, }, /* 733 */ + { 99, 17, 12, 0, 0, 28672, 212, }, /* 734 */ + { 99, 21, 12, 0, 0, 28672, 64, }, /* 735 */ + { 99, 20, 12, 0, 0, 28672, 214, }, /* 736 */ + { 99, 19, 12, 0, 0, 28672, 214, }, /* 737 */ + { 99, 22, 12, 0, 0, 28672, 216, }, /* 738 */ + { 99, 20, 12, 0, 0, 28672, 216, }, /* 739 */ + { 99, 19, 12, 0, 0, 28672, 216, }, /* 740 */ + { 99, 21, 12, 0, 0, 28672, 218, }, /* 741 */ + { 99, 21, 12, 0, 0, 28672, 220, }, /* 742 */ + { 99, 27, 2, 0, 0, 45056, 50, }, /* 743 */ + { 99, 28, 2, 0, 0, 4096, 50, }, /* 744 */ + { 99, 1, 2, 0, 0, 20480, 136, }, /* 745 */ + { 99, 1, 2, 0, 0, 36864, 136, }, /* 746 */ + { 99, 1, 2, 0, 0, 30720, 136, }, /* 747 */ + { 99, 1, 2, 0, 0, 24576, 136, }, /* 748 */ + { 99, 1, 2, 0, 0, 40960, 136, }, /* 749 */ + { 99, 29, 12, 0, 0, 8488, 52, }, /* 750 */ + { 99, 21, 12, 0, 0, 14336, 54, }, /* 751 */ + { 99, 21, 12, 0, 0, 14336, 64, }, /* 752 */ + { 99, 21, 14, 0, 0, 28672, 222, }, /* 753 */ + { 99, 21, 12, 0, 0, 28672, 224, }, /* 754 */ + { 99, 16, 12, 0, 0, 28672, 144, }, /* 755 */ + { 99, 16, 12, 0, 0, 28672, 226, }, /* 756 */ + { 99, 25, 12, 0, 0, 8192, 64, }, /* 757 */ + { 99, 22, 12, 0, 0, 28672, 228, }, /* 758 */ + { 99, 18, 12, 0, 0, 28672, 228, }, /* 759 */ + { 99, 21, 12, 0, 0, 28972, 54, }, /* 760 */ + { 99, 21, 12, 0, 0, 28672, 212, }, /* 761 */ + { 99, 21, 12, 0, 0, 28976, 54, }, /* 762 */ + { 99, 21, 12, 0, 0, 28980, 54, }, /* 763 */ + { 99, 1, 2, 0, 0, 6144, 230, }, /* 764 */ + { 98, 2, 2, 0, 0, 6144, 232, }, /* 765 */ + { 99, 1, 2, 0, 0, 22528, 136, }, /* 766 */ + { 99, 1, 2, 0, 0, 38912, 136, }, /* 767 */ + { 99, 1, 2, 0, 0, 16384, 136, }, /* 768 */ + { 99, 1, 2, 0, 0, 32768, 136, }, /* 769 */ + { 99, 1, 2, 0, 0, 6144, 234, }, /* 770 */ + { 99, 25, 12, 0, 0, 12288, 236, }, /* 771 */ + { 99, 25, 12, 0, 0, 12288, 238, }, /* 772 */ + { 99, 25, 12, 0, 0, 28672, 236, }, /* 773 */ + { 99, 22, 12, 0, 0, 28672, 240, }, /* 774 */ + { 99, 18, 12, 0, 0, 28672, 240, }, /* 775 */ + { 98, 2, 12, 0, 0, 14336, 0, }, /* 776 */ + { 106, 12, 3, 0, 0, 26624, 242, }, /* 777 */ + { 106, 11, 3, 0, 0, 26624, 124, }, /* 778 */ + { 106, 11, 3, 0, 0, 26624, 244, }, /* 779 */ + { 106, 12, 3, 0, 0, 26936, 104, }, /* 780 */ + { 99, 26, 12, 0, 0, 28672, 74, }, /* 781 */ + { 99, 9, 12, 0, 0, 18432, 116, }, /* 782 */ + { 99, 5, 12, 0, 0, 18432, 246, }, /* 783 */ + { 99, 25, 12, 0, 0, 28672, 248, }, /* 784 */ + { 99, 26, 14, 0, 0, 28672, 250, }, /* 785 */ + { 1, 9, 12, 96, -7517, 18432, 76, }, /* 786 */ + { 99, 26, 12, 0, 0, 28672, 122, }, /* 787 */ + { 0, 9, 12, 100, 0, 18432, 76, }, /* 788 */ + { 0, 9, 12, 104, -8262, 18432, 76, }, /* 789 */ + { 99, 26, 12, 0, 0, 14336, 252, }, /* 790 */ + { 0, 9, 12, 0, 28, 18432, 76, }, /* 791 */ + { 99, 7, 12, 0, 0, 18432, 254, }, /* 792 */ + { 99, 5, 14, 0, 0, 18432, 256, }, /* 793 */ + { 99, 25, 12, 0, 0, 28672, 122, }, /* 794 */ + { 99, 5, 12, 0, 0, 18432, 258, }, /* 795 */ + { 0, 5, 12, 0, -28, 18432, 78, }, /* 796 */ + { 0, 14, 12, 0, 16, 18432, 76, }, /* 797 */ + { 0, 14, 12, 0, -16, 18432, 78, }, /* 798 */ + { 0, 14, 12, 0, 0, 18432, 84, }, /* 799 */ + { 99, 25, 14, 0, 0, 28672, 260, }, /* 800 */ + { 99, 26, 14, 0, 0, 28672, 260, }, /* 801 */ + { 99, 26, 12, 0, 0, 28672, 64, }, /* 802 */ + { 99, 25, 12, 0, 0, 28672, 262, }, /* 803 */ + { 99, 25, 12, 0, 0, 28672, 264, }, /* 804 */ + { 99, 25, 12, 0, 0, 12288, 266, }, /* 805 */ + { 99, 22, 12, 0, 0, 28672, 264, }, /* 806 */ + { 99, 18, 12, 0, 0, 28672, 264, }, /* 807 */ + { 99, 26, 14, 0, 0, 28672, 268, }, /* 808 */ + { 99, 22, 12, 0, 0, 28672, 270, }, /* 809 */ + { 99, 18, 12, 0, 0, 28672, 270, }, /* 810 */ + { 99, 26, 12, 0, 0, 18432, 54, }, /* 811 */ + { 99, 26, 14, 0, 0, 28672, 272, }, /* 812 */ + { 98, 2, 12, 0, 0, 18432, 274, }, /* 813 */ + { 99, 15, 12, 0, 0, 10240, 74, }, /* 814 */ + { 99, 26, 12, 0, 26, 18432, 276, }, /* 815 */ + { 99, 26, 14, 0, 26, 18432, 278, }, /* 816 */ + { 99, 26, 12, 0, -26, 18432, 280, }, /* 817 */ + { 99, 25, 14, 0, 0, 28672, 282, }, /* 818 */ + { 99, 26, 14, 0, 0, 28672, 284, }, /* 819 */ + { 99, 26, 14, 0, 0, 28672, 286, }, /* 820 */ + { 99, 25, 14, 0, 0, 28672, 284, }, /* 821 */ + { 99, 26, 14, 0, 0, 18432, 272, }, /* 822 */ + { 99, 26, 14, 0, 0, 28672, 288, }, /* 823 */ + { 109, 26, 12, 0, 0, 18432, 54, }, /* 824 */ + { 99, 26, 12, 0, 0, 28672, 228, }, /* 825 */ + { 44, 9, 12, 0, 48, 18432, 76, }, /* 826 */ + { 44, 5, 12, 0, -48, 18432, 78, }, /* 827 */ + { 0, 9, 12, 0, -10743, 18432, 76, }, /* 828 */ + { 0, 9, 12, 0, -3814, 18432, 76, }, /* 829 */ + { 0, 9, 12, 0, -10727, 18432, 76, }, /* 830 */ + { 0, 5, 12, 0, -10795, 18432, 78, }, /* 831 */ + { 0, 5, 12, 0, -10792, 18432, 78, }, /* 832 */ + { 0, 9, 12, 0, -10780, 18432, 76, }, /* 833 */ + { 0, 9, 12, 0, -10749, 18432, 76, }, /* 834 */ + { 0, 9, 12, 0, -10783, 18432, 76, }, /* 835 */ + { 0, 9, 12, 0, -10782, 18432, 76, }, /* 836 */ + { 0, 9, 12, 0, -10815, 18432, 76, }, /* 837 */ + { 43, 5, 12, 0, 0, 18432, 60, }, /* 838 */ + { 43, 26, 12, 0, 0, 28672, 74, }, /* 839 */ + { 43, 12, 3, 0, 0, 26624, 98, }, /* 840 */ + { 43, 21, 12, 0, 0, 28672, 128, }, /* 841 */ + { 43, 21, 12, 0, 0, 28672, 74, }, /* 842 */ + { 43, 15, 12, 0, 0, 28672, 74, }, /* 843 */ + { 21, 5, 12, 0, -7264, 18432, 78, }, /* 844 */ + { 45, 7, 12, 0, 0, 18432, 84, }, /* 845 */ + { 45, 6, 12, 0, 0, 18432, 148, }, /* 846 */ + { 45, 21, 12, 0, 0, 18432, 74, }, /* 847 */ + { 45, 12, 3, 0, 0, 26624, 290, }, /* 848 */ + { 2, 12, 3, 0, 0, 26624, 106, }, /* 849 */ + { 99, 20, 12, 0, 0, 28672, 228, }, /* 850 */ + { 99, 19, 12, 0, 0, 28672, 228, }, /* 851 */ + { 99, 17, 12, 0, 0, 28988, 212, }, /* 852 */ + { 99, 6, 12, 0, 0, 28672, 292, }, /* 853 */ + { 99, 21, 12, 0, 0, 28992, 54, }, /* 854 */ + { 99, 21, 12, 0, 0, 28996, 54, }, /* 855 */ + { 99, 21, 12, 0, 0, 29000, 224, }, /* 856 */ + { 99, 21, 12, 0, 0, 29004, 294, }, /* 857 */ + { 99, 21, 12, 0, 0, 28812, 54, }, /* 858 */ + { 99, 21, 12, 0, 0, 28672, 294, }, /* 859 */ + { 30, 26, 12, 0, 0, 28672, 296, }, /* 860 */ + { 99, 26, 12, 0, 0, 29008, 298, }, /* 861 */ + { 99, 26, 12, 0, 0, 29008, 300, }, /* 862 */ + { 99, 26, 12, 0, 0, 29008, 302, }, /* 863 */ + { 99, 21, 12, 0, 0, 29012, 294, }, /* 864 */ + { 99, 21, 12, 0, 0, 29016, 224, }, /* 865 */ + { 99, 21, 12, 0, 0, 29020, 54, }, /* 866 */ + { 30, 6, 12, 0, 0, 18432, 138, }, /* 867 */ + { 99, 7, 12, 0, 0, 18784, 304, }, /* 868 */ + { 30, 14, 12, 0, 0, 18432, 304, }, /* 869 */ + { 99, 22, 12, 0, 0, 29028, 228, }, /* 870 */ + { 99, 18, 12, 0, 0, 29028, 228, }, /* 871 */ + { 99, 22, 12, 0, 0, 29032, 228, }, /* 872 */ + { 99, 18, 12, 0, 0, 29032, 228, }, /* 873 */ + { 99, 22, 12, 0, 0, 29036, 62, }, /* 874 */ + { 99, 18, 12, 0, 0, 29036, 62, }, /* 875 */ + { 99, 22, 12, 0, 0, 29036, 228, }, /* 876 */ + { 99, 18, 12, 0, 0, 29036, 228, }, /* 877 */ + { 99, 26, 12, 0, 0, 29020, 54, }, /* 878 */ + { 99, 17, 12, 0, 0, 29020, 212, }, /* 879 */ + { 99, 22, 12, 0, 0, 29020, 216, }, /* 880 */ + { 99, 18, 12, 0, 0, 29020, 216, }, /* 881 */ + { 106, 12, 3, 0, 0, 26992, 98, }, /* 882 */ + { 22, 10, 3, 0, 0, 18432, 306, }, /* 883 */ + { 99, 17, 14, 0, 0, 29020, 308, }, /* 884 */ + { 99, 6, 12, 0, 0, 18804, 138, }, /* 885 */ + { 99, 26, 12, 0, 0, 29020, 74, }, /* 886 */ + { 30, 6, 12, 0, 0, 18432, 148, }, /* 887 */ + { 99, 7, 12, 0, 0, 18808, 84, }, /* 888 */ + { 99, 21, 14, 0, 0, 29048, 250, }, /* 889 */ + { 99, 26, 12, 0, 0, 29024, 74, }, /* 890 */ + { 27, 7, 12, 0, 0, 18432, 84, }, /* 891 */ + { 106, 12, 3, 0, 0, 26996, 98, }, /* 892 */ + { 99, 24, 12, 0, 0, 29044, 310, }, /* 893 */ + { 27, 6, 12, 0, 0, 18432, 138, }, /* 894 */ + { 99, 17, 12, 0, 0, 29044, 130, }, /* 895 */ + { 28, 7, 12, 0, 0, 18432, 84, }, /* 896 */ + { 99, 21, 12, 0, 0, 29036, 144, }, /* 897 */ + { 99, 6, 12, 0, 0, 18804, 96, }, /* 898 */ + { 28, 6, 12, 0, 0, 18432, 138, }, /* 899 */ + { 29, 7, 12, 0, 0, 18432, 84, }, /* 900 */ + { 22, 7, 12, 0, 0, 18432, 84, }, /* 901 */ + { 22, 7, 12, 0, 0, 18432, 184, }, /* 902 */ + { 99, 26, 12, 0, 0, 18784, 74, }, /* 903 */ + { 99, 15, 12, 0, 0, 18784, 74, }, /* 904 */ + { 22, 26, 12, 0, 0, 18432, 74, }, /* 905 */ + { 22, 26, 12, 0, 0, 28672, 74, }, /* 906 */ + { 99, 15, 12, 0, 0, 18432, 74, }, /* 907 */ + { 99, 26, 14, 0, 0, 18784, 250, }, /* 908 */ + { 28, 26, 12, 0, 0, 18432, 74, }, /* 909 */ + { 30, 7, 12, 0, 0, 18432, 312, }, /* 910 */ + { 31, 7, 12, 0, 0, 18432, 84, }, /* 911 */ + { 31, 6, 12, 0, 0, 18432, 138, }, /* 912 */ + { 31, 26, 12, 0, 0, 28672, 74, }, /* 913 */ + { 55, 7, 12, 0, 0, 18432, 84, }, /* 914 */ + { 55, 6, 12, 0, 0, 18432, 148, }, /* 915 */ + { 55, 21, 12, 0, 0, 18432, 110, }, /* 916 */ + { 55, 21, 12, 0, 0, 18432, 128, }, /* 917 */ + { 119, 7, 12, 0, 0, 18432, 84, }, /* 918 */ + { 119, 6, 12, 0, 0, 18432, 138, }, /* 919 */ + { 119, 21, 12, 0, 0, 28672, 110, }, /* 920 */ + { 119, 21, 12, 0, 0, 28672, 128, }, /* 921 */ + { 119, 13, 12, 0, 0, 18432, 144, }, /* 922 */ + { 2, 9, 12, 108, 1, 18432, 76, }, /* 923 */ + { 2, 5, 12, 108, -35267, 18432, 78, }, /* 924 */ + { 2, 7, 12, 0, 0, 18432, 84, }, /* 925 */ + { 2, 21, 12, 0, 0, 28672, 74, }, /* 926 */ + { 2, 12, 3, 0, 0, 26624, 98, }, /* 927 */ + { 2, 6, 12, 0, 0, 28672, 94, }, /* 928 */ + { 2, 6, 12, 0, 0, 18432, 90, }, /* 929 */ + { 126, 7, 12, 0, 0, 18432, 84, }, /* 930 */ + { 126, 14, 12, 0, 0, 18432, 84, }, /* 931 */ + { 126, 12, 3, 0, 0, 26624, 98, }, /* 932 */ + { 126, 21, 12, 0, 0, 18432, 74, }, /* 933 */ + { 126, 21, 12, 0, 0, 18432, 128, }, /* 934 */ + { 126, 21, 12, 0, 0, 18432, 110, }, /* 935 */ + { 99, 24, 12, 0, 0, 29052, 56, }, /* 936 */ + { 0, 9, 12, 0, -35332, 18432, 76, }, /* 937 */ + { 99, 24, 12, 0, 0, 18432, 56, }, /* 938 */ + { 0, 9, 12, 0, -42280, 18432, 76, }, /* 939 */ + { 0, 5, 12, 0, 48, 18432, 78, }, /* 940 */ + { 0, 9, 12, 0, -42308, 18432, 76, }, /* 941 */ + { 0, 9, 12, 0, -42319, 18432, 76, }, /* 942 */ + { 0, 9, 12, 0, -42315, 18432, 76, }, /* 943 */ + { 0, 9, 12, 0, -42305, 18432, 76, }, /* 944 */ + { 0, 9, 12, 0, -42258, 18432, 76, }, /* 945 */ + { 0, 9, 12, 0, -42282, 18432, 76, }, /* 946 */ + { 0, 9, 12, 0, -42261, 18432, 76, }, /* 947 */ + { 0, 9, 12, 0, 928, 18432, 76, }, /* 948 */ + { 0, 9, 12, 0, -48, 18432, 76, }, /* 949 */ + { 0, 9, 12, 0, -42307, 18432, 76, }, /* 950 */ + { 0, 9, 12, 0, -35384, 18432, 76, }, /* 951 */ + { 0, 9, 12, 0, -42343, 18432, 76, }, /* 952 */ + { 0, 9, 12, 0, -42561, 18432, 76, }, /* 953 */ + { 46, 7, 12, 0, 0, 18432, 84, }, /* 954 */ + { 46, 12, 3, 0, 0, 26624, 106, }, /* 955 */ + { 46, 12, 3, 0, 0, 26624, 158, }, /* 956 */ + { 46, 10, 5, 0, 0, 18432, 154, }, /* 957 */ + { 46, 26, 12, 0, 0, 28672, 74, }, /* 958 */ + { 99, 15, 12, 0, 0, 18816, 74, }, /* 959 */ + { 99, 15, 12, 0, 0, 18820, 74, }, /* 960 */ + { 99, 26, 12, 0, 0, 18824, 74, }, /* 961 */ + { 99, 23, 12, 0, 0, 14732, 74, }, /* 962 */ + { 99, 26, 12, 0, 0, 14728, 74, }, /* 963 */ + { 47, 7, 12, 0, 0, 18432, 84, }, /* 964 */ + { 47, 21, 12, 0, 0, 28672, 74, }, /* 965 */ + { 47, 21, 12, 0, 0, 28672, 128, }, /* 966 */ + { 120, 10, 5, 0, 0, 18432, 154, }, /* 967 */ + { 120, 7, 12, 0, 0, 18432, 84, }, /* 968 */ + { 120, 12, 3, 0, 0, 26624, 158, }, /* 969 */ + { 120, 12, 3, 0, 0, 26624, 106, }, /* 970 */ + { 120, 21, 12, 0, 0, 18432, 128, }, /* 971 */ + { 120, 13, 12, 0, 0, 18432, 144, }, /* 972 */ + { 8, 12, 3, 0, 0, 27024, 98, }, /* 973 */ + { 8, 7, 12, 0, 0, 18836, 84, }, /* 974 */ + { 49, 13, 12, 0, 0, 18432, 144, }, /* 975 */ + { 49, 7, 12, 0, 0, 18432, 84, }, /* 976 */ + { 49, 12, 3, 0, 0, 26624, 106, }, /* 977 */ + { 49, 12, 3, 0, 0, 26624, 98, }, /* 978 */ + { 99, 21, 12, 0, 0, 18840, 200, }, /* 979 */ + { 49, 21, 12, 0, 0, 18432, 128, }, /* 980 */ + { 121, 7, 12, 0, 0, 18432, 84, }, /* 981 */ + { 121, 12, 3, 0, 0, 26624, 106, }, /* 982 */ + { 121, 10, 5, 0, 0, 18432, 154, }, /* 983 */ + { 121, 10, 3, 0, 0, 18432, 188, }, /* 984 */ + { 121, 21, 12, 0, 0, 18432, 74, }, /* 985 */ + { 56, 12, 3, 0, 0, 26624, 106, }, /* 986 */ + { 56, 10, 5, 0, 0, 18432, 154, }, /* 987 */ + { 56, 7, 12, 0, 0, 18432, 84, }, /* 988 */ + { 56, 12, 3, 0, 0, 26624, 98, }, /* 989 */ + { 56, 10, 3, 0, 0, 18432, 188, }, /* 990 */ + { 56, 21, 12, 0, 0, 18432, 74, }, /* 991 */ + { 56, 21, 12, 0, 0, 18432, 110, }, /* 992 */ + { 56, 21, 12, 0, 0, 18432, 128, }, /* 993 */ + { 99, 6, 12, 0, 0, 18844, 138, }, /* 994 */ + { 56, 13, 12, 0, 0, 18432, 144, }, /* 995 */ + { 20, 6, 12, 0, 0, 18432, 138, }, /* 996 */ + { 122, 7, 12, 0, 0, 18432, 84, }, /* 997 */ + { 122, 12, 3, 0, 0, 26624, 106, }, /* 998 */ + { 122, 10, 5, 0, 0, 18432, 154, }, /* 999 */ + { 122, 13, 12, 0, 0, 18432, 144, }, /* 1000 */ + { 122, 21, 12, 0, 0, 18432, 74, }, /* 1001 */ + { 122, 21, 12, 0, 0, 18432, 128, }, /* 1002 */ + { 124, 7, 12, 0, 0, 18432, 84, }, /* 1003 */ + { 124, 12, 3, 0, 0, 26624, 106, }, /* 1004 */ + { 124, 7, 12, 0, 0, 18432, 170, }, /* 1005 */ + { 124, 12, 3, 0, 0, 26624, 98, }, /* 1006 */ + { 124, 7, 12, 0, 0, 18432, 314, }, /* 1007 */ + { 124, 6, 12, 0, 0, 18432, 138, }, /* 1008 */ + { 124, 21, 12, 0, 0, 18432, 74, }, /* 1009 */ + { 124, 21, 12, 0, 0, 18432, 110, }, /* 1010 */ + { 127, 7, 12, 0, 0, 18432, 84, }, /* 1011 */ + { 127, 10, 5, 0, 0, 18432, 154, }, /* 1012 */ + { 127, 12, 3, 0, 0, 26624, 106, }, /* 1013 */ + { 127, 21, 12, 0, 0, 18432, 128, }, /* 1014 */ + { 127, 6, 12, 0, 0, 18432, 138, }, /* 1015 */ + { 127, 12, 3, 0, 0, 26624, 158, }, /* 1016 */ + { 0, 5, 12, 0, -928, 18432, 78, }, /* 1017 */ + { 24, 5, 12, 0, -38864, 18432, 70, }, /* 1018 */ + { 127, 10, 5, 0, 0, 18432, 174, }, /* 1019 */ + { 127, 13, 12, 0, 0, 18432, 144, }, /* 1020 */ + { 22, 7, 9, 0, 0, 18432, 84, }, /* 1021 */ + { 22, 7, 10, 0, 0, 18432, 84, }, /* 1022 */ + { 98, 4, 12, 0, 0, 18432, 0, }, /* 1023 */ + { 98, 3, 12, 0, 0, 18432, 0, }, /* 1024 */ + { 30, 7, 12, 0, 0, 18432, 304, }, /* 1025 */ + { 0, 5, 12, 0, 1, 18432, 70, }, /* 1026 */ + { 0, 5, 12, 0, -1, 18432, 70, }, /* 1027 */ + { 4, 25, 12, 0, 0, 12288, 122, }, /* 1028 */ + { 5, 7, 12, 0, 0, 0, 316, }, /* 1029 */ + { 99, 18, 12, 0, 0, 29088, 54, }, /* 1030 */ + { 99, 22, 12, 0, 0, 29088, 54, }, /* 1031 */ + { 98, 2, 12, 0, 0, 6144, 318, }, /* 1032 */ + { 5, 7, 12, 0, 0, 420, 84, }, /* 1033 */ + { 5, 26, 12, 0, 0, 29092, 74, }, /* 1034 */ + { 106, 12, 3, 0, 0, 26624, 192, }, /* 1035 */ + { 106, 12, 3, 0, 0, 26624, 320, }, /* 1036 */ + { 99, 21, 12, 0, 0, 28672, 74, }, /* 1037 */ + { 99, 21, 12, 0, 0, 28672, 128, }, /* 1038 */ + { 99, 21, 12, 0, 0, 28672, 126, }, /* 1039 */ + { 99, 22, 12, 0, 0, 28672, 74, }, /* 1040 */ + { 99, 18, 12, 0, 0, 28672, 74, }, /* 1041 */ + { 99, 17, 12, 0, 0, 28672, 130, }, /* 1042 */ + { 99, 22, 12, 0, 0, 28672, 322, }, /* 1043 */ + { 99, 18, 12, 0, 0, 28672, 322, }, /* 1044 */ + { 99, 21, 12, 0, 0, 8192, 110, }, /* 1045 */ + { 99, 21, 12, 0, 0, 8192, 324, }, /* 1046 */ + { 99, 21, 12, 0, 0, 8192, 326, }, /* 1047 */ + { 99, 22, 12, 0, 0, 28672, 172, }, /* 1048 */ + { 99, 18, 12, 0, 0, 28672, 172, }, /* 1049 */ + { 99, 21, 12, 0, 0, 14336, 74, }, /* 1050 */ + { 99, 21, 12, 0, 0, 28672, 122, }, /* 1051 */ + { 99, 25, 12, 0, 0, 12288, 122, }, /* 1052 */ + { 99, 17, 12, 0, 0, 12288, 328, }, /* 1053 */ + { 99, 25, 12, 0, 0, 28672, 330, }, /* 1054 */ + { 99, 21, 12, 0, 0, 28672, 322, }, /* 1055 */ + { 99, 21, 12, 0, 0, 28672, 332, }, /* 1056 */ + { 99, 17, 12, 0, 0, 12288, 130, }, /* 1057 */ + { 99, 21, 12, 0, 0, 8192, 74, }, /* 1058 */ + { 99, 13, 12, 0, 0, 10240, 334, }, /* 1059 */ + { 0, 9, 12, 0, 32, 18432, 336, }, /* 1060 */ + { 99, 24, 12, 0, 0, 28672, 338, }, /* 1061 */ + { 0, 5, 12, 0, -32, 18432, 340, }, /* 1062 */ + { 99, 21, 12, 0, 0, 29036, 128, }, /* 1063 */ + { 99, 22, 12, 0, 0, 29036, 342, }, /* 1064 */ + { 99, 18, 12, 0, 0, 29036, 342, }, /* 1065 */ + { 99, 21, 12, 0, 0, 29036, 110, }, /* 1066 */ + { 99, 6, 3, 0, 0, 18804, 344, }, /* 1067 */ + { 99, 1, 2, 0, 0, 28672, 346, }, /* 1068 */ + { 39, 7, 12, 0, 0, 18432, 84, }, /* 1069 */ + { 99, 21, 12, 0, 0, 18856, 74, }, /* 1070 */ + { 99, 21, 12, 0, 0, 29096, 74, }, /* 1071 */ + { 99, 21, 12, 0, 0, 18860, 74, }, /* 1072 */ + { 99, 15, 12, 0, 0, 18864, 74, }, /* 1073 */ + { 99, 26, 12, 0, 0, 18860, 74, }, /* 1074 */ + { 1, 14, 12, 0, 0, 28672, 84, }, /* 1075 */ + { 1, 15, 12, 0, 0, 28672, 74, }, /* 1076 */ + { 1, 26, 12, 0, 0, 28672, 74, }, /* 1077 */ + { 1, 26, 12, 0, 0, 18432, 74, }, /* 1078 */ + { 50, 7, 12, 0, 0, 18432, 84, }, /* 1079 */ + { 51, 7, 12, 0, 0, 18432, 84, }, /* 1080 */ + { 106, 12, 3, 0, 0, 27060, 98, }, /* 1081 */ + { 99, 15, 12, 0, 0, 10676, 74, }, /* 1082 */ + { 104, 7, 12, 0, 0, 18432, 84, }, /* 1083 */ + { 104, 15, 12, 0, 0, 18432, 74, }, /* 1084 */ + { 32, 7, 12, 0, 0, 18432, 84, }, /* 1085 */ + { 32, 14, 12, 0, 0, 18432, 84, }, /* 1086 */ + { 73, 7, 12, 0, 0, 18432, 84, }, /* 1087 */ + { 73, 12, 3, 0, 0, 26624, 106, }, /* 1088 */ + { 107, 7, 12, 0, 0, 18432, 84, }, /* 1089 */ + { 107, 21, 12, 0, 0, 18432, 110, }, /* 1090 */ + { 111, 7, 12, 0, 0, 18432, 84, }, /* 1091 */ + { 111, 21, 12, 0, 0, 18432, 110, }, /* 1092 */ + { 111, 14, 12, 0, 0, 18432, 84, }, /* 1093 */ + { 105, 9, 12, 0, 40, 18432, 76, }, /* 1094 */ + { 105, 5, 12, 0, -40, 18432, 78, }, /* 1095 */ + { 40, 7, 12, 0, 0, 18432, 84, }, /* 1096 */ + { 108, 7, 12, 0, 0, 18432, 84, }, /* 1097 */ + { 108, 13, 12, 0, 0, 18432, 144, }, /* 1098 */ + { 80, 9, 12, 0, 40, 18432, 76, }, /* 1099 */ + { 80, 5, 12, 0, -40, 18432, 78, }, /* 1100 */ + { 66, 7, 12, 0, 0, 18432, 84, }, /* 1101 */ + { 64, 7, 12, 0, 0, 18432, 84, }, /* 1102 */ + { 64, 21, 12, 0, 0, 18432, 74, }, /* 1103 */ + { 167, 9, 12, 0, 39, 18432, 76, }, /* 1104 */ + { 167, 5, 12, 0, -39, 18432, 78, }, /* 1105 */ + { 96, 7, 12, 0, 0, 18432, 84, }, /* 1106 */ + { 69, 7, 12, 0, 0, 18432, 84, }, /* 1107 */ + { 0, 6, 12, 0, 0, 18432, 96, }, /* 1108 */ + { 41, 7, 12, 0, 0, 34816, 84, }, /* 1109 */ + { 128, 7, 12, 0, 0, 34816, 84, }, /* 1110 */ + { 128, 21, 12, 0, 0, 34816, 110, }, /* 1111 */ + { 128, 15, 12, 0, 0, 34816, 74, }, /* 1112 */ + { 143, 7, 12, 0, 0, 34816, 84, }, /* 1113 */ + { 143, 26, 12, 0, 0, 34816, 74, }, /* 1114 */ + { 143, 15, 12, 0, 0, 34816, 74, }, /* 1115 */ + { 142, 7, 12, 0, 0, 34816, 84, }, /* 1116 */ + { 142, 15, 12, 0, 0, 34816, 74, }, /* 1117 */ + { 149, 7, 12, 0, 0, 34816, 84, }, /* 1118 */ + { 149, 15, 12, 0, 0, 34816, 74, }, /* 1119 */ + { 115, 7, 12, 0, 0, 34816, 84, }, /* 1120 */ + { 115, 15, 12, 0, 0, 34816, 74, }, /* 1121 */ + { 115, 21, 12, 0, 0, 28672, 110, }, /* 1122 */ + { 52, 7, 12, 0, 0, 34816, 84, }, /* 1123 */ + { 52, 21, 12, 0, 0, 34816, 74, }, /* 1124 */ + { 61, 7, 12, 0, 0, 34816, 84, }, /* 1125 */ + { 134, 7, 12, 0, 0, 34816, 84, }, /* 1126 */ + { 134, 15, 12, 0, 0, 34816, 74, }, /* 1127 */ + { 112, 7, 12, 0, 0, 34816, 84, }, /* 1128 */ + { 112, 12, 3, 0, 0, 26624, 106, }, /* 1129 */ + { 112, 12, 3, 0, 0, 26624, 98, }, /* 1130 */ + { 112, 12, 3, 0, 0, 26624, 158, }, /* 1131 */ + { 112, 15, 12, 0, 0, 34816, 74, }, /* 1132 */ + { 112, 21, 12, 0, 0, 34816, 74, }, /* 1133 */ + { 112, 21, 12, 0, 0, 34816, 128, }, /* 1134 */ + { 129, 7, 12, 0, 0, 34816, 84, }, /* 1135 */ + { 129, 15, 12, 0, 0, 34816, 74, }, /* 1136 */ + { 129, 21, 12, 0, 0, 34816, 74, }, /* 1137 */ + { 141, 7, 12, 0, 0, 34816, 84, }, /* 1138 */ + { 141, 15, 12, 0, 0, 34816, 74, }, /* 1139 */ + { 71, 7, 12, 0, 0, 34816, 84, }, /* 1140 */ + { 71, 26, 12, 0, 0, 34816, 74, }, /* 1141 */ + { 71, 12, 3, 0, 0, 26624, 98, }, /* 1142 */ + { 71, 15, 12, 0, 0, 34816, 74, }, /* 1143 */ + { 71, 21, 12, 0, 0, 34816, 110, }, /* 1144 */ + { 71, 21, 12, 0, 0, 35256, 110, }, /* 1145 */ + { 71, 21, 12, 0, 0, 34816, 74, }, /* 1146 */ + { 53, 7, 12, 0, 0, 34816, 84, }, /* 1147 */ + { 53, 21, 12, 0, 0, 28672, 74, }, /* 1148 */ + { 53, 21, 12, 0, 0, 28672, 110, }, /* 1149 */ + { 130, 7, 12, 0, 0, 34816, 84, }, /* 1150 */ + { 130, 15, 12, 0, 0, 34816, 74, }, /* 1151 */ + { 131, 7, 12, 0, 0, 34816, 84, }, /* 1152 */ + { 131, 15, 12, 0, 0, 34816, 74, }, /* 1153 */ + { 74, 7, 12, 0, 0, 34816, 84, }, /* 1154 */ + { 74, 21, 12, 0, 0, 34816, 110, }, /* 1155 */ + { 74, 15, 12, 0, 0, 34816, 74, }, /* 1156 */ + { 57, 7, 12, 0, 0, 34816, 84, }, /* 1157 */ + { 78, 9, 12, 0, 64, 34816, 76, }, /* 1158 */ + { 78, 5, 12, 0, -64, 34816, 78, }, /* 1159 */ + { 78, 15, 12, 0, 0, 34816, 74, }, /* 1160 */ + { 85, 7, 12, 0, 0, 0, 84, }, /* 1161 */ + { 85, 7, 12, 0, 0, 0, 314, }, /* 1162 */ + { 85, 12, 3, 0, 0, 26624, 132, }, /* 1163 */ + { 85, 13, 12, 0, 0, 2048, 144, }, /* 1164 */ + { 92, 13, 12, 0, 0, 2048, 144, }, /* 1165 */ + { 92, 7, 12, 0, 0, 34816, 84, }, /* 1166 */ + { 92, 6, 12, 0, 0, 34816, 96, }, /* 1167 */ + { 92, 9, 12, 0, 32, 34816, 76, }, /* 1168 */ + { 92, 12, 3, 0, 0, 26624, 132, }, /* 1169 */ + { 92, 12, 3, 0, 0, 26624, 164, }, /* 1170 */ + { 92, 12, 3, 0, 0, 26624, 98, }, /* 1171 */ + { 92, 17, 12, 0, 0, 28672, 130, }, /* 1172 */ + { 92, 6, 12, 0, 0, 34816, 138, }, /* 1173 */ + { 92, 5, 12, 0, -32, 34816, 78, }, /* 1174 */ + { 92, 25, 12, 0, 0, 34816, 122, }, /* 1175 */ + { 5, 15, 12, 0, 0, 2048, 74, }, /* 1176 */ + { 88, 7, 12, 0, 0, 34816, 84, }, /* 1177 */ + { 88, 12, 3, 0, 0, 26624, 106, }, /* 1178 */ + { 88, 17, 12, 0, 0, 34816, 130, }, /* 1179 */ + { 159, 7, 12, 0, 0, 34816, 84, }, /* 1180 */ + { 159, 15, 12, 0, 0, 34816, 74, }, /* 1181 */ + { 86, 7, 12, 0, 0, 0, 84, }, /* 1182 */ + { 86, 12, 3, 0, 0, 26624, 98, }, /* 1183 */ + { 86, 15, 12, 0, 0, 0, 74, }, /* 1184 */ + { 86, 21, 12, 0, 0, 0, 128, }, /* 1185 */ + { 90, 7, 12, 0, 0, 34816, 84, }, /* 1186 */ + { 90, 12, 3, 0, 0, 26624, 98, }, /* 1187 */ + { 90, 21, 12, 0, 0, 34816, 128, }, /* 1188 */ + { 163, 7, 12, 0, 0, 34816, 84, }, /* 1189 */ + { 163, 15, 12, 0, 0, 34816, 74, }, /* 1190 */ + { 160, 7, 12, 0, 0, 34816, 84, }, /* 1191 */ + { 133, 10, 5, 0, 0, 18432, 154, }, /* 1192 */ + { 133, 12, 3, 0, 0, 26624, 106, }, /* 1193 */ + { 133, 7, 12, 0, 0, 18432, 84, }, /* 1194 */ + { 133, 12, 3, 0, 0, 26624, 158, }, /* 1195 */ + { 133, 21, 12, 0, 0, 18432, 128, }, /* 1196 */ + { 133, 21, 12, 0, 0, 18432, 110, }, /* 1197 */ + { 133, 15, 12, 0, 0, 28672, 74, }, /* 1198 */ + { 133, 13, 12, 0, 0, 18432, 144, }, /* 1199 */ + { 133, 12, 3, 0, 0, 26624, 290, }, /* 1200 */ + { 58, 12, 3, 0, 0, 26624, 106, }, /* 1201 */ + { 58, 10, 5, 0, 0, 18432, 154, }, /* 1202 */ + { 58, 7, 12, 0, 0, 18432, 84, }, /* 1203 */ + { 58, 12, 3, 0, 0, 26624, 158, }, /* 1204 */ + { 58, 12, 3, 0, 0, 26624, 98, }, /* 1205 */ + { 58, 21, 12, 0, 0, 18432, 74, }, /* 1206 */ + { 58, 1, 4, 0, 0, 18432, 134, }, /* 1207 */ + { 58, 21, 12, 0, 0, 18432, 128, }, /* 1208 */ + { 136, 7, 12, 0, 0, 18432, 84, }, /* 1209 */ + { 136, 13, 12, 0, 0, 18432, 144, }, /* 1210 */ + { 60, 12, 3, 0, 0, 26624, 106, }, /* 1211 */ + { 60, 7, 12, 0, 0, 18432, 84, }, /* 1212 */ + { 60, 10, 5, 0, 0, 18432, 154, }, /* 1213 */ + { 60, 12, 3, 0, 0, 26624, 158, }, /* 1214 */ + { 60, 13, 12, 0, 0, 18432, 144, }, /* 1215 */ + { 60, 21, 12, 0, 0, 18432, 74, }, /* 1216 */ + { 60, 21, 12, 0, 0, 18432, 128, }, /* 1217 */ + { 70, 7, 12, 0, 0, 18432, 84, }, /* 1218 */ + { 70, 12, 3, 0, 0, 26624, 98, }, /* 1219 */ + { 70, 21, 12, 0, 0, 18432, 74, }, /* 1220 */ + { 62, 12, 3, 0, 0, 26624, 106, }, /* 1221 */ + { 62, 10, 5, 0, 0, 18432, 154, }, /* 1222 */ + { 62, 7, 12, 0, 0, 18432, 84, }, /* 1223 */ + { 62, 10, 3, 0, 0, 18432, 188, }, /* 1224 */ + { 62, 7, 4, 0, 0, 18432, 84, }, /* 1225 */ + { 62, 21, 12, 0, 0, 18432, 128, }, /* 1226 */ + { 62, 21, 12, 0, 0, 18432, 74, }, /* 1227 */ + { 62, 12, 3, 0, 0, 26624, 104, }, /* 1228 */ + { 62, 12, 3, 0, 0, 26624, 98, }, /* 1229 */ + { 62, 13, 12, 0, 0, 18432, 144, }, /* 1230 */ + { 17, 15, 12, 0, 0, 18432, 74, }, /* 1231 */ + { 68, 7, 12, 0, 0, 18432, 84, }, /* 1232 */ + { 68, 10, 5, 0, 0, 18432, 154, }, /* 1233 */ + { 68, 12, 3, 0, 0, 26624, 106, }, /* 1234 */ + { 68, 10, 3, 0, 0, 18432, 188, }, /* 1235 */ + { 68, 12, 3, 0, 0, 26624, 98, }, /* 1236 */ + { 68, 12, 3, 0, 0, 26624, 162, }, /* 1237 */ + { 68, 21, 12, 0, 0, 18432, 128, }, /* 1238 */ + { 68, 21, 12, 0, 0, 18432, 110, }, /* 1239 */ + { 68, 21, 12, 0, 0, 18432, 74, }, /* 1240 */ + { 77, 7, 12, 0, 0, 18432, 84, }, /* 1241 */ + { 77, 21, 12, 0, 0, 18432, 128, }, /* 1242 */ + { 75, 7, 12, 0, 0, 18432, 84, }, /* 1243 */ + { 75, 12, 3, 0, 0, 26624, 106, }, /* 1244 */ + { 75, 10, 5, 0, 0, 18432, 154, }, /* 1245 */ + { 75, 12, 3, 0, 0, 26624, 98, }, /* 1246 */ + { 75, 12, 3, 0, 0, 26624, 158, }, /* 1247 */ + { 75, 13, 12, 0, 0, 18432, 144, }, /* 1248 */ + { 67, 12, 3, 0, 0, 26624, 106, }, /* 1249 */ + { 67, 12, 3, 0, 0, 26836, 106, }, /* 1250 */ + { 67, 10, 5, 0, 0, 18432, 154, }, /* 1251 */ + { 67, 10, 5, 0, 0, 18644, 154, }, /* 1252 */ + { 67, 7, 12, 0, 0, 18432, 84, }, /* 1253 */ + { 106, 12, 3, 0, 0, 26836, 98, }, /* 1254 */ + { 67, 12, 3, 0, 0, 26836, 98, }, /* 1255 */ + { 67, 10, 3, 0, 0, 18432, 160, }, /* 1256 */ + { 67, 10, 3, 0, 0, 18432, 188, }, /* 1257 */ + { 67, 7, 12, 0, 0, 18432, 348, }, /* 1258 */ + { 67, 12, 3, 0, 0, 26624, 98, }, /* 1259 */ + { 97, 7, 12, 0, 0, 18432, 84, }, /* 1260 */ + { 97, 10, 3, 0, 0, 18432, 160, }, /* 1261 */ + { 97, 10, 5, 0, 0, 18432, 154, }, /* 1262 */ + { 97, 12, 3, 0, 0, 26624, 106, }, /* 1263 */ + { 97, 12, 3, 0, 0, 26624, 158, }, /* 1264 */ + { 97, 10, 3, 0, 0, 18432, 188, }, /* 1265 */ + { 97, 7, 4, 0, 0, 18432, 84, }, /* 1266 */ + { 97, 12, 3, 0, 0, 26624, 164, }, /* 1267 */ + { 97, 7, 12, 0, 0, 18432, 350, }, /* 1268 */ + { 97, 21, 12, 0, 0, 18432, 128, }, /* 1269 */ + { 97, 21, 12, 0, 0, 18432, 74, }, /* 1270 */ + { 97, 12, 3, 0, 0, 26624, 98, }, /* 1271 */ + { 153, 7, 12, 0, 0, 18432, 84, }, /* 1272 */ + { 153, 10, 5, 0, 0, 18432, 154, }, /* 1273 */ + { 153, 12, 3, 0, 0, 26624, 106, }, /* 1274 */ + { 153, 12, 3, 0, 0, 26624, 158, }, /* 1275 */ + { 153, 12, 3, 0, 0, 26624, 98, }, /* 1276 */ + { 153, 21, 12, 0, 0, 18432, 128, }, /* 1277 */ + { 153, 21, 12, 0, 0, 18432, 110, }, /* 1278 */ + { 153, 21, 12, 0, 0, 18432, 74, }, /* 1279 */ + { 153, 13, 12, 0, 0, 18432, 144, }, /* 1280 */ + { 153, 12, 3, 0, 0, 26624, 104, }, /* 1281 */ + { 76, 7, 12, 0, 0, 18432, 84, }, /* 1282 */ + { 76, 10, 3, 0, 0, 18432, 160, }, /* 1283 */ + { 76, 10, 5, 0, 0, 18432, 154, }, /* 1284 */ + { 76, 12, 3, 0, 0, 26624, 106, }, /* 1285 */ + { 76, 12, 3, 0, 0, 26624, 158, }, /* 1286 */ + { 76, 12, 3, 0, 0, 26624, 98, }, /* 1287 */ + { 76, 21, 12, 0, 0, 18432, 74, }, /* 1288 */ + { 76, 13, 12, 0, 0, 18432, 144, }, /* 1289 */ + { 145, 7, 12, 0, 0, 18432, 84, }, /* 1290 */ + { 145, 10, 3, 0, 0, 18432, 160, }, /* 1291 */ + { 145, 10, 5, 0, 0, 18432, 154, }, /* 1292 */ + { 145, 12, 3, 0, 0, 26624, 106, }, /* 1293 */ + { 145, 12, 3, 0, 0, 26624, 158, }, /* 1294 */ + { 145, 12, 3, 0, 0, 26624, 98, }, /* 1295 */ + { 145, 21, 12, 0, 0, 18432, 74, }, /* 1296 */ + { 145, 21, 12, 0, 0, 18432, 128, }, /* 1297 */ + { 145, 21, 12, 0, 0, 18432, 110, }, /* 1298 */ + { 145, 21, 12, 0, 0, 18432, 190, }, /* 1299 */ + { 72, 7, 12, 0, 0, 18432, 84, }, /* 1300 */ + { 72, 10, 5, 0, 0, 18432, 154, }, /* 1301 */ + { 72, 12, 3, 0, 0, 26624, 106, }, /* 1302 */ + { 72, 12, 3, 0, 0, 26624, 158, }, /* 1303 */ + { 72, 21, 12, 0, 0, 18432, 128, }, /* 1304 */ + { 72, 21, 12, 0, 0, 18432, 74, }, /* 1305 */ + { 72, 13, 12, 0, 0, 18432, 144, }, /* 1306 */ + { 63, 7, 12, 0, 0, 18432, 84, }, /* 1307 */ + { 63, 12, 3, 0, 0, 26624, 106, }, /* 1308 */ + { 63, 10, 5, 0, 0, 18432, 154, }, /* 1309 */ + { 63, 10, 3, 0, 0, 18432, 188, }, /* 1310 */ + { 63, 12, 3, 0, 0, 26624, 98, }, /* 1311 */ + { 63, 21, 12, 0, 0, 18432, 74, }, /* 1312 */ + { 63, 13, 12, 0, 0, 18432, 144, }, /* 1313 */ + { 147, 7, 12, 0, 0, 18432, 84, }, /* 1314 */ + { 147, 12, 3, 0, 0, 26624, 106, }, /* 1315 */ + { 147, 10, 5, 0, 0, 18432, 154, }, /* 1316 */ + { 147, 10, 12, 0, 0, 18432, 154, }, /* 1317 */ + { 147, 12, 3, 0, 0, 26624, 158, }, /* 1318 */ + { 147, 13, 12, 0, 0, 18432, 144, }, /* 1319 */ + { 147, 15, 12, 0, 0, 18432, 74, }, /* 1320 */ + { 147, 21, 12, 0, 0, 18432, 128, }, /* 1321 */ + { 147, 26, 12, 0, 0, 18432, 74, }, /* 1322 */ + { 83, 7, 12, 0, 0, 18432, 84, }, /* 1323 */ + { 83, 10, 5, 0, 0, 18432, 154, }, /* 1324 */ + { 83, 12, 3, 0, 0, 26624, 106, }, /* 1325 */ + { 83, 12, 3, 0, 0, 26624, 158, }, /* 1326 */ + { 83, 12, 3, 0, 0, 26624, 98, }, /* 1327 */ + { 83, 21, 12, 0, 0, 18432, 74, }, /* 1328 */ + { 146, 9, 12, 0, 32, 18432, 76, }, /* 1329 */ + { 146, 5, 12, 0, -32, 18432, 78, }, /* 1330 */ + { 146, 13, 12, 0, 0, 18432, 144, }, /* 1331 */ + { 146, 15, 12, 0, 0, 18432, 74, }, /* 1332 */ + { 146, 7, 12, 0, 0, 18432, 84, }, /* 1333 */ + { 164, 7, 12, 0, 0, 18432, 84, }, /* 1334 */ + { 164, 10, 3, 0, 0, 18432, 160, }, /* 1335 */ + { 164, 10, 5, 0, 0, 18432, 154, }, /* 1336 */ + { 164, 12, 3, 0, 0, 26624, 106, }, /* 1337 */ + { 164, 10, 3, 0, 0, 18432, 188, }, /* 1338 */ + { 164, 12, 3, 0, 0, 26624, 158, }, /* 1339 */ + { 164, 7, 4, 0, 0, 18432, 84, }, /* 1340 */ + { 164, 12, 3, 0, 0, 26624, 98, }, /* 1341 */ + { 164, 21, 12, 0, 0, 18432, 128, }, /* 1342 */ + { 164, 21, 12, 0, 0, 18432, 74, }, /* 1343 */ + { 164, 13, 12, 0, 0, 18432, 144, }, /* 1344 */ + { 87, 7, 12, 0, 0, 18432, 84, }, /* 1345 */ + { 87, 10, 5, 0, 0, 18432, 154, }, /* 1346 */ + { 87, 12, 3, 0, 0, 26624, 106, }, /* 1347 */ + { 87, 12, 3, 0, 0, 26624, 158, }, /* 1348 */ + { 87, 21, 12, 0, 0, 18432, 74, }, /* 1349 */ + { 156, 7, 12, 0, 0, 18432, 84, }, /* 1350 */ + { 156, 12, 3, 0, 0, 26624, 106, }, /* 1351 */ + { 156, 12, 3, 0, 0, 18432, 106, }, /* 1352 */ + { 156, 12, 3, 0, 0, 26624, 104, }, /* 1353 */ + { 156, 12, 3, 0, 0, 26624, 158, }, /* 1354 */ + { 156, 10, 5, 0, 0, 18432, 154, }, /* 1355 */ + { 156, 7, 4, 0, 0, 18432, 84, }, /* 1356 */ + { 156, 21, 12, 0, 0, 18432, 74, }, /* 1357 */ + { 156, 21, 12, 0, 0, 18432, 128, }, /* 1358 */ + { 155, 7, 12, 0, 0, 18432, 84, }, /* 1359 */ + { 155, 12, 3, 0, 0, 26624, 106, }, /* 1360 */ + { 155, 10, 5, 0, 0, 18432, 154, }, /* 1361 */ + { 155, 7, 4, 0, 0, 18432, 84, }, /* 1362 */ + { 155, 12, 3, 0, 0, 26624, 352, }, /* 1363 */ + { 155, 12, 3, 0, 0, 26624, 158, }, /* 1364 */ + { 155, 21, 12, 0, 0, 18432, 74, }, /* 1365 */ + { 155, 21, 12, 0, 0, 18432, 128, }, /* 1366 */ + { 155, 21, 12, 0, 0, 18432, 110, }, /* 1367 */ + { 144, 7, 12, 0, 0, 18432, 84, }, /* 1368 */ + { 95, 7, 12, 0, 0, 18432, 84, }, /* 1369 */ + { 95, 21, 12, 0, 0, 18432, 74, }, /* 1370 */ + { 95, 13, 12, 0, 0, 18432, 144, }, /* 1371 */ + { 151, 7, 12, 0, 0, 18432, 84, }, /* 1372 */ + { 151, 10, 5, 0, 0, 18432, 154, }, /* 1373 */ + { 151, 12, 3, 0, 0, 26624, 106, }, /* 1374 */ + { 151, 12, 3, 0, 0, 18432, 158, }, /* 1375 */ + { 151, 21, 12, 0, 0, 18432, 128, }, /* 1376 */ + { 151, 21, 12, 0, 0, 18432, 110, }, /* 1377 */ + { 151, 21, 12, 0, 0, 18432, 74, }, /* 1378 */ + { 151, 13, 12, 0, 0, 18432, 144, }, /* 1379 */ + { 151, 15, 12, 0, 0, 18432, 74, }, /* 1380 */ + { 152, 21, 12, 0, 0, 18432, 74, }, /* 1381 */ + { 152, 21, 12, 0, 0, 18432, 110, }, /* 1382 */ + { 152, 7, 12, 0, 0, 18432, 84, }, /* 1383 */ + { 152, 12, 3, 0, 0, 26624, 106, }, /* 1384 */ + { 152, 10, 5, 0, 0, 18432, 154, }, /* 1385 */ + { 82, 7, 12, 0, 0, 18432, 84, }, /* 1386 */ + { 82, 12, 3, 0, 0, 26624, 106, }, /* 1387 */ + { 82, 12, 3, 0, 0, 26624, 98, }, /* 1388 */ + { 82, 12, 3, 0, 0, 26624, 158, }, /* 1389 */ + { 82, 7, 4, 0, 0, 18432, 84, }, /* 1390 */ + { 82, 13, 12, 0, 0, 18432, 144, }, /* 1391 */ + { 84, 7, 12, 0, 0, 18432, 84, }, /* 1392 */ + { 84, 10, 5, 0, 0, 18432, 154, }, /* 1393 */ + { 84, 12, 3, 0, 0, 26624, 106, }, /* 1394 */ + { 84, 12, 3, 0, 0, 26624, 158, }, /* 1395 */ + { 84, 13, 12, 0, 0, 18432, 144, }, /* 1396 */ + { 157, 7, 12, 0, 0, 18432, 84, }, /* 1397 */ + { 157, 12, 3, 0, 0, 26624, 106, }, /* 1398 */ + { 157, 10, 5, 0, 0, 18432, 154, }, /* 1399 */ + { 157, 21, 12, 0, 0, 18432, 128, }, /* 1400 */ + { 168, 12, 3, 0, 0, 26624, 106, }, /* 1401 */ + { 168, 7, 4, 0, 0, 18432, 84, }, /* 1402 */ + { 168, 10, 5, 0, 0, 18432, 154, }, /* 1403 */ + { 168, 7, 12, 0, 0, 18432, 84, }, /* 1404 */ + { 168, 10, 3, 0, 0, 18432, 188, }, /* 1405 */ + { 168, 12, 3, 0, 0, 26624, 158, }, /* 1406 */ + { 168, 21, 12, 0, 0, 18432, 128, }, /* 1407 */ + { 168, 21, 12, 0, 0, 18432, 74, }, /* 1408 */ + { 168, 13, 12, 0, 0, 18432, 144, }, /* 1409 */ + { 168, 12, 3, 0, 0, 26624, 98, }, /* 1410 */ + { 13, 15, 12, 0, 0, 18432, 74, }, /* 1411 */ + { 13, 21, 12, 0, 0, 18432, 74, }, /* 1412 */ + { 114, 7, 12, 0, 0, 18432, 84, }, /* 1413 */ + { 114, 14, 12, 0, 0, 18432, 84, }, /* 1414 */ + { 114, 21, 12, 0, 0, 18432, 110, }, /* 1415 */ + { 89, 7, 12, 0, 0, 18432, 84, }, /* 1416 */ + { 89, 21, 12, 0, 0, 18432, 74, }, /* 1417 */ + { 125, 7, 12, 0, 0, 18432, 84, }, /* 1418 */ + { 125, 1, 2, 0, 0, 18432, 346, }, /* 1419 */ + { 125, 12, 3, 0, 0, 26624, 104, }, /* 1420 */ + { 125, 12, 3, 0, 0, 26624, 98, }, /* 1421 */ + { 148, 7, 12, 0, 0, 18432, 84, }, /* 1422 */ + { 93, 7, 12, 0, 0, 18432, 84, }, /* 1423 */ + { 93, 12, 3, 0, 0, 26624, 106, }, /* 1424 */ + { 93, 10, 5, 0, 0, 18432, 154, }, /* 1425 */ + { 93, 12, 3, 0, 0, 26624, 158, }, /* 1426 */ + { 93, 13, 12, 0, 0, 18432, 144, }, /* 1427 */ + { 140, 7, 12, 0, 0, 18432, 84, }, /* 1428 */ + { 140, 13, 12, 0, 0, 18432, 144, }, /* 1429 */ + { 140, 21, 12, 0, 0, 18432, 128, }, /* 1430 */ + { 166, 7, 12, 0, 0, 18432, 84, }, /* 1431 */ + { 166, 13, 12, 0, 0, 18432, 144, }, /* 1432 */ + { 137, 7, 12, 0, 0, 18432, 84, }, /* 1433 */ + { 137, 12, 3, 0, 0, 26624, 98, }, /* 1434 */ + { 137, 21, 12, 0, 0, 18432, 128, }, /* 1435 */ + { 138, 7, 12, 0, 0, 18432, 84, }, /* 1436 */ + { 138, 12, 3, 0, 0, 26624, 98, }, /* 1437 */ + { 138, 21, 12, 0, 0, 18432, 128, }, /* 1438 */ + { 138, 21, 12, 0, 0, 18432, 110, }, /* 1439 */ + { 138, 21, 12, 0, 0, 18432, 74, }, /* 1440 */ + { 138, 26, 12, 0, 0, 18432, 74, }, /* 1441 */ + { 138, 6, 12, 0, 0, 18432, 148, }, /* 1442 */ + { 138, 6, 12, 0, 0, 18432, 138, }, /* 1443 */ + { 138, 13, 12, 0, 0, 18432, 144, }, /* 1444 */ + { 138, 15, 12, 0, 0, 18432, 74, }, /* 1445 */ + { 170, 6, 12, 0, 0, 18432, 148, }, /* 1446 */ + { 170, 7, 12, 0, 0, 18432, 84, }, /* 1447 */ + { 170, 7, 7, 0, 0, 18432, 84, }, /* 1448 */ + { 170, 6, 12, 0, 0, 18432, 94, }, /* 1449 */ + { 170, 21, 12, 0, 0, 18432, 74, }, /* 1450 */ + { 170, 21, 12, 0, 0, 18432, 128, }, /* 1451 */ + { 170, 13, 12, 0, 0, 18432, 144, }, /* 1452 */ + { 158, 9, 12, 0, 32, 18432, 76, }, /* 1453 */ + { 158, 5, 12, 0, -32, 18432, 78, }, /* 1454 */ + { 158, 15, 12, 0, 0, 18432, 74, }, /* 1455 */ + { 158, 21, 12, 0, 0, 18432, 110, }, /* 1456 */ + { 158, 21, 12, 0, 0, 18432, 128, }, /* 1457 */ + { 158, 21, 12, 0, 0, 18432, 74, }, /* 1458 */ + { 135, 7, 12, 0, 0, 18432, 84, }, /* 1459 */ + { 135, 12, 3, 0, 0, 26624, 106, }, /* 1460 */ + { 135, 10, 5, 0, 0, 18432, 154, }, /* 1461 */ + { 135, 12, 3, 0, 0, 26624, 132, }, /* 1462 */ + { 135, 6, 12, 0, 0, 18432, 94, }, /* 1463 */ + { 81, 6, 12, 0, 0, 18432, 138, }, /* 1464 */ + { 154, 6, 12, 0, 0, 18432, 138, }, /* 1465 */ + { 30, 21, 12, 0, 0, 28672, 74, }, /* 1466 */ + { 165, 12, 3, 0, 0, 26624, 354, }, /* 1467 */ + { 30, 10, 3, 0, 0, 18432, 356, }, /* 1468 */ + { 81, 7, 12, 0, 0, 18432, 304, }, /* 1469 */ + { 165, 7, 12, 0, 0, 18432, 304, }, /* 1470 */ + { 28, 6, 12, 0, 0, 18432, 94, }, /* 1471 */ + { 154, 7, 12, 0, 0, 18432, 304, }, /* 1472 */ + { 65, 7, 12, 0, 0, 18432, 84, }, /* 1473 */ + { 65, 26, 12, 0, 0, 18432, 74, }, /* 1474 */ + { 65, 12, 3, 0, 0, 26624, 104, }, /* 1475 */ + { 65, 12, 3, 0, 0, 26624, 106, }, /* 1476 */ + { 65, 21, 12, 0, 0, 18432, 128, }, /* 1477 */ + { 99, 1, 2, 0, 0, 6472, 66, }, /* 1478 */ + { 99, 13, 12, 0, 0, 10240, 144, }, /* 1479 */ + { 99, 10, 3, 0, 0, 18432, 358, }, /* 1480 */ + { 99, 10, 3, 0, 0, 18432, 306, }, /* 1481 */ + { 1, 12, 3, 0, 0, 26624, 104, }, /* 1482 */ + { 99, 25, 12, 0, 0, 28672, 360, }, /* 1483 */ + { 99, 13, 12, 0, 0, 10240, 226, }, /* 1484 */ + { 150, 26, 12, 0, 0, 18432, 74, }, /* 1485 */ + { 150, 12, 3, 0, 0, 26624, 104, }, /* 1486 */ + { 150, 21, 12, 0, 0, 18432, 110, }, /* 1487 */ + { 150, 21, 12, 0, 0, 18432, 128, }, /* 1488 */ + { 150, 21, 12, 0, 0, 18432, 74, }, /* 1489 */ + { 44, 12, 3, 0, 0, 26624, 106, }, /* 1490 */ + { 2, 6, 12, 0, 0, 18432, 92, }, /* 1491 */ + { 161, 7, 12, 0, 0, 18432, 84, }, /* 1492 */ + { 161, 12, 3, 0, 0, 26624, 98, }, /* 1493 */ + { 161, 6, 12, 0, 0, 18432, 148, }, /* 1494 */ + { 161, 6, 12, 0, 0, 18432, 138, }, /* 1495 */ + { 161, 13, 12, 0, 0, 18432, 144, }, /* 1496 */ + { 161, 26, 12, 0, 0, 18432, 74, }, /* 1497 */ + { 91, 7, 12, 0, 0, 18432, 84, }, /* 1498 */ + { 91, 12, 3, 0, 0, 26624, 98, }, /* 1499 */ + { 162, 7, 12, 0, 0, 18432, 84, }, /* 1500 */ + { 162, 12, 3, 0, 0, 26624, 98, }, /* 1501 */ + { 162, 13, 12, 0, 0, 18432, 144, }, /* 1502 */ + { 162, 23, 12, 0, 0, 14336, 74, }, /* 1503 */ + { 169, 7, 12, 0, 0, 18432, 84, }, /* 1504 */ + { 169, 6, 12, 0, 0, 18432, 148, }, /* 1505 */ + { 169, 12, 3, 0, 0, 26624, 104, }, /* 1506 */ + { 169, 13, 12, 0, 0, 18432, 144, }, /* 1507 */ + { 94, 7, 12, 0, 0, 18432, 84, }, /* 1508 */ + { 94, 12, 3, 0, 0, 26624, 98, }, /* 1509 */ + { 94, 12, 3, 0, 0, 26624, 164, }, /* 1510 */ + { 94, 13, 12, 0, 0, 18432, 144, }, /* 1511 */ + { 94, 21, 12, 0, 0, 18432, 74, }, /* 1512 */ + { 139, 7, 12, 0, 0, 34816, 84, }, /* 1513 */ + { 139, 15, 12, 0, 0, 34816, 74, }, /* 1514 */ + { 139, 12, 3, 0, 0, 26624, 98, }, /* 1515 */ + { 79, 9, 12, 0, 34, 34816, 76, }, /* 1516 */ + { 79, 5, 12, 0, -34, 34816, 78, }, /* 1517 */ + { 79, 12, 3, 0, 0, 26624, 164, }, /* 1518 */ + { 79, 12, 3, 0, 0, 26624, 106, }, /* 1519 */ + { 79, 12, 3, 0, 0, 26624, 98, }, /* 1520 */ + { 79, 6, 12, 0, 0, 34816, 148, }, /* 1521 */ + { 79, 13, 12, 0, 0, 34816, 144, }, /* 1522 */ + { 79, 21, 12, 0, 0, 34816, 74, }, /* 1523 */ + { 99, 15, 12, 0, 0, 0, 74, }, /* 1524 */ + { 99, 26, 12, 0, 0, 0, 74, }, /* 1525 */ + { 99, 23, 12, 0, 0, 0, 74, }, /* 1526 */ + { 5, 7, 12, 0, 0, 0, 254, }, /* 1527 */ + { 99, 26, 14, 0, 0, 28672, 362, }, /* 1528 */ + { 99, 26, 14, 0, 0, 28672, 364, }, /* 1529 */ + { 98, 2, 14, 0, 0, 18432, 366, }, /* 1530 */ + { 99, 26, 12, 0, 0, 18432, 368, }, /* 1531 */ + { 99, 26, 14, 0, 0, 18432, 370, }, /* 1532 */ + { 99, 26, 14, 0, 0, 18432, 364, }, /* 1533 */ + { 99, 26, 11, 0, 0, 18432, 372, }, /* 1534 */ + { 27, 26, 12, 0, 0, 18432, 74, }, /* 1535 */ + { 99, 26, 14, 0, 0, 18432, 250, }, /* 1536 */ + { 99, 26, 14, 0, 0, 18784, 364, }, /* 1537 */ + { 99, 26, 14, 0, 0, 28672, 374, }, /* 1538 */ + { 99, 26, 14, 0, 0, 28672, 376, }, /* 1539 */ + { 99, 24, 3, 0, 0, 28672, 378, }, /* 1540 */ + { 99, 26, 14, 0, 0, 28672, 380, }, /* 1541 */ + { 99, 1, 3, 0, 0, 6144, 382, }, /* 1542 */ }; const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ @@ -1885,36 +2129,36 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,129,129,130,131,132,133,134,135,136,137,138,139,140,141, /* U+F800 */ 142,143,144,145,146,147,148,149,150,151,152,153,154,154,155,156, /* U+10000 */ 157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172, /* U+10800 */ -173,174,175,176,177,178,179,146,180,181,146,182,183,184,185,146, /* U+11000 */ -186,187,188,189,190,191,192,146,193,194,195,196,146,197,198,199, /* U+11800 */ -200,200,200,200,200,200,200,201,202,200,203,146,146,146,146,146, /* U+12000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,204, /* U+12800 */ -205,205,205,205,205,205,205,205,206,146,146,146,146,146,146,146, /* U+13000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+13800 */ -146,146,146,146,146,146,146,146,207,207,207,207,208,146,146,146, /* U+14000 */ +173,174,175,176,177,178,179,180,181,182,146,183,184,185,186,146, /* U+11000 */ +187,188,189,190,191,192,193,194,195,196,197,198,146,199,200,201, /* U+11800 */ +202,202,202,202,202,202,202,203,204,202,205,146,146,146,146,146, /* U+12000 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,206, /* U+12800 */ +207,207,207,207,207,207,207,207,208,207,207,207,207,207,207,207, /* U+13000 */ +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, /* U+13800 */ +207,207,207,207,207,207,207,209,210,210,210,210,211,146,146,146, /* U+14000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+14800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15800 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */ -209,209,209,209,210,211,212,213,146,146,146,146,214,215,216,217, /* U+16800 */ -218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17000 */ -218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17800 */ -218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,219, /* U+18000 */ -218,218,218,218,218,218,220,220,220,221,222,146,146,146,146,146, /* U+18800 */ +146,146,212,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */ +213,213,213,213,214,215,216,217,146,146,218,146,219,220,221,222, /* U+16800 */ +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, /* U+17000 */ +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, /* U+17800 */ +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224, /* U+18000 */ +223,223,223,223,223,223,225,225,225,226,227,146,146,146,146,146, /* U+18800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1A000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,223, /* U+1A800 */ -224,225,226,227,227,228,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ -146,146,146,146,146,146,146,146,229,230,146,146,146,146,146,146, /* U+1B800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,228, /* U+1A800 */ +229,230,231,232,232,233,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ +146,146,146,146,146,146,146,146,234,235,146,146,146,146,146,146, /* U+1B800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1C000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,231,232, /* U+1C800 */ -233,234,235,236,237,238,239,146,240,241,242,243,244,245,246,247, /* U+1D000 */ -248,248,248,248,249,250,146,146,146,146,146,146,146,146,251,146, /* U+1D800 */ -252,253,254,146,146,255,146,146,146,256,146,146,146,146,146,257, /* U+1E000 */ -258,259,260,168,168,168,168,168,261,262,263,168,264,265,168,168, /* U+1E800 */ -266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281, /* U+1F000 */ -282,283,284,285,286,287,288,289,271,271,271,271,271,271,271,290, /* U+1F800 */ +146,146,146,146,146,146,146,146,236,237,236,236,236,238,239,240, /* U+1C800 */ +241,242,243,244,245,246,247,146,248,249,250,251,252,253,254,255, /* U+1D000 */ +256,256,256,256,257,258,146,146,146,146,146,146,146,146,259,146, /* U+1D800 */ +260,261,262,146,146,263,146,146,146,264,146,265,146,146,146,266, /* U+1E000 */ +267,268,269,270,270,270,270,270,271,272,273,270,274,275,270,270, /* U+1E800 */ +276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291, /* U+1F000 */ +292,293,294,295,296,297,236,298,281,281,281,281,281,281,281,299, /* U+1F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21000 */ @@ -1935,23 +2179,23 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,291,101,101, /* U+2A000 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,300,101,101, /* U+2A000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2A800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,101,292,101, /* U+2B000 */ -293,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,101,301,101, /* U+2B000 */ +302,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2C000 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,294,101,101, /* U+2C800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,303,101,101, /* U+2C800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2E000 */ -101,101,101,101,101,101,101,295,146,146,146,146,146,146,146,146, /* U+2E800 */ +101,101,101,101,101,101,101,304,101,101,101,101,305,146,146,146, /* U+2E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+2F000 */ -129,129,129,129,296,146,146,146,146,146,146,146,146,146,146,297, /* U+2F800 */ +129,129,129,129,306,146,146,146,146,146,146,146,146,146,146,307, /* U+2F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30800 */ -101,101,101,101,101,101,298,101,101,101,101,101,101,101,101,101, /* U+31000 */ +101,101,101,101,101,101,308,101,101,101,101,101,101,101,101,101, /* U+31000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+31800 */ -101,101,101,101,101,101,101,299,146,146,146,146,146,146,146,146, /* U+32000 */ +101,101,101,101,101,101,101,309,146,146,146,146,146,146,146,146, /* U+32000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33800 */ @@ -1978,7 +2222,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+3F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+3F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41000 */ @@ -2010,7 +2254,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+4F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+4F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51000 */ @@ -2042,7 +2286,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+5F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+5F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61000 */ @@ -2074,7 +2318,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+6F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+6F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71000 */ @@ -2106,7 +2350,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+7F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+7F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81000 */ @@ -2138,7 +2382,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+8F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+8F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91000 */ @@ -2170,7 +2414,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+9F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+9F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1000 */ @@ -2202,7 +2446,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+AF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+AF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1000 */ @@ -2234,7 +2478,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+BF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+BF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1000 */ @@ -2266,7 +2510,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+CF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+CF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1000 */ @@ -2298,9 +2542,9 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+DF800 */ -300,301,302,303,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0000 */ -301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+DF800 */ +310,311,312,313,311,311,311,311,311,311,311,311,311,311,311,311, /* U+E0000 */ +311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, /* U+E0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2000 */ @@ -2330,7 +2574,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+EF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+EF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1000 */ @@ -2362,7 +2606,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FF000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+FF800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,314, /* U+FF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101000 */ @@ -2394,10 +2638,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10F000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+10F800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,314, /* U+10F800 */ }; -const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ +const uint16_t PRIV(ucd_stage2)[] = { /* 80640 bytes, block = 128 */ /* block 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 3, 4, 0, 0, @@ -2431,553 +2675,553 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ /* block 3 */ 74, 75, 65, 66, 65, 66, 76, 65, 66, 77, 77, 65, 66, 70, 78, 79, - 80, 65, 66, 77, 81, 82, 83, 84, 65, 66, 85, 70, 83, 86, 87, 88, - 65, 66, 65, 66, 65, 66, 89, 65, 66, 89, 70, 70, 65, 66, 89, 65, - 66, 90, 90, 65, 66, 65, 66, 91, 65, 66, 70, 92, 65, 66, 70, 93, - 92, 92, 92, 92, 94, 95, 96, 97, 98, 99,100,101,102, 65, 66, 65, - 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,103, 65, 66, + 80, 65, 66, 77, 81, 82, 83, 84, 65, 66, 85, 86, 83, 87, 88, 89, + 65, 66, 65, 66, 65, 66, 90, 65, 66, 90, 70, 70, 65, 66, 90, 65, + 66, 91, 91, 65, 66, 65, 66, 92, 65, 66, 70, 93, 65, 66, 70, 94, + 93, 93, 93, 93, 95, 96, 97, 98, 99,100,101,102,103, 65, 66, 65, + 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,104, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 69,104,105,106, 65, 66,107,108, 65, 66, 65, 66, 65, 66, 65, 66, + 69,105,106,107, 65, 66,108,109, 65, 66, 65, 66, 65, 66, 65, 66, /* block 4 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -109, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 70, 70, 70, 70, 70, 70,110, 65, 66,111,112,113, -113, 65, 66,114,115,116, 65, 66, 65, 67, 65, 66, 65, 66, 65, 66, -117,118,119,120,121, 70,122,122, 70,123, 70,124,125, 70, 70, 70, -122,126, 70,127, 70,128,129, 70,130,131,129,132,133, 70, 70,131, - 70,134,135, 70, 70,136, 70, 70, 70, 70, 70, 70, 70,137, 70, 70, +110, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 70, 70, 70, 70, 70, 70,111, 65, 66,112,113,114, +114, 65, 66,115,116,117, 65, 66, 65, 67, 65, 66, 65, 66, 65, 66, +118,119,120,121,122, 70,123,123, 70,124, 70,125,126, 70, 70, 70, +123,127, 70,128,129,130,131, 70,132,133,131,134,135, 70, 70,133, + 70,136,137, 70, 70,138, 70, 70, 70, 70, 70, 70, 70,139, 70, 70, /* block 5 */ -138, 70,139,138, 70, 70, 70,140,138,141,142,142,143, 70, 70, 70, - 70, 70,144, 70, 92, 70, 70, 70, 70, 70, 70, 70, 70,145,146, 70, +140, 70,141,140, 70, 70, 70,142,140,143,144,144,145, 70, 70, 70, + 70, 70,146, 70, 93, 70, 70, 70, 70, 70, 70, 70, 70,147,148, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, -147,147,148,147,147,147,147,147,147,149,149,150,150,150,150,150, -151,151, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149,149, -152,152, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, -147,147,147,147,147, 46, 46, 46, 46, 46,153,153,149, 46,150, 46, +149,149,150,149,149,149,149,149,149,151,151,152,153,152,152,152, +154,154, 46, 46, 46, 46,151,155,151,155,155,155,151,156,151,151, +157,157, 46, 46, 46, 46, 46,158, 46,159, 46, 46, 46, 46, 46, 46, +149,149,149,149,149, 46, 46, 46, 46, 46,160,160,151, 46,152, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, /* block 6 */ -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,155,154,154,156,154,154,154,154,154,154,154,154,154,157, -154,154,154,154,154,154,154,154,158,158,158,158,158,154,154,154, -154,154,154,159,159,159,159,159,159,159,159,159,159,159,159,159, -160,161,160,161,149,162,160,161,163,163,164,165,165,165,166,167, +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +174,177,176,178,176,176,176,176,176,176,176,176,176,176,176,176, +179,176,176,180,181,179,176,176,176,176,176,176,176,182,179,176, +183,184,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,185,176,176,186,176,176,176,176,176,176,176,176,176,187, +176,176,176,176,176,176,176,176,188,189,189,189,189,176,190,176, +176,176,176,191,191,191,191,191,191,191,191,191,191,191,191,191, +192,193,192,193,194,195,192,193,196,196,197,198,198,198,199,200, /* block 7 */ -163,163,163,163,162, 46,168,169,170,170,170,163,171,163,172,172, -173,174,175,174,174,176,174,174,177,178,179,174,180,174,174,174, -181,182,163,183,174,174,184,174,174,185,174,174,186,187,187,187, -173,188,189,188,188,190,188,188,191,192,193,188,194,188,188,188, -195,196,197,198,188,188,199,188,188,200,188,188,201,202,202,203, -204,205,206,207,207,208,209,210,160,161,160,161,160,161,160,161, -160,161,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -213,214,215,216,217,218,219,160,161,220,160,161,221,222,222,222, +196,196,196,196,201, 46,202,203,204,204,204,196,205,196,206,206, +207,208,209,208,208,210,208,208,211,212,213,208,214,208,208,208, +215,216,196,217,208,208,218,208,208,219,208,208,220,221,221,221, +222,223,224,223,223,225,223,223,226,227,228,223,229,223,223,223, +230,231,232,233,223,223,234,223,223,235,223,223,236,237,237,238, +239,240,241,242,242,243,244,245,192,193,192,193,192,193,192,193, +192,193,246,247,246,247,246,247,246,247,246,247,246,247,246,247, +248,249,250,251,252,253,254,192,193,255,192,193,256,257,257,257, /* block 8 */ -223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, -224,224,225,224,226,224,224,224,224,224,224,224,224,224,227,224, -224,228,229,224,224,224,224,224,224,224,230,224,224,224,224,224, -231,231,232,231,233,231,231,231,231,231,231,231,231,231,234,231, -231,235,236,231,231,231,231,231,231,231,237,231,231,231,231,231, -238,238,238,238,238,238,239,238,239,238,238,238,238,238,238,238, -240,241,242,243,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +259,259,260,259,261,259,259,259,259,259,259,259,259,259,262,259, +259,263,264,259,259,259,259,259,259,259,265,259,259,259,259,259, +266,266,267,266,268,266,266,266,266,266,266,266,266,266,269,266, +266,270,271,266,266,266,266,266,266,266,272,266,266,266,266,266, +273,273,273,273,273,273,274,273,274,273,273,273,273,273,273,273, +275,276,277,278,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, /* block 9 */ -240,241,244,245,246,247,247,246,248,248,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -249,240,241,240,241,240,241,240,241,240,241,240,241,240,241,250, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +275,276,279,280,281,282,282,281,283,283,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +284,275,276,275,276,275,276,275,276,275,276,275,276,275,276,285, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, /* block 10 */ -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -163,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, -251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, -251,251,251,251,251,251,251,163,163,252,253,253,253,253,253,254, -255,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, -256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +196,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,196,196,287,288,288,288,288,288,289, +290,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, /* block 11 */ -256,256,256,256,256,256,256,257,255,258,259,163,163,260,260,261, -262,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, -263,263,264,263,263,263,263,263,263,263,263,263,263,263,263,263, -265,265,265,265,265,265,265,265,265,265,265,265,265,265,266,265, -267,265,265,268,265,269,267,269,262,262,262,262,262,262,262,262, -270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270, -270,270,270,270,270,270,270,270,270,270,270,262,262,262,262,270, -270,270,270,267,271,262,262,262,262,262,262,262,262,262,262,262, +291,291,291,291,291,291,291,292,290,293,294,196,196,295,295,296, +297,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298, +298,298,299,298,298,298,298,298,298,298,298,298,298,298,298,298, +300,300,300,300,300,300,300,300,300,300,300,300,300,300,301,300, +302,300,300,303,300,304,302,304,297,297,297,297,297,297,297,297, +305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305, +305,305,305,305,305,305,305,305,305,305,305,297,297,297,297,305, +305,305,305,302,306,297,297,297,297,297,297,297,297,297,297,297, /* block 12 */ -272,272,272,272,272,273,274,274,275,276,276,277,278,279,280,280, -281,281,281,281,281,281,281,281,281,281,281,282,283,284,284,285, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -287,286,286,286,286,286,286,286,286,286,286,288,288,288,288,288, -288,288,288,289,289,289,281,290,291,281,281,281,281,281,281,281, -292,292,292,292,292,292,292,292,292,292,276,293,293,279,286,286, -289,286,286,294,286,286,286,286,286,286,286,286,286,286,286,286, +307,307,307,307,307,308,309,309,310,311,311,312,313,314,315,315, +316,316,316,316,316,316,316,316,316,316,316,317,318,319,319,320, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +322,321,321,321,321,321,321,321,321,321,321,323,323,323,323,323, +323,323,323,324,325,325,316,326,327,316,316,316,316,316,316,316, +328,328,328,328,328,328,328,328,328,328,311,329,329,314,321,321, +324,321,321,330,321,321,321,321,321,321,321,321,321,321,321,321, /* block 13 */ -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,295,286,281,281,281,281,281,281,281,273,280,291, -291,281,281,281,281,296,296,281,281,280,291,291,291,281,286,286, -297,297,297,297,297,297,297,297,297,297,286,286,286,298,298,286, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,331,321,316,316,316,316,316,316,332,308,315,333, +333,316,316,332,316,334,334,332,332,315,333,333,333,316,321,321, +335,335,335,335,335,335,335,335,335,335,321,321,321,336,336,321, /* block 14 */ -299,299,299,300,300,300,300,300,300,300,300,301,300,301,302,303, -304,305,304,304,304,304,304,304,304,304,304,304,304,304,304,304, -304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304, -306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306, -307,307,307,307,307,307,307,307,307,307,307,302,302,304,304,304, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +337,337,337,338,338,338,338,338,338,338,338,339,338,339,340,341, +342,343,342,342,342,342,342,342,342,342,342,342,342,342,342,342, +342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342, +344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, +345,345,345,345,345,345,345,345,345,345,345,340,340,342,342,342, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, /* block 15 */ -308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, -308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, -308,308,308,308,308,308,309,309,309,309,309,309,309,309,309,309, -309,308,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -310,310,310,310,310,310,310,310,310,310,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,312,312,312,312,312, -312,312,312,312,313,313,314,315,316,317,318,262,262,319,320,320, +346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346, +346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346, +346,346,346,346,346,346,347,347,347,347,347,347,347,347,347,347, +347,346,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +348,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349, +349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, +349,349,349,349,349,349,349,349,349,349,349,350,350,350,350,350, +350,350,350,350,351,351,352,353,354,355,356,297,297,357,358,358, /* block 16 */ +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,360,360,361,361,362,360,360,360,360,360, +360,360,360,360,362,360,360,360,362,360,360,360,360,363,297,297, +364,364,364,364,364,364,365,366,364,366,364,364,364,366,366,297, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,368,368,368,297,297,369,297, +342,342,342,342,342,342,342,342,342,342,342,340,340,340,340,340, 321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,322,322,323,323,324,322,322,322,322,322, -322,322,322,322,324,322,322,322,324,322,322,322,322,325,262,262, -326,326,326,326,326,326,326,327,326,327,326,326,326,327,327,262, -328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328, -328,328,328,328,328,328,328,328,328,329,329,329,262,262,330,262, -304,304,304,304,304,304,304,304,304,304,304,302,302,302,302,302, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 17 */ -286,286,286,286,286,286,286,286,331,286,286,286,286,286,286,302, -272,272,302,302,302,302,302,302,291,291,291,291,291,291,291,291, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,296,291,291,291,291,291,291, -291,291,291,332,281,281,281,281,281,281,281,281,281,281,281,281, -332,332,273,290,290,290,290,290,290,290,291,291,291,291,291,291, -290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,281, +321,321,321,321,321,321,321,321,370,321,321,321,321,321,321,340, +307,307,340,340,340,340,340,316,333,333,333,333,333,333,333,333, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,334,327,327,333,327,327,327, +333,333,333,371,316,316,316,316,316,316,316,316,316,316,316,316, +372,372,308,326,326,326,326,326,326,326,333,333,333,333,333,333, +326,326,326,373,326,326,326,326,326,326,326,326,326,326,326,316, /* block 18 */ -333,333,333,334,335,335,335,335,335,335,335,335,335,335,335,335, -335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335, -335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335, -335,335,335,335,335,335,335,335,335,335,333,334,336,335,334,334, -334,333,333,333,333,333,333,333,333,334,334,334,334,337,334,334, -335,338,339,154,154,333,333,333,335,335,335,335,335,335,335,335, -335,335,333,333,340,341,342,342,342,342,342,342,342,342,342,342, -343,344,335,335,335,335,335,335,335,335,335,335,335,335,335,335, +374,374,374,375,376,376,376,376,376,376,376,376,376,376,376,376, +376,376,376,376,376,377,377,377,377,377,377,377,377,377,377,377, +377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377, +377,377,377,377,377,377,377,377,377,377,374,375,378,376,375,375, +375,374,374,374,374,374,374,374,374,375,375,375,375,379,375,375, +376,380,381,176,176,374,374,374,377,377,377,377,377,377,377,377, +376,376,374,374,382,383,384,384,384,384,384,384,384,384,384,384, +385,386,376,376,376,376,376,376,377,377,377,377,377,377,377,377, /* block 19 */ -345,346,347,347,163,345,345,345,345,345,345,345,345,163,163,345, -345,163,163,345,345,345,345,345,345,345,345,345,345,345,345,345, -345,345,345,345,345,345,345,345,345,163,345,345,345,345,345,345, -345,163,345,163,163,163,345,345,345,345,163,163,348,345,349,347, -347,346,346,346,346,163,163,347,347,163,163,347,347,350,345,163, -163,163,163,163,163,163,163,349,163,163,163,163,345,345,163,345, -345,345,346,346,163,163,351,351,351,351,351,351,351,351,351,351, -345,345,352,352,353,353,353,353,353,353,354,352,345,355,356,163, +387,388,389,389,196,387,387,387,387,387,387,387,387,196,196,387, +387,196,196,387,387,390,390,390,390,390,390,390,390,390,390,390, +390,390,390,390,390,390,390,390,390,196,390,390,390,390,390,390, +390,196,390,196,196,196,390,390,390,390,196,196,391,387,392,389, +389,388,388,388,388,196,196,389,389,196,196,389,389,393,387,196, +196,196,196,196,196,196,196,392,196,196,196,196,390,390,196,390, +387,387,388,388,196,196,394,394,394,394,394,394,394,394,394,394, +390,390,395,395,396,396,396,396,396,396,397,395,387,398,399,196, /* block 20 */ -163,357,357,358,163,359,359,359,359,359,359,163,163,163,163,359, -359,163,163,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,163,359,359,359,359,359,359, -359,163,359,359,163,359,359,163,359,359,163,163,360,163,358,358, -358,357,357,163,163,163,163,357,357,163,163,357,357,361,163,163, -163,357,163,163,163,163,163,163,163,359,359,359,359,163,359,163, -163,163,163,163,163,163,362,362,362,362,362,362,362,362,362,362, -357,357,359,359,359,357,363,163,163,163,163,163,163,163,163,163, +196,400,400,401,196,402,402,402,402,402,402,196,196,196,196,402, +402,196,196,402,402,402,402,402,402,402,402,402,402,402,402,402, +402,402,402,402,402,402,402,402,402,196,402,402,402,402,402,402, +402,196,402,402,196,402,402,196,402,402,196,196,403,196,401,401, +401,400,400,196,196,196,196,400,400,196,196,400,400,404,196,196, +196,400,196,196,196,196,196,196,196,402,402,402,402,196,402,196, +196,196,196,196,196,196,405,405,405,405,405,405,405,405,405,405, +400,406,402,402,402,400,407,196,196,196,196,196,196,196,196,196, /* block 21 */ -163,364,364,365,163,366,366,366,366,366,366,366,366,366,163,366, -366,366,163,366,366,366,366,366,366,366,366,366,366,366,366,366, -366,366,366,366,366,366,366,366,366,163,366,366,366,366,366,366, -366,163,366,366,163,366,366,366,366,366,163,163,367,366,365,365, -365,364,364,364,364,364,163,364,364,365,163,365,365,368,163,163, -366,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -366,366,364,364,163,163,369,369,369,369,369,369,369,369,369,369, -370,371,163,163,163,163,163,163,163,366,364,364,364,367,367,367, +196,408,408,409,196,410,410,410,410,410,410,410,410,410,196,410, +410,410,196,410,410,411,411,411,411,411,411,411,411,411,411,411, +411,411,411,411,411,411,411,411,411,196,411,411,411,411,411,411, +411,196,411,411,196,411,411,411,411,411,196,196,412,410,409,409, +409,408,408,408,408,408,196,408,408,409,196,409,409,413,196,196, +410,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +410,410,408,408,196,196,414,414,414,414,414,414,414,414,414,414, +415,416,196,196,196,196,196,196,196,411,408,417,408,412,412,412, /* block 22 */ -163,372,373,373,163,374,374,374,374,374,374,374,374,163,163,374, -374,163,163,374,374,374,374,374,374,374,374,374,374,374,374,374, -374,374,374,374,374,374,374,374,374,163,374,374,374,374,374,374, -374,163,374,374,163,374,374,374,374,374,163,163,375,374,376,372, -373,372,372,372,372,163,163,373,373,163,163,373,373,377,163,163, -163,163,163,163,163,378,372,376,163,163,163,163,374,374,163,374, -374,374,372,372,163,163,379,379,379,379,379,379,379,379,379,379, -380,374,381,381,381,381,381,381,163,163,163,163,163,163,163,163, +196,418,419,419,196,420,420,420,420,420,420,420,420,196,196,420, +420,196,196,420,420,421,421,421,421,421,421,421,421,421,421,421, +421,421,421,421,421,421,421,421,421,196,421,421,421,421,421,421, +421,196,421,421,196,421,421,421,421,421,196,196,422,420,423,418, +419,418,418,418,418,196,196,419,419,196,196,419,419,424,196,196, +196,196,196,196,196,425,418,423,196,196,196,196,421,421,196,421, +420,420,418,418,196,196,426,426,426,426,426,426,426,426,426,426, +427,421,428,428,428,428,428,428,196,196,196,196,196,196,196,196, /* block 23 */ -163,163,382,383,163,383,383,383,383,383,383,163,163,163,383,383, -383,163,383,383,383,383,163,163,163,383,383,163,383,163,383,383, -163,163,163,383,383,163,163,163,383,383,383,163,163,163,383,383, -383,383,383,383,383,383,383,383,383,383,163,163,163,163,384,385, -382,385,385,163,163,163,385,385,385,163,385,385,385,386,163,163, -383,163,163,163,163,163,163,384,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,387,387,387,387,387,387,387,387,387,387, -388,388,388,389,390,390,390,390,390,391,390,163,163,163,163,163, +196,196,429,430,196,430,430,430,430,430,430,196,196,196,430,430, +430,196,430,430,430,430,196,196,196,430,430,196,430,196,430,430, +196,196,196,430,430,196,196,196,430,430,430,196,196,196,430,430, +430,430,430,430,430,430,430,430,430,430,196,196,196,196,431,432, +429,432,432,196,196,196,432,432,432,196,432,432,432,433,196,196, +430,196,196,196,196,196,196,431,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,434,434,434,434,434,434,434,434,434,434, +435,435,435,436,437,437,437,437,437,438,437,196,196,196,196,196, /* block 24 */ -392,393,393,393,392,394,394,394,394,394,394,394,394,163,394,394, -394,163,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,163,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,394,163,163,395,394,392,392, -392,393,393,393,393,163,392,392,392,163,392,392,392,396,163,163, -163,163,163,163,163,392,392,163,394,394,394,163,163,394,163,163, -394,394,392,392,163,163,397,397,397,397,397,397,397,397,397,397, -163,163,163,163,163,163,163,398,399,399,399,399,399,399,399,400, +439,440,440,440,439,441,441,441,441,441,441,441,441,196,441,441, +441,196,441,441,441,442,442,442,442,442,442,442,442,442,442,442, +442,442,442,442,442,442,442,442,442,196,442,442,442,442,442,442, +442,442,442,442,442,442,442,442,442,442,196,196,443,441,439,439, +439,440,440,440,440,196,439,439,439,196,439,439,439,444,196,196, +196,196,196,196,196,439,439,196,442,442,442,196,196,441,196,196, +441,441,439,439,196,196,445,445,445,445,445,445,445,445,445,445, +196,196,196,196,196,196,196,446,447,447,447,447,447,447,447,448, /* block 25 */ -401,402,403,403,404,401,401,401,401,401,401,401,401,163,401,401, -401,163,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,163,401,401,401,401,401,401, -401,401,401,401,163,401,401,401,401,401,163,163,405,401,403,406, -403,403,407,403,403,163,406,403,403,163,403,403,402,408,163,163, -163,163,163,163,163,407,407,163,163,163,163,163,163,401,401,163, -401,401,402,402,163,163,409,409,409,409,409,409,409,409,409,409, -163,401,401,403,163,163,163,163,163,163,163,163,163,163,163,163, +449,450,451,451,452,449,449,449,449,449,449,449,449,196,449,449, +449,196,449,449,449,449,449,449,449,449,449,449,449,449,449,449, +449,449,449,449,449,449,449,449,449,196,449,449,449,449,449,449, +449,449,449,449,196,449,449,449,449,449,196,196,453,449,451,454, +455,451,455,451,451,196,454,455,455,196,455,455,450,456,196,196, +196,196,196,196,196,455,455,196,196,196,196,196,196,449,449,196, +449,449,450,450,196,196,457,457,457,457,457,457,457,457,457,457, +196,449,449,451,196,196,196,196,196,196,196,196,196,196,196,196, /* block 26 */ -410,410,411,411,412,412,412,412,412,412,412,412,412,163,412,412, -412,163,412,412,412,412,412,412,412,412,412,412,412,412,412,412, -412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, -412,412,412,412,412,412,412,412,412,412,412,413,413,412,414,411, -411,410,410,410,410,163,411,411,411,163,411,411,411,413,415,416, -163,163,163,163,412,412,412,414,417,417,417,417,417,417,417,412, -412,412,410,410,163,163,418,418,418,418,418,418,418,418,418,418, -417,417,417,417,417,417,417,417,417,416,412,412,412,412,412,412, +458,458,459,459,460,460,460,460,460,460,460,460,460,196,460,460, +460,196,460,460,460,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,462,462,460,463,459, +459,458,458,458,458,196,459,459,459,196,459,459,459,462,464,465, +196,196,196,196,460,460,460,463,466,466,466,466,466,466,466,460, +460,460,458,458,196,196,467,467,467,467,467,467,467,467,467,467, +466,466,466,466,466,466,466,466,466,465,460,460,460,460,460,460, /* block 27 */ -163,419,420,420,163,421,421,421,421,421,421,421,421,421,421,421, -421,421,421,421,421,421,421,163,163,163,421,421,421,421,421,421, -421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421, -421,421,163,421,421,421,421,421,421,421,421,421,163,421,163,163, -421,421,421,421,421,421,421,163,163,163,422,163,163,163,163,423, -420,420,419,419,419,163,419,163,420,420,420,420,420,420,420,423, -163,163,163,163,163,163,424,424,424,424,424,424,424,424,424,424, -163,163,420,420,425,163,163,163,163,163,163,163,163,163,163,163, +196,468,469,469,196,470,470,470,470,470,470,470,470,470,470,470, +470,470,470,470,470,470,470,196,196,196,470,470,470,470,470,470, +470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, +470,470,196,470,470,470,470,470,470,470,470,470,196,470,196,196, +470,470,470,470,470,470,470,196,196,196,471,196,196,196,196,472, +469,469,468,468,468,196,468,196,469,469,469,469,469,469,469,472, +196,196,196,196,196,196,473,473,473,473,473,473,473,473,473,473, +196,196,469,469,474,196,196,196,196,196,196,196,196,196,196,196, /* block 28 */ -163,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,427,426,428,427,427,427,427,427,427,429,163,163,163,163,430, -431,431,431,431,431,426,432,433,433,433,433,433,433,427,433,434, -435,435,435,435,435,435,435,435,435,435,436,436,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +196,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, +475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, +475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, +475,476,475,477,476,476,476,476,476,476,478,196,196,196,196,479, +480,480,480,480,480,475,481,482,482,482,482,482,482,476,482,483, +484,484,484,484,484,484,484,484,484,484,485,485,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 29 */ -163,437,437,163,437,163,437,437,437,437,437,163,437,437,437,437, -437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, -437,437,437,437,163,437,163,437,437,437,437,437,437,437,437,437, -437,438,437,439,438,438,438,438,438,438,440,438,438,437,163,163, -441,441,441,441,441,163,442,163,443,443,443,443,443,438,444,163, -445,445,445,445,445,445,445,445,445,445,163,163,437,437,437,437, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +196,486,486,196,486,196,486,486,486,486,486,196,486,486,486,486, +486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486, +486,486,486,486,196,486,196,486,486,486,486,486,486,486,486,486, +486,487,486,488,487,487,487,487,487,487,489,487,487,486,196,196, +490,490,490,490,490,196,491,196,492,492,492,492,492,487,493,196, +494,494,494,494,494,494,494,494,494,494,196,196,486,486,486,486, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 30 */ -446,447,447,447,448,448,448,448,449,448,448,448,448,449,449,449, -449,449,449,447,448,447,447,447,450,450,447,447,447,447,447,447, -451,451,451,451,451,451,451,451,451,451,452,452,452,452,452,452, -452,452,452,452,447,450,447,450,447,450,453,454,453,454,455,455, -446,446,446,446,446,446,446,446,163,446,446,446,446,446,446,446, -446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, -446,446,446,446,446,446,446,446,446,446,446,446,446,163,163,163, -163,456,456,456,456,456,456,457,456,457,456,456,456,456,456,458, +495,496,496,496,497,497,497,497,498,497,497,497,497,498,498,498, +498,498,498,496,497,496,496,496,499,499,496,496,496,496,496,496, +500,500,500,500,500,500,500,500,500,500,501,501,501,501,501,501, +501,501,501,501,496,499,496,499,496,499,502,503,502,503,504,504, +495,495,495,495,495,495,495,495,196,495,495,495,495,495,495,495, +495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +495,495,495,495,495,495,495,495,495,495,495,495,495,196,196,196, +196,505,505,505,505,505,505,506,505,506,505,505,505,505,505,507, /* block 31 */ -456,456,459,459,460,448,450,450,446,446,446,446,446,456,456,456, -456,456,456,456,456,456,456,456,163,456,456,456,456,456,456,456, -456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, -456,456,456,456,456,456,456,456,456,456,456,456,456,163,447,447, -447,447,447,447,447,447,450,447,447,447,447,447,447,163,447,447, -448,448,448,448,448,461,461,461,461,448,448,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +505,505,508,508,509,497,499,499,495,495,495,495,495,505,505,505, +505,505,505,505,505,505,505,505,196,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,196,496,496, +496,496,496,496,496,496,499,496,496,496,496,496,496,196,496,496, +497,497,497,497,497,510,510,510,510,497,497,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 32 */ -462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, -462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, -462,462,462,462,462,462,462,462,462,462,462,463,463,464,464,464, -464,465,464,464,464,464,464,466,463,467,467,465,465,464,464,462, -468,468,468,468,468,468,468,468,468,468,469,469,470,470,470,470, -462,462,462,462,462,462,465,465,464,464,462,462,462,462,464,464, -464,462,463,471,471,462,462,463,463,471,471,471,471,471,462,462, -462,464,464,464,464,462,462,462,462,462,462,462,462,462,462,462, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,512,512,513,513,513, +513,514,513,513,513,513,513,515,512,516,516,514,514,513,513,511, +517,517,517,517,517,517,517,517,517,517,518,518,519,519,519,519, +511,511,511,511,511,511,514,514,513,513,511,511,511,511,513,513, +513,511,512,520,520,511,511,512,512,520,520,520,520,520,511,511, +511,513,513,513,513,511,511,511,511,511,511,511,511,511,511,511, /* block 33 */ -462,462,464,463,465,464,464,471,471,471,471,471,471,472,462,471, -473,473,473,473,473,473,473,473,473,473,471,471,463,464,474,474, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,163,475,163,163,163,163,163,475,163,163, -476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, -476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, -476,476,476,476,476,476,476,476,476,476,476,477,478,476,476,476, +511,511,513,512,514,513,513,520,520,520,520,520,520,521,511,520, +522,522,522,522,522,522,522,522,522,522,520,520,512,513,523,523, +524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, +524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, +524,524,524,524,524,524,196,524,196,196,196,196,196,524,196,196, +525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, +525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, +525,525,525,525,525,525,525,525,525,525,525,526,527,525,525,525, /* block 34 */ -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,480, -481,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,529, +530,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, /* block 35 */ -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,531,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, /* block 36 */ -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, -484,484,484,484,484,484,484,163,484,163,484,484,484,484,163,163, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,196,533,533,533,533,196,196, +533,533,533,533,533,533,533,196,533,196,533,533,533,533,196,196, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, /* block 37 */ -484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,163, -484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +533,533,533,533,533,533,533,533,533,196,533,533,533,533,196,196, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,196, +533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, /* block 38 */ -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,484,484,484,484,163,163,485,485,485, -486,487,488,487,487,487,487,488,488,489,489,489,489,489,489,489, -489,489,490,490,490,490,490,490,490,490,490,490,490,163,163,163, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,533,533,533,533,196,196,534,534,534, +535,536,537,536,536,536,536,537,537,538,538,538,538,538,538,538, +538,538,539,539,539,539,539,539,539,539,539,539,539,196,196,196, /* block 39 */ -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -491,491,491,491,491,491,491,491,491,491,163,163,163,163,163,163, -492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, -492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, -492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, -492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, -492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, -493,493,493,493,493,493,163,163,494,494,494,494,494,494,163,163, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +540,540,540,540,540,540,540,540,540,540,196,196,196,196,196,196, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +542,542,542,542,542,542,196,196,543,543,543,543,543,543,196,196, /* block 40 */ -495,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +544,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, /* block 41 */ -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, /* block 42 */ -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,497,498,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,546,547,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, /* block 43 */ -499,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, -500,500,500,500,500,500,500,500,500,500,500,501,502,163,163,163, -503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, -503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, -503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, -503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, -503,503,503,503,503,503,503,503,503,503,503,504,504,504,505,505, -505,503,503,503,503,503,503,503,503,163,163,163,163,163,163,163, +548,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549, +549,549,549,549,549,549,549,549,549,549,549,550,551,196,196,196, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,553,553,553,554,554, +554,552,552,552,552,552,552,552,552,196,196,196,196,196,196,196, /* block 44 */ -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, -506,506,507,507,508,509,163,163,163,163,163,163,163,163,163,506, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,511,511,512,513,513,163,163,163,163,163,163,163,163,163, -514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, -514,514,515,515,163,163,163,163,163,163,163,163,163,163,163,163, -516,516,516,516,516,516,516,516,516,516,516,516,516,163,516,516, -516,163,517,517,163,163,163,163,163,163,163,163,163,163,163,163, +555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555, +555,555,556,556,557,558,196,196,196,196,196,196,196,196,196,555, +559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, +559,559,560,560,561,562,562,196,196,196,196,196,196,196,196,196, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,564,564,196,196,196,196,196,196,196,196,196,196,196,196, +565,565,565,565,565,565,565,565,565,565,565,565,565,196,565,565, +565,196,566,566,196,196,196,196,196,196,196,196,196,196,196,196, /* block 45 */ -518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, -518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, -518,518,518,519,519,518,518,518,518,518,518,518,518,518,518,518, -518,518,518,518,520,520,521,522,522,522,522,522,522,522,521,521, -521,521,521,521,521,521,522,521,521,523,523,523,523,523,523,523, -523,523,524,523,525,525,525,526,527,527,525,528,518,523,163,163, -529,529,529,529,529,529,529,529,529,529,163,163,163,163,163,163, -530,530,530,530,530,530,530,530,530,530,163,163,163,163,163,163, +567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567, +567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567, +567,567,567,568,568,567,567,567,567,567,567,567,567,567,567,567, +567,567,567,567,569,569,570,571,571,571,571,571,571,571,570,570, +570,570,570,570,570,570,571,570,570,572,572,572,572,572,572,572, +572,572,573,572,574,574,575,576,577,577,575,578,567,572,196,196, +579,579,579,579,579,579,579,579,579,579,196,196,196,196,196,196, +580,580,580,580,580,580,580,580,580,580,196,196,196,196,196,196, /* block 46 */ -531,531,532,533,534,532,535,531,534,536,537,538,538,538,539,538, -540,540,540,540,540,540,540,540,540,540,163,163,163,163,163,163, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,542,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,163,163,163,163,163,163,163, +581,581,582,583,584,582,585,581,584,586,587,588,588,588,589,588, +590,590,590,590,590,590,590,590,590,590,196,196,196,196,196,196, +591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, +591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, +591,591,591,592,591,591,591,591,591,591,591,591,591,591,591,591, +591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, +591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, +591,591,591,591,591,591,591,591,591,196,196,196,196,196,196,196, /* block 47 */ -541,541,541,541,541,543,543,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,544,541,163,163,163,163,163, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,163,163,163,163,163,163,163,163,163,163, +591,591,591,591,591,593,593,591,591,591,591,591,591,591,591,591, +591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, +591,591,591,591,591,591,591,591,591,594,591,196,196,196,196,196, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,196,196,196,196,196,196,196,196,196,196, /* block 48 */ -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,163, -546,546,546,547,547,547,547,546,546,547,547,547,163,163,163,163, -547,547,546,547,547,547,547,547,547,548,548,548,163,163,163,163, -549,163,163,163,550,550,551,551,551,551,551,551,551,551,551,551, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,163,163, -552,552,552,552,552,163,163,163,163,163,163,163,163,163,163,163, +595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, +595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,196, +596,596,596,597,597,597,597,596,596,597,597,597,196,196,196,196, +597,597,596,597,597,597,597,597,597,598,598,598,196,196,196,196, +599,196,196,196,600,600,601,601,601,601,601,601,601,601,601,601, +602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602, +602,602,602,602,602,602,602,602,602,602,602,602,602,602,196,196, +602,602,602,602,602,196,196,196,196,196,196,196,196,196,196,196, /* block 49 */ -553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, -553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, -553,553,553,553,553,553,553,553,553,553,553,553,163,163,163,163, -553,553,553,553,553,554,554,554,553,553,554,553,553,553,553,553, -553,553,553,553,553,553,553,553,553,553,163,163,163,163,163,163, -555,555,555,555,555,555,555,555,555,555,556,163,163,163,557,557, -558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, -558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603, +603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603, +603,603,603,603,603,603,603,603,603,603,603,603,196,196,196,196, +603,603,603,603,603,604,604,604,603,603,604,603,603,603,603,603, +603,603,603,603,603,603,603,603,603,603,196,196,196,196,196,196, +605,605,605,605,605,605,605,605,605,605,606,196,196,196,607,607, +608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608, +608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608, /* block 50 */ -559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, -559,559,559,559,559,559,559,560,560,561,561,560,163,163,562,562, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,564,565,564,565,565,565,565,565,565,565,163, -566,567,565,567,567,565,565,565,565,565,565,565,565,564,564,564, -564,564,564,565,565,568,568,568,568,568,568,568,568,163,163,568, +609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609, +609,609,609,609,609,609,609,610,610,611,611,610,196,196,612,612, +613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613, +613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613, +613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613, +613,613,613,613,613,614,615,614,615,615,615,615,615,615,615,196, +616,617,615,617,617,615,615,615,615,615,615,615,615,614,614,614, +614,614,614,615,615,618,618,618,618,618,618,618,618,196,196,618, /* block 51 */ -569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, -569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, -570,570,570,570,570,570,570,571,572,572,572,572,570,570,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,573,574, -574,154,154,154,154,154,154,154,154,154,154,154,574,574,574,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +619,619,619,619,619,619,619,619,619,619,196,196,196,196,196,196, +619,619,619,619,619,619,619,619,619,619,196,196,196,196,196,196, +620,620,620,620,620,620,620,621,622,622,622,622,620,620,196,196, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,623,624, +624,176,176,176,176,176,176,176,176,176,176,176,624,624,624,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 52 */ -575,575,575,575,576,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,578,579,575,575,575,575,575,576,575,576,576,576, -576,576,575,576,580,577,577,577,577,577,577,577,577,163,163,163, -581,581,581,581,581,581,581,581,581,581,582,582,583,584,582,582, -583,585,585,585,585,585,585,585,585,585,585,578,578,578,578,578, -578,578,578,578,585,585,585,585,585,585,585,585,585,582,582,163, +625,625,625,625,626,627,627,627,627,627,627,627,627,627,627,627, +627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, +627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, +627,627,627,627,628,629,625,625,625,625,625,629,625,629,626,626, +626,626,625,629,630,627,627,627,627,627,627,627,627,196,631,631, +632,632,632,632,632,632,632,632,632,632,631,631,633,634,631,631, +633,635,635,635,635,635,635,635,635,635,635,628,628,628,628,628, +628,628,628,628,635,635,635,635,635,635,635,635,635,631,631,631, /* block 53 */ -586,586,587,588,588,588,588,588,588,588,588,588,588,588,588,588, -588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588, -588,587,586,586,586,586,587,587,586,586,589,590,586,586,588,588, -591,591,591,591,591,591,591,591,591,591,588,588,588,588,588,588, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,593,594,595,595,594,594,594,595,594,595, -595,595,596,596,163,163,163,163,163,163,163,163,597,597,597,597, +636,636,637,638,638,638,638,638,638,638,638,638,638,638,638,638, +638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638, +638,637,636,636,636,636,637,637,636,636,639,640,636,636,638,638, +641,641,641,641,641,641,641,641,641,641,638,638,638,638,638,638, +642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642, +642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642, +642,642,642,642,642,642,643,644,645,645,644,644,644,645,644,645, +645,645,646,646,196,196,196,196,196,196,196,196,647,647,647,647, /* block 54 */ -598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, -598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, -598,598,598,598,599,599,599,599,599,599,599,599,600,600,600,600, -600,600,600,600,599,599,601,602,163,163,163,603,603,604,604,604, -605,605,605,605,605,605,605,605,605,605,163,163,163,598,598,598, -606,606,606,606,606,606,606,606,606,606,607,607,607,607,607,607, -607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607, -607,607,607,607,607,607,607,607,608,608,608,609,608,608,610,610, +648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, +648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, +648,648,648,648,649,649,649,649,649,649,649,649,650,650,650,650, +650,650,650,650,649,649,651,652,196,196,196,653,653,654,654,654, +655,655,655,655,655,655,655,655,655,655,196,196,196,648,648,648, +656,656,656,656,656,656,656,656,656,656,657,657,657,657,657,657, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +657,657,657,657,657,657,657,657,658,658,658,659,658,658,660,660, /* block 55 */ -611,612,613,614,615,616,617,618,619,163,163,163,163,163,163,163, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,620,620,620,620,620,620,163,163,620,620,620, -621,621,621,621,621,621,621,621,163,163,163,163,163,163,163,163, -622,623,622,624,623,625,625,626,625,626,627,623,626,626,623,623, -626,628,623,623,623,623,623,623,623,629,630,631,631,625,631,631, -631,631,632,633,634,630,630,635,636,636,637,163,163,163,163,163, +661,662,663,664,665,666,667,668,669,275,276,196,196,196,196,196, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,196,196,670,670,670, +671,671,671,671,671,671,671,671,196,196,196,196,196,196,196,196, +672,673,672,674,673,675,675,676,675,676,677,673,676,676,673,673, +676,678,673,673,673,673,673,673,673,679,680,681,681,675,681,681, +681,681,682,683,684,680,680,685,686,686,687,196,196,196,196,196, /* block 56 */ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70,221,221,221,221,221,638,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,639,639,639, -639,639,148,147,147,147,639,639,639,639,639, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70,640,641, 70, 70, 70,642, 70, 70, + 70, 70, 70, 70, 70, 70,256,256,256,256,256,688,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,689,689,689, +689,689,150,149,149,149,689,689,689,689,689, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70,690,691, 70, 70, 70,692, 70, 70, /* block 57 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,643, 70, - 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,645,645,645,645,645, -645,645,645,645,646,645,645,645,646,645,645,645,645,645,645,645, -645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,647, -648,648,158,158,154,154,154,154,154,154,154,154,154,154,154,154, -158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, -158,158,158,158,158,158,158,574,574,574,574,574,574,574,574,574, -574,574,574,574,574,154,154,154,649,154,650,154,154,154,154,154, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,693, 70, + 70, 70, 70, 70, 70, 70,694, 70, 70, 70, 70,695,695,695,695,695, +695,695,695,695,696,695,695,695,696,695,695,695,695,695,695,695, +695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,697, +698,698,189,189,176,176,176,176,176,176,176,176,176,176,176,176, +189,189,189,624,624,624,624,624,624,624,624,624,624,624,624,624, +624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624, +624,624,624,624,624,176,176,176,699,176,700,176,176,176,176,176, /* block 58 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, @@ -2986,12 +3230,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -651,652, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, +701,702, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 59 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,653,654, 70, 70,655, 70, + 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,703,704, 70, 70,705, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66, 65, 66, @@ -3000,123 +3244,123 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 60 */ -656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, -656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, -656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, -656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, -656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, -173,656,173,656,173,656,173,656,163,657,163,657,163,657,163,657, -656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, -658,658,659,659,659,659,660,660,661,661,662,662,663,663,163,163, +706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, +706,706,706,706,706,706,196,196,707,707,707,707,707,707,196,196, +706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, +706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, +706,706,706,706,706,706,196,196,707,707,707,707,707,707,196,196, +708,706,708,706,708,706,708,706,196,707,196,707,196,707,196,707, +706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, +709,709,710,710,710,710,711,711,712,712,713,713,714,714,196,196, /* block 61 */ -664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, -664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, -664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, -656,656,666,667,666,163,173,666,657,657,668,668,669,162,670,162, -162,162,666,667,666,163,173,666,671,671,671,671,669,162,162,162, -656,656,173,173,163,163,173,173,657,657,672,672,163,162,162,162, -656,656,173,173,173,215,173,173,657,657,673,673,220,162,162,162, -163,163,666,667,666,163,173,666,674,674,675,675,669,162,162,163, +715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716, +715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716, +715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716, +706,706,717,718,717,196,708,717,707,707,719,719,720,201,721,201, +201,201,717,718,717,196,708,717,722,722,722,722,720,201,201,201, +706,706,708,723,196,196,708,708,707,707,724,724,196,201,201,201, +706,706,708,725,708,250,708,708,707,707,726,726,255,201,201,201, +196,196,717,718,717,196,708,717,727,727,728,728,720,201,201,196, /* block 62 */ -676,676,676,676,676,676,676,676,676,676,676, 51,677,678,679,680, -681,681,681,681,681,681,682, 43,683,684,685,686,686,687,685,686, - 43, 43, 43, 43,688, 43, 43,688,689,690,691,692,693,694,695,696, -697,697,698,698,698, 43, 43, 43, 43, 49, 57, 43,699,700, 43,701, -702, 43, 43, 43,703,704,705,700,700,699, 43, 43, 43, 43, 43, 43, - 43, 43, 50,706,701, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,676, - 51,707,707,707,707,708,709,710,711,712,713,713,713,713,713,713, - 54,646,163,163, 54, 54, 54, 54, 54, 54,714,715,716,717,718,645, +729,729,729,729,729,729,729,729,729,729,729, 51,730,731,732,733, +734,734,734,734,734,734,735, 43,736,737,738,739,739,740,738,739, + 43, 43, 43, 43,741, 43, 43,742,743,744,745,746,747,748,749,750, +751,751,752,752,752, 43, 43, 43, 43, 49, 57, 43,753,754, 43,755, +756, 43, 43, 43,757,758,759,754,754,753, 43, 43, 43, 43, 43,760, + 43, 43, 50,761,755, 43, 43, 43, 43, 43,762, 43, 43,763, 43,729, + 51,764,764,764,764,765,766,767,768,769,770,770,770,770,770,770, + 54,696,196,196, 54, 54, 54, 54, 54, 54,771,772,773,774,775,695, /* block 63 */ - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,714,715,716,717,718,163, -645,645,645,645,645,645,645,645,645,645,645,645,645,163,163,163, -430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, -430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, -430,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719, -720,720,720,720,720,720,720,720,720,720,720,720,720,721,721,721, -721,720,721,722,721,720,720,158,158,158,158,720,720,720,720,720, -723,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,771,772,773,774,775,196, +695,695,695,695,695,695,695,695,695,695,695,695,695,196,196,196, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776, +777,777,777,777,777,777,777,777,777,777,777,777,777,778,778,778, +778,777,778,779,778,777,777,189,189,189,189,777,777,777,777,777, +780,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 64 */ -724,724,725,724,724,724,724,725,724,724,726,725,725,725,726,726, -725,725,725,726,724,725,724,724,727,725,725,725,725,725,724,724, -724,724,728,724,725,724,729,724,725,730,731,732,725,725,733,726, -725,725,734,725,726,735,735,735,735,736,724,724,726,726,725,725, -716,716,716,716,716,725,726,726,737,737,724,716,724,724,738,461, +781,781,782,781,781,781,781,782,781,781,783,782,782,782,783,783, +782,782,782,783,781,782,781,781,784,782,782,782,782,782,781,781, +781,781,785,781,782,781,786,781,782,787,788,789,782,782,790,783, +782,782,791,782,783,792,792,792,792,793,781,781,783,783,782,782, +794,794,794,794,794,782,783,783,795,795,781,794,781,781,796,510, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739, -740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, +797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797, +798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798, /* block 65 */ -741,741,741, 65, 66,741,741,741,741, 58,724,724,163,163,163,163, - 50, 50, 50, 50,742,743,743,743,743,743, 50, 50,744,744,744,744, - 50,744,744, 50,744,744, 50,744, 45,743,743,744,744,744, 50, 45, -744,744, 45, 45, 45, 45,744,744, 45, 45, 45, 45,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, -744,744, 50,744, 50,744,744,744,744,744,744,744, 45,744, 45, 45, - 45, 45, 45, 45,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +799,799,799, 65, 66,799,799,799,799, 58,781,781,196,196,196,196, + 50, 50, 50, 50,800,801,801,801,801,801, 50, 50,802,802,802,802, + 50,802,802, 50,802,802, 50,802, 45,801,801,802,802,802, 50, 45, +802,802, 45, 45, 45, 45,802,802, 45, 45, 45, 45,802,802,802,802, +802,802,802,802,802,802,802,802,802,802,802,802,802,802, 50, 50, +802,802, 50,802, 50,802,802,802,802,802,802,802, 45,802, 45, 45, + 45, 45, 45, 45,802,802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 66 */ - 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745, 50, 50, - 50, 50,746, 53, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, -745,745,745, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, - 50, 50, 50,745, 50,745, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, - 50, 50,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,745,745,745,745,745,745,745,745, 50, 50,745,745, -745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, + 50, 50,803, 50, 50, 50, 50,803,804,804,804,804,804,804, 50, 50, + 50, 50,805, 53, 50,804, 50, 50, 50, 50, 50, 50, 50, 50,803,804, +804,804,804, 50,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804, 50, 50, + 50, 50, 50,804, 50,804, 50, 50, 50, 50, 50, 50,804, 50, 50, 50, + 50, 50,804,804,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,804,804,804,804,804,804,804,804, 50, 50,804,804, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, /* block 67 */ -745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, 50,745, -745,745,745, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, - 50, 50,745,745, 50, 50,745, 50,745,745, 50,745, 50, 50, 50, 50, -745,745,745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745, 50, 50, -745,745, 50, 50, 50, 50,745,745,745,745,745,745,745,745,745,745, -745,745,745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, -745,745,745,745,745, 50,745,745, 50, 50,745,745,745,745,745, 50, +804,804,804,804,804,804,804,804,804,804,804,804, 50, 50, 50,804, +804,804,804, 50, 50, 50, 50, 50,804, 50, 50, 50, 50, 50, 50, 50, + 50, 50,804,804, 50, 50,804, 50,804,804, 50,804, 50, 50, 50, 50, +804,804,804,804,804,804,804,804,804, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804,804, 50, 50, +804,804, 50, 50, 50, 50,804,804,804,804,804,804,804,804,804,804, +804,804,804,804,804,804,804,804,804,804,804,804,804,804, 50, 50, +804,804,804,804,804, 50,804,804, 50, 50,804,804,804,804,804, 50, /* block 68 */ - 45, 45, 45, 45, 45, 45, 45, 45,747,748,747,748, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, 45, - 50, 50, 45, 45, 45, 45, 45, 45, 47,750,751, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,752,752,752,752,752,752,752,752,752,752, -752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, -752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, -752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, -752,752,752,752,752,752,752,752,752,752,752, 45, 50, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45,806,807,806,807, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808,808, 45, 45, 45, 45, + 50, 50, 45, 45, 45, 45, 45, 45, 47,809,810, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,811,811,811,811,811,811,811,811,811,811, +811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811, +811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811, +811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811, +811,811,811,811,811,811,811,811,811,811,811, 45, 50, 45, 45, 45, /* block 69 */ - 45, 45, 45, 45, 45, 45, 45, 45,753, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45,752, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, + 45, 45, 45, 45, 45, 45, 45, 45,812, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45,811, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,744,744, 45,744, 45, 45, 45, 45, 45, 45, 45, 45, + 50, 50, 50, 50,802,802, 45,802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, -744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, - 50, 50,744, 45, 45, 45, 45, 45, 45,749,749,749,749, 47, 47, 47, -749, 47, 47,749, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, +802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, + 50, 50,802, 45, 45, 45, 45, 45, 45,808,808,808,808, 47, 47, 47, +808, 47, 47,808, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, /* block 70 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754,754,754,754,754, -754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754, -754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,813,813,813,813,813,813, +813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,813,813,813,813,813, +813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 71 */ - 58, 58, 58, 58, 58, 58, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,755,755,755,755,755,755,755,755,755,755, -755,755,756,755,755,755,755,755,755,755,755,755,755,755,755,755, -757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, -757,757,757,757,757,757,757,757,757,757, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58,814,814,814,814,814,814,814,814, +814,814,814,814,814,814,814,814,814,814,814,814,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,815,815,815,815,815,815,815,815,815,815, +815,815,816,815,815,815,815,815,815,815,815,815,815,815,815,815, +817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817, +817,817,817,817,817,817,817,817,817,817, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 72 */ @@ -3132,2322 +3376,2422 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ /* block 73 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -744,744, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,744,744, -744,744,744,744,744,744,743, 50, 45, 45, 45, 45,744,744,744,744, -743, 50, 45, 45, 45, 45,744,744, 45, 45,744,744, 45, 45, 45,744, -744,744,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45,744, 45,744, 45, 45,744,744,744,744,744,744, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,742,742,758,758, 50, +802,802, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,802,802, +802,802,802,802,802,802,801, 50, 45, 45, 45, 45,802,802,802,802, +801, 50, 45, 45, 45, 45,802,802, 45, 45,802,802, 45, 45, 45,802, +802,802,802,802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45,802, 45,802, 45, 45,802,802,802,802,802,802, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,800,800,818,818, 50, /* block 74 */ - 47, 47, 47, 47, 47,759,744,753,753,753,753,753,753,753, 47,753, -753, 47,753, 45,749,749,753,753, 47,753,753,753,753,760,753,753, - 47,753, 47, 47,753,753, 47,753,753,753, 47,753,753,753, 47, 47, -753,753,753,753,753,753,753,753, 47, 47, 47,753,753,753,753,753, -743,753,743,753,753,753,753,753,749,749,749,749,749,749,749,749, -749,749,749,749,753,753,753,753,753,753,753,753,753,753,753, 47, -743,759,759,743,753, 47, 47,753, 47,753,753,753,753,759,759,761, -753,753,753,753,753,753,753,753,753,753,753, 47,753,753, 47,749, + 47, 47, 47, 47, 47,819,802,812,812,812,812,812,812,812, 47,812, +812, 47,812, 45,808,808,812,812, 47,812,812,812,812,820,812,812, + 47,812, 47, 47,812,812, 47,812,812,812, 47,812,812,812, 47, 47, +812,812,812,812,812,812,812,812, 47, 47, 47,812,812,812,812,812, +801,812,801,812,812,812,812,812,808,808,808,808,808,808,808,808, +808,808,808,808,812,812,812,812,812,812,812,812,812,812,812, 47, +801,819,819,801,812, 47, 47,812, 47,812,812,812,812,819,819,821, +812,812,812,812,812,812,812,812,812,812,812, 47,812,812, 47,808, /* block 75 */ -753,753,753,753,753,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -753,753, 47,749, 47, 47, 47, 47,753, 47,753, 47, 47,753,753,753, - 47,749,753,753,753,753,753, 47,753,753,749,749,762,753,753,753, - 47, 47,753,753,753,753,753,753,753,753,753,753,753,749,749,753, -753,753,753,753,749,749,753,753, 47,753,753,753,753,753,749, 47, -753, 47,753, 47,749,753,753,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753, 47,749,753,753,753,753,753, - 47, 47,749,749, 47,749,753, 47, 47,760,749,753,753,749,753,753, +812,812,812,812,812,812, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +812,812, 47,808, 47, 47, 47, 47,812, 47,812, 47, 47,812,812,812, + 47,808,812,812,812,812,812, 47,812,812,808,808,822,812,812,812, + 47, 47,812,812,812,812,812,812,812,812,812,812,812,808,808,812, +812,812,812,812,808,808,812,812, 47,812,812,812,812,812,808, 47, +812, 47,812, 47,808,812,812,812,812,812,812,812,812,812,812,812, +812,812,812,812,812,812,812,812,812, 47,808,812,812,812,812,812, + 47, 47,808,808, 47,808,812, 47, 47,820,808,812,812,808,812,812, /* block 76 */ -753,753, 47,753,753,749, 45, 45, 47, 47,763,763,760,760,753, 47, -753,753, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, - 45, 47, 45, 45, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, +812,812, 47,812,812,808, 45, 45, 47, 47,823,823,820,820,812, 47, +812,812, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, + 45, 47, 45, 45, 45, 45, 45, 45,808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,749, 45,749, 45, - 45, 45, 45,749,749,749, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 47, 47,753,753,753,704,705,704,705,704,705,704,705, -704,705,704,705,704,705, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,808, 45,808, 45, + 45, 45, 45,808,808,808, 45,808, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 47, 47,812,812,812,758,759,758,759,758,759,758,759, +758,759,758,759,758,759, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 77 */ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 45,749,749,749, 45, 45, 45, 45, 45, 45, 45, 45, + 58, 58, 58, 58, 45,808,808,808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749, - 50, 50, 50,745,745,747,748, 50,745,745, 50,745, 50,745, 50, 50, - 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50,745,745,745, 50, - 50, 50,745,745,745,745,747,748,747,748,747,748,747,748,747,748, +808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808, + 50, 50, 50,804,804,806,807, 50,804,804, 50,804, 50,804, 50, 50, + 50, 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50,804,804,804, 50, + 50, 50,804,804,804,804,806,807,806,807,806,807,806,807,806,807, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 78 */ -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, /* block 79 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,742,742, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,800,800, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 80 */ - 50, 50, 50,747,748,747,748,747,748,747,748,747,748,747,748,747, -748,747,748,747,748,747,748,747,748, 50, 50,745, 50, 50, 50, 50, -745, 50, 50,745,745,745, 50, 50,745,745,745,745,745,745,745,745, - 50, 50, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, -745,745, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, -745,745,745, 50,745,745, 50, 50,747,748,747,748, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50,745, 50, 50,745,745, 50, 50,747,748, 50, 50, + 50, 50, 50,806,807,806,807,806,807,806,807,806,807,806,807,806, +807,806,807,806,807,806,807,806,807, 50, 50,804, 50, 50, 50, 50, +804, 50, 50,804,804,804, 50, 50,804,804,804,804,804,804,804,804, + 50, 50, 50, 50, 50, 50, 50, 50,804, 50, 50, 50, 50, 50, 50, 50, +804,804, 50, 50,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50,804, +804,804,804, 50,804,804, 50, 50,806,807,806,807, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50,804, 50, 50,804,804, 50, 50,806,807, 50, 50, /* block 81 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, - 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50,745,745, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804, 50, + 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745,745, + 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804,804,804,804, /* block 82 */ -745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, -745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, -745,745,745, 50, 50, 50,745,745,745,745,745,745,745,745, 50,745, -745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, -745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, -745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50,745, 50, - 50, 50, 50,745,745,745, 50, 50, 50, 50, 50, 50,745,745,745, 50, - 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, 50, 50, 50, 50, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +804,804,804, 50, 50, 50,804,804,804,804,804,804,804,804, 50,804, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +804,804,804,804,804,804,804, 50, 50, 50, 50, 50, 50, 50,804, 50, + 50, 50, 50,804,804,804, 50, 50, 50, 50, 50, 50,804,804,804, 50, + 50, 50, 50, 50, 50, 50, 50,804,804,804,804, 50, 50, 50, 50, 50, /* block 83 */ 45, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808,808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 45, 45, 50, 50, 50, 50, 50, 50, 45, 45, 45, -749, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +808, 45, 45, 45, 45,808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45,754,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45,813,813, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, /* block 84 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,813, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,765, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,825, 45, /* block 85 */ -766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, -766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, -766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, -767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, -767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, -767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, - 65, 66,768,769,770,771,772, 65, 66, 65, 66, 65, 66,773,774,775, -776, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,646,645,777,777, +826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826, +826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826, +826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826, +827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827, +827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827, +827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827, + 65, 66,828,829,830,831,832, 65, 66, 65, 66, 65, 66,833,834,835, +836, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,696,695,837,837, /* block 86 */ -211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,778,779,779,779,779,779,779,211,212,211,212,780, -780,780,211,212,163,163,163,163,163,781,781,781,781,782,781,781, +246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, +246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, +246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, +246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, +246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, +246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, +246,247,246,247,838,839,839,839,839,839,839,246,247,246,247,840, +840,840,246,247,196,196,196,196,196,841,841,841,842,843,842,842, /* block 87 */ -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,163,783,163,163,163,163,163,783,163,163, -784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, -784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, -784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, -784,784,784,784,784,784,784,784,163,163,163,163,163,163,163,785, -786,163,163,163,163,163,163,163,163,163,163,163,163,163,163,787, +844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844, +844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844, +844,844,844,844,844,844,196,844,196,196,196,196,196,844,196,196, +845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, +845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, +845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, +845,845,845,845,845,845,845,845,196,196,196,196,196,196,196,846, +847,196,196,196,196,196,196,196,196,196,196,196,196,196,196,848, /* block 88 */ -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, -484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, -484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, -484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, -484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, -788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, -788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +533,533,533,533,533,533,533,196,196,196,196,196,196,196,196,196, +533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, +533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, +533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, +533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, +849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, +849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, /* block 89 */ - 43, 43,789,790,789,790, 43, 43, 43,789,790, 43,789,790, 43, 43, - 43, 43, 43, 43, 43, 43, 43,681, 43, 43,681, 43,789,790, 43, 43, -789,790,704,705,704,705,704,705,704,705, 43, 43, 43, 43,700,791, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,681,681,700, 43, 43, 43, -681,792,685,793, 43, 43, 43, 43, 43, 43, 43, 43,792, 43,792,792, - 45, 45, 43,700,700,704,705,704,705,704,705,704,705,681,754,754, -754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, -754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, + 43, 43,850,851,850,851, 43, 43, 43,850,851, 43,850,851, 43, 43, + 43, 43, 43, 43, 43, 43, 43,852, 43, 43,734, 43,850,851, 43, 43, +850,851,758,759,758,759,758,759,758,759, 43, 43, 43, 43,754,853, +854,855, 43, 43, 43, 43, 43, 43, 43, 43,734,734,856, 43, 43, 43, +734,857,738,858, 43, 43, 43, 43, 43, 43, 43, 43,859, 43,859,859, + 45, 45, 43,754,754,758,759,758,759,758,759,758,759,734,813,813, +813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, +813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, /* block 90 */ -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,163,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,163,163,163,163,163,163,163,163,163,163,163,163, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,196,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,196,196,196,196,196,196,196,196,196,196,196,196, /* block 91 */ -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, /* block 92 */ -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, -794,794,794,794,794,794,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -795,795,796,796,795,795,795,795,795,795,795,795,163,163,163,163, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +860,860,860,860,860,860,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +861,861,862,862,861,861,861,861,861,861,861,861,861,861,863,863, /* block 93 */ -676,797,798,799,724,800,801,802,803,804,803,804,805,806,805,806, -803,804, 45,807,803,804,803,804,803,804,803,804,808,809,810,810, - 45,802,802,802,802,802,802,802,802,802,811,811,811,811,812,812, -813,814,814,814,814,814,724,815,802,802,802,816,817,818,819,819, -163,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +729,864,865,866,781,867,868,869,870,871,872,873,874,875,874,875, +876,877, 45,878,876,877,876,877,876,877,876,877,879,880,881,881, + 45,869,869,869,869,869,869,869,869,869,882,882,882,882,883,883, +884,885,885,885,885,885,781,886,869,869,869,887,888,889,890,890, +196,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, /* block 94 */ -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,163,163,821,821,822,822,823,823,820, -824,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, -825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, -825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, -825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, -825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, -825,825,825,825,825,825,825,825,825,825,825,826,827,828,828,825, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,196,196,892,892,893,893,894,894,891, +895,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,897,898,899,899,896, /* block 95 */ -163,163,163,163,163,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -163,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, -830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, -830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, -830,830,830,830,831,830,830,830,830,830,830,830,830,830,830,830, -830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +196,196,196,196,196,900,900,900,900,900,900,900,900,900,900,900, +900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, +900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, +196,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,902,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, /* block 96 */ -830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, -832,832,833,833,833,833,832,832,832,832,832,832,832,832,832,832, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,163,163,163,163,163,163,163,163,163,163,163,163, -825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,196, +903,903,904,904,904,904,903,903,903,903,903,903,903,903,903,903, +900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, +900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, +890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,890, +890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,890, +890,890,890,890,890,890,196,196,196,196,196,196,196,196,196,861, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, /* block 97 */ -834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, -834,834,834,834,834,834,834,834,834,834,834,834,834,835,835,163, -833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, -832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, -832,832,832,832,832,832,832,832,836,836,836,836,836,836,836,836, -724, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, -834,834,834,834,834,834,834,834,834,834,834,834,835,835,835,461, +905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, +905,905,905,905,905,905,905,905,905,905,905,905,905,906,906,196, +904,904,904,904,904,904,904,904,904,904,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,907,907,907,907,907,907,907,907, +781, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, +905,905,905,905,905,905,905,905,905,905,905,905,906,906,906,510, /* block 98 */ -833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, -832,832,832,832,832,832,832,837,832,837,832,832,832,832,832,832, -832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, -832, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -832,832,832,832,832,832,832,832,832,832,832,832,724,724,724,724, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,832, +904,904,904,904,904,904,904,904,904,904,903,903,903,903,903,903, +903,903,903,903,903,903,903,908,903,908,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +903,903,903,903,903,903,903,903,903,903,903,903,781,781,781,781, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,903, /* block 99 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,832,832,832,832,832,832,832,832, -832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, -832,461,461,461,461,461,461,724,724,724,724,832,832,832,832,832, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, +909,909,909,909,909,909,909,909,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,510,510,510,510,510,510,781,781,781,781,903,903,903,903,903, /* block 100 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,724,724, -832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, -832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,724, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,781,781, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,781, /* block 101 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, /* block 102 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, /* block 103 */ -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,841,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,912,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, /* block 104 */ -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, /* block 105 */ -840,840,840,840,840,840,840,840,840,840,840,840,840,163,163,163, -842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, -842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, -842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, -842,842,842,842,842,842,842,163,163,163,163,163,163,163,163,163, -843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, -843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, -843,843,843,843,843,843,843,843,844,844,844,844,844,844,845,846, +911,911,911,911,911,911,911,911,911,911,911,911,911,196,196,196, +913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, +913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, +913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, +913,913,913,913,913,913,913,196,196,196,196,196,196,196,196,196, +914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914, +914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914, +914,914,914,914,914,914,914,914,915,915,915,915,915,915,916,917, /* block 106 */ -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, /* block 107 */ -847,847,847,847,847,847,847,847,847,847,847,847,848,849,850,850, -847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, -851,851,851,851,851,851,851,851,851,851,847,847,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -240,241,240,241,240,241,240,241,240,241,852,853,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,854,246, -248,248,248,855,788,788,788,788,788,788,788,788,856,856,855,857, +918,918,918,918,918,918,918,918,918,918,918,918,919,920,921,921, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +922,922,922,922,922,922,922,922,922,922,918,918,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +275,276,275,276,275,276,275,276,275,276,923,924,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,925,281, +283,283,283,926,849,849,849,849,849,849,849,849,927,927,926,928, /* block 108 */ -240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,858,858,788,788, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,860,860,860,860,860,860,860,860,860,860, -861,861,862,863,864,864,864,863,163,163,163,163,163,163,163,163, +275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +275,276,275,276,275,276,275,276,275,276,275,276,929,929,849,849, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,931,931,931,931,931,931,931,931,931,931, +932,932,933,934,935,935,935,934,196,196,196,196,196,196,196,196, /* block 109 */ -865,865,865,865,865,865,865,865, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149, +936,936,936,936,936,936,936,936, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46,151,151,151,151,151,151,151,151,151, 46, 46, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 70, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -645, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,866, 65, 66, +695, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,937, 65, 66, /* block 110 */ - 65, 66, 65, 66, 65, 66, 65, 66,149,867,867, 65, 66,868, 70, 92, - 65, 66, 65, 66,869, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,870,871,872,873,870, 70, -874,875,876,877, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66,878,879,880, 65, 66, 65, 66,163,163,163,163,163, - 65, 66,163, 70,163, 70, 65, 66, 65, 66,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,645,645,645, 65, 66, 92,147,147, 70, 92, 92, 92, 92, 92, + 65, 66, 65, 66, 65, 66, 65, 66,151,938,938, 65, 66,939, 70, 93, + 65, 66, 65, 66,940, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,941,942,943,944,941, 70, +945,946,947,948, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66,949,950,951, 65, 66, 65, 66,952, 65, 66,196,196, + 65, 66,196, 70,196, 70, 65, 66, 65, 66, 65, 66,953,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,695,695,695, 65, 66, 93,149,149, 70, 93, 93, 93, 93, 93, /* block 111 */ -881,881,882,881,881,881,883,881,881,881,881,882,881,881,881,881, -881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881, -881,881,881,884,884,882,882,884,885,885,885,885,883,163,163,163, -886,886,886,887,887,887,888,888,889,890,163,163,163,163,163,163, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,892,892,893,893,163,163,163,163,163,163,163,163, +954,954,955,954,954,954,956,954,954,954,954,955,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,957,957,955,955,957,958,958,958,958,956,196,196,196, +959,959,959,960,960,960,961,961,962,963,196,196,196,196,196,196, +964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, +964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, +964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, +964,964,964,964,965,965,966,966,196,196,196,196,196,196,196,196, /* block 112 */ -894,894,895,895,895,895,895,895,895,895,895,895,895,895,895,895, -895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, -895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, -895,895,895,895,894,894,894,894,894,894,894,894,894,894,894,894, -894,894,894,894,896,897,163,163,163,163,163,163,163,163,898,898, -899,899,899,899,899,899,899,899,899,899,163,163,163,163,163,163, -336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336, -336,900,335,901,335,335,335,335,343,343,343,335,343,335,335,333, +967,967,968,968,968,968,968,968,968,968,968,968,968,968,968,968, +968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,968, +968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,968, +968,968,968,968,967,967,967,967,967,967,967,967,967,967,967,967, +967,967,967,967,969,970,196,196,196,196,196,196,196,196,971,971, +972,972,972,972,972,972,972,972,972,972,196,196,196,196,196,196, +378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, +378,973,376,974,376,376,376,376,385,385,385,376,385,376,376,374, /* block 113 */ -902,902,902,902,902,902,902,902,902,902,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,904,904,904,904,904,905,905,905,906,907, -908,908,908,908,908,908,908,908,908,908,908,908,908,908,908,908, -908,908,908,908,908,908,908,909,909,909,909,909,909,909,909,909, -909,909,910,911,163,163,163,163,163,163,163,163,163,163,163,912, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,163,163,163, +975,975,975,975,975,975,975,975,975,975,976,976,976,976,976,976, +976,976,976,976,976,976,976,976,976,976,976,976,976,976,976,976, +976,976,976,976,976,976,977,977,977,977,977,978,978,978,979,980, +981,981,981,981,981,981,981,981,981,981,981,981,981,981,981,981, +981,981,981,981,981,981,981,982,982,982,982,982,982,982,982,982, +982,982,983,984,196,196,196,196,196,196,196,196,196,196,196,985, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,196,196,196, /* block 114 */ -913,913,913,914,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,916,914,914,913,913,913,913,914,914,913,913,914,914, -917,918,918,918,918,918,918,919,920,920,918,918,918,918,163,921, -922,922,922,922,922,922,922,922,922,922,163,163,163,163,918,918, -462,462,462,462,462,472,923,462,462,462,462,462,462,462,462,462, -473,473,473,473,473,473,473,473,473,473,462,462,462,462,462,163, +986,986,986,987,988,988,988,988,988,988,988,988,988,988,988,988, +988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,988, +988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,988, +988,988,988,989,987,987,986,986,986,986,987,987,986,986,987,987, +990,991,991,991,991,991,991,992,993,993,991,991,991,991,196,994, +995,995,995,995,995,995,995,995,995,995,196,196,196,196,991,991, +511,511,511,511,511,521,996,511,511,511,511,511,511,511,511,511, +522,522,522,522,522,522,522,522,522,522,511,511,511,511,511,196, /* block 115 */ -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,925,925,925,925,925,925,926, -926,925,925,926,926,925,925,163,163,163,163,163,163,163,163,163, -924,924,924,925,924,924,924,924,924,924,924,924,925,926,163,163, -927,927,927,927,927,927,927,927,927,927,163,163,928,929,929,929, -462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, -923,462,462,462,462,462,462,474,474,474,462,471,472,471,462,462, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,998,998,998,998,998,998,999, +999,998,998,999,999,998,998,196,196,196,196,196,196,196,196,196, +997,997,997,998,997,997,997,997,997,997,997,997,998,999,196,196, +1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,196,196,1001,1002,1002,1002, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +996,511,511,511,511,511,511,523,523,523,511,520,521,520,511,511, /* block 116 */ -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -931,930,931,931,931,932,932,931,931,932,930,932,932,930,931,933, -934,933,934,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,930,930,935,936,937, -938,938,938,938,938,938,938,938,938,938,938,939,940,940,939,939, -941,941,938,942,942,939,943,163,163,163,163,163,163,163,163,163, +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, +1004,1003,1004,1004,1004,1005,1005,1004,1004,1005,1003,1005,1005,1003,1004,1006, +1007,1006,1007,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,1003,1003,1008,1009,1010, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1012,1013,1013,1012,1012, +1014,1014,1011,1015,1015,1012,1016,196,196,196,196,196,196,196,196,196, /* block 117 */ -163,484,484,484,484,484,484,163,163,484,484,484,484,484,484,163, -163,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, -484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +196,533,533,533,533,533,533,196,196,533,533,533,533,533,533,196, +196,533,533,533,533,533,533,196,196,196,196,196,196,196,196,196, +533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,944, 70, 70, 70, 70, 70, 70, 70,867,147,147,147,147, - 70, 70, 70, 70, 70,221, 70, 70, 70,147, 46, 46,163,163,163,163, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, + 70, 70, 70,1017, 70, 70, 70, 70, 70, 70, 70,938,149,149,149,149, + 70, 70, 70, 70, 70,256, 70, 70, 70,149, 46, 46,196,196,196,196, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, /* block 118 */ -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, -938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, -938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, -938,938,938,939,939,940,939,939,940,939,939,941,946,943,163,163, -947,947,947,947,947,947,947,947,947,947,163,163,163,163,163,163, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1012,1012,1013,1012,1012,1013,1012,1012,1014,1019,1016,196,196, +1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,196,196,196,196,196,196, /* block 119 */ -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, /* block 120 */ -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, /* block 121 */ -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, /* block 122 */ -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, /* block 123 */ -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, /* block 124 */ -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, /* block 125 */ -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, /* block 126 */ -949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, -949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, -949,949,949,949,163,163,163,163,163,163,163,163,163,163,163,163, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,163,163,163,163,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,163,163,163,163, +1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +1022,1022,1022,1022,196,196,196,196,196,196,196,196,196,196,196,196, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,196,196,196,196,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,196,196,196,196, /* block 127 */ -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, /* block 128 */ -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, /* block 129 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, /* block 130 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,839,839, -952,839,952,839,839,952,952,952,952,952,952,952,952,952,952,839, -952,839,952,839,839,952,952,839,839,839,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,910,910, +1025,910,1025,910,910,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,910, +1025,910,1025,910,910,1025,1025,910,910,910,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, /* block 131 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 132 */ -653,653,653,653,653,653,653,163,163,163,163,163,163,163,163,163, -163,163,163,257,257,257,257,257,163,163,163,163,163,270,265,270, -270,270,270,270,270,270,270,270,270,953,270,270,270,270,270,270, -270,270,270,270,270,270,270,262,270,270,270,270,270,262,270,262, -270,270,262,270,270,262,270,270,270,270,270,270,270,270,270,270, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +703,703,703,703,703,1026,1027,196,196,196,196,196,196,196,196,196, +196,196,196,292,292,292,292,292,196,196,196,196,196,305,300,305, +305,305,305,305,305,305,305,305,305,1028,305,305,305,305,305,305, +305,305,305,305,305,305,305,297,305,305,305,305,305,297,305,297, +305,305,297,305,305,297,305,305,305,305,305,305,305,305,305,305, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, /* block 133 */ -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,331,331,331,331,331,331,331,331,331,331,331,331,331,331, -331,331,331,302,302,302,302,302,302,302,302,302,302,302,302,302, -302,302,302,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,370,370,370,370,370,370,370,370,370,370,370,370,370,370, +370,370,370,340,340,340,340,340,340,340,340,340,340,340,340,340, +340,340,340,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, /* block 134 */ -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,954,954, -954,954,954,954,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,1029,1029, +1029,1029,1029,1029,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, /* block 135 */ -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, /* block 136 */ -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,955,956, -280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,1030,1031, +315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, /* block 137 */ -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -302,302,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,302,302,302,302,302,302,302,280, -957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, -957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, -286,286,958,286,286,286,286,286,286,286,954,954,277,959,280,280, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +340,340,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,340,340,340,340,340,340,340,315, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +321,321,1033,321,321,321,321,321,321,321,1029,1029,312,1034,315,315, /* block 138 */ -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,961, -962,962,962,963,962,962,962,964,965,962,163,163,163,163,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,856,856, -962,966,966,701,701,964,965,964,965,964,965,964,965,964,965,964, -965,967,968,967,968,799,799,964,965,962,962,962,962,701,701,701, -969,166,970,163,166,971,972,972,966,973,974,973,974,973,974,975, -962,976,714,977,978,978,716,163,976,430,975,962,163,163,163,163, -954,286,954,286,954,302,954,286,954,286,954,286,954,286,954,286, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1036, +1037,1037,1038,1039,1037,1038,1038,1040,1041,1037,196,196,196,196,196,196, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,927,927, +1037,1042,1042,755,755,1040,1041,1040,1041,1040,1041,1040,1041,1040,1041,1040, +1041,1043,1044,1043,1044,866,866,1040,1041,1037,1037,1037,1037,755,755,755, +1045,199,1046,196,199,1047,1038,1038,1042,1048,1049,1048,1049,1048,1049,1050, +1037,1051,1052,1053,1054,1054,794,196,1051,479,1050,1037,196,196,196,196, +1029,321,1029,321,1029,340,1029,321,1029,321,1029,321,1029,321,1029,321, /* block 139 */ -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,302,302, 51, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,340,340, 51, /* block 140 */ -163,972,979,975,430,975,962,980,973,974,962,714,969,981,970,982, -983,983,983,983,983,983,983,983,983,983,971,166,978,716,978,972, -962,984,984,984,984,984,984, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,973,976,974,985,701, - 46,986,986,986,986,986,986, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,973,716,974,716,973, -974,987,988,989,990,826,825,825,825,825,825,825,825,825,825,825, -827,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +196,1038,1055,1050,479,1050,1037,1056,1048,1049,1037,1052,1045,1057,1046,1058, +1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1047,199,1054,794,1054,1038, +1037,1060,1060,1060,1060,1060,1060, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,1048,1051,1049,1061,755, + 46,1062,1062,1062,1062,1062,1062, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,1048,794,1049,794,1048, +1049,1063,1064,1065,1066,897,896,896,896,896,896,896,896,896,896,896, +898,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, /* block 141 */ -825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, -825,825,825,825,825,825,825,825,825,825,825,825,825,825,991,991, -831,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, -830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, -163,163,830,830,830,830,830,830,163,163,830,830,830,830,830,830, -163,163,830,830,830,830,830,830,163,163,830,830,830,163,163,163, -430,430,716, 46,724,430,430,163,724,716,716,716,716,724,724,163, -708,708,708,708,708,708,708,708,708,992,992,992,724,724,957,957, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,1067,1067, +902,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,196, +196,196,901,901,901,901,901,901,196,196,901,901,901,901,901,901, +196,196,901,901,901,901,901,901,196,196,901,901,901,196,196,196, +479,479,794, 46,781,479,479,196,781,794,794,794,794,781,781,196, +765,765,765,765,765,765,765,765,765,1068,1068,1068,781,781,1032,1032, /* block 142 */ -993,993,993,993,993,993,993,993,993,993,993,993,163,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,163,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,163,993,993,163,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,196,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,1069,1069,196,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 143 */ -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, -993,993,993,993,993,993,993,993,993,993,993,163,163,163,163,163, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, +1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196,196,196,196, /* block 144 */ -994,995,996,163,163,163,163,997,997,997,997,997,997,997,997,997, -997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, -997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, -997,997,997,997,163,163,163,998,998,998,998,998,998,998,998,998, -999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, -999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, -999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, -999,999,999,999,999,1000,1000,1000,1000,1001,1001,1001,1001,1001,1001,1001, +1070,1071,1072,196,196,196,196,1073,1073,1073,1073,1073,1073,1073,1073,1073, +1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, +1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, +1073,1073,1073,1073,196,196,196,1074,1074,1074,1074,1074,1074,1074,1074,1074, +1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, +1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, +1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, +1075,1075,1075,1075,1075,1076,1076,1076,1076,1077,1077,1077,1077,1077,1077,1077, /* block 145 */ -1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1000,1000,1001,1002,1002,163, -724,724,724,724,724,724,724,724,724,724,724,724,724,163,163,163, -1001,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,158,163,163, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1076,1076,1077,1078,1078,196, +781,781,781,781,781,781,781,781,781,781,781,781,781,196,196,196, +1077,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,189,196,196, /* block 146 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 147 */ -1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, -1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,163,163,163, -1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, -1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, -1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, -1004,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1005,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006, -1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,163,163,163,163, +1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079, +1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,196,196,196, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1081,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, +1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,196,196,196,196, /* block 148 */ -1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, -1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, -1008,1008,1008,1008,163,163,163,163,163,163,163,163,163,1007,1007,1007, -1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009, -1009,1010,1009,1009,1009,1009,1009,1009,1009,1009,1010,163,163,163,163,163, -1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, -1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, -1011,1011,1011,1011,1011,1011,1012,1012,1012,1012,1012,163,163,163,163,163, +1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, +1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, +1084,1084,1084,1084,196,196,196,196,196,196,196,196,196,1083,1083,1083, +1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085, +1085,1086,1085,1085,1085,1085,1085,1085,1085,1085,1086,196,196,196,196,196, +1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087, +1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087, +1087,1087,1087,1087,1087,1087,1088,1088,1088,1088,1088,196,196,196,196,196, /* block 149 */ -1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013, -1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,163,1014, -1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, -1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, -1015,1015,1015,1015,163,163,163,163,1015,1015,1015,1015,1015,1015,1015,1015, -1016,1017,1017,1017,1017,1017,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,196,1090, +1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091, +1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091, +1091,1091,1091,1091,196,196,196,196,1091,1091,1091,1091,1091,1091,1091,1091, +1092,1093,1093,1093,1093,1093,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 150 */ -1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, -1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, -1018,1018,1018,1018,1018,1018,1018,1018,1019,1019,1019,1019,1019,1019,1019,1019, -1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, -1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, -1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, -1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, -1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, +1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, +1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, +1094,1094,1094,1094,1094,1094,1094,1094,1095,1095,1095,1095,1095,1095,1095,1095, +1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, +1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, +1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, +1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, +1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, /* block 151 */ -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,163,163, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,163,163,163,163,163,163, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,163,163,163,163,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,163,163,163,163, +1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097, +1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,196,196, +1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,196,196,196,196,196,196, +1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099, +1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099, +1099,1099,1099,1099,196,196,196,196,1100,1100,1100,1100,1100,1100,1100,1100, +1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100, +1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,196,196,196,196, /* block 152 */ -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,163,163,163,163,163,163,163,163, -1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, -1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, -1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, -1026,1026,1026,1026,163,163,163,163,163,163,163,163,163,163,163,1027, -1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, +1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, +1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, +1101,1101,1101,1101,1101,1101,1101,1101,196,196,196,196,196,196,196,196, +1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, +1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, +1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, +1102,1102,1102,1102,196,196,196,196,196,196,196,196,196,196,196,1103, +1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,196,1104,1104,1104,1104, /* block 153 */ -1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, -1028,1028,1028,163,1028,1028,163,1029,1029,1029,1029,1029,1029,1029,1029,1029, -1029,1029,163,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029, -1029,1029,163,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,196,1104,1104,1104,1104, +1104,1104,1104,196,1104,1104,196,1105,1105,1105,1105,1105,1105,1105,1105,1105, +1105,1105,196,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105, +1105,1105,196,1105,1105,1105,1105,1105,1105,1105,196,1105,1105,196,196,196, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,196,196,196,196,196,196,196,196,196,196,196,196, /* block 154 */ -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, /* block 155 */ -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163, -1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163,163, -1030,1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196,196, +1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196,196,196, +1107,1107,1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 156 */ -147,1031,1031,147,147,147,163,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,163,147,147,147,147,147,147,147,147,147,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +149,1108,1108,149,149,149,196,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,196,149,149,149,149,149,149,149,149,149,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 157 */ -1032,1032,1032,1032,1032,1032,262,262,1032,262,1032,1032,1032,1032,1032,1032, -1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, -1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, -1032,1032,1032,1032,1032,1032,262,1032,1032,262,262,262,1032,262,262,1032, -1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033, -1033,1033,1033,1033,1033,1033,262,1034,1035,1035,1035,1035,1035,1035,1035,1035, -1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036, -1036,1036,1036,1036,1036,1036,1036,1037,1037,1038,1038,1038,1038,1038,1038,1038, +1109,1109,1109,1109,1109,1109,297,297,1109,297,1109,1109,1109,1109,1109,1109, +1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109, +1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109, +1109,1109,1109,1109,1109,1109,297,1109,1109,297,297,297,1109,297,297,1109, +1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110, +1110,1110,1110,1110,1110,1110,297,1111,1112,1112,1112,1112,1112,1112,1112,1112, +1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113, +1113,1113,1113,1113,1113,1113,1113,1114,1114,1115,1115,1115,1115,1115,1115,1115, /* block 158 */ -1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039, -1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,262, -262,262,262,262,262,262,262,1040,1040,1040,1040,1040,1040,1040,1040,1040, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041, -1041,1041,1041,262,1041,1041,262,262,262,262,262,1042,1042,1042,1042,1042, +1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, +1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,297, +297,297,297,297,297,297,297,1117,1117,1117,1117,1117,1117,1117,1117,1117, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118, +1118,1118,1118,297,1118,1118,297,297,297,297,297,1119,1119,1119,1119,1119, /* block 159 */ -1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043, -1043,1043,1043,1043,1043,1043,1044,1044,1044,1044,1044,1044,262,262,262,1045, -1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046, -1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,262,262,262,262,262,1047, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120, +1120,1120,1120,1120,1120,1120,1121,1121,1121,1121,1121,1121,297,297,297,1122, +1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123, +1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,297,297,297,297,297,1124, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 160 */ -1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, -1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, -1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049, -1049,1049,1049,1049,1049,1049,1049,1049,262,262,262,262,1050,1050,1049,1049, -1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, -262,262,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, -1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, -1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125, +1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125, +1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126, +1126,1126,1126,1126,1126,1126,1126,1126,297,297,297,297,1127,1127,1126,1126, +1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, +297,297,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, +1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, +1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, /* block 161 */ -1051,1052,1052,1052,262,1052,1052,262,262,262,262,262,1052,1052,1052,1052, -1051,1051,1051,1051,262,1051,1051,1051,262,1051,1051,1051,1051,1051,1051,1051, -1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, -1051,1051,1051,1051,1051,1051,262,262,1053,1053,1053,262,262,262,262,1054, -1055,1055,1055,1055,1055,1055,1055,1055,1055,262,262,262,262,262,262,262, -1056,1056,1056,1056,1056,1056,1057,1057,1056,262,262,262,262,262,262,262, -1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058, -1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1059,1059,1060, +1128,1129,1129,1129,297,1129,1129,297,297,297,297,297,1129,1129,1129,1129, +1128,1128,1128,1128,297,1128,1128,1128,297,1128,1128,1128,1128,1128,1128,1128, +1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128, +1128,1128,1128,1128,1128,1128,297,297,1130,1130,1130,297,297,297,297,1131, +1132,1132,1132,1132,1132,1132,1132,1132,1132,297,297,297,297,297,297,297, +1133,1133,1133,1133,1133,1133,1134,1134,1133,297,297,297,297,297,297,297, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1136,1136,1137, /* block 162 */ -1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061, -1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1062,1062,1062, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1063,1063,1063,1063,1063,1063,1063,1063,1064,1063,1063,1063,1063,1063,1063,1063, -1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063, -1063,1063,1063,1063,1063,1065,1065,262,262,262,262,1066,1066,1066,1066,1066, -1067,1067,1068,1067,1067,1067,1069,262,262,262,262,262,262,262,262,262, +1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138, +1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1139,1139,1139, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1140,1140,1140,1140,1140,1140,1140,1140,1141,1140,1140,1140,1140,1140,1140,1140, +1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140, +1140,1140,1140,1140,1140,1142,1142,297,297,297,297,1143,1143,1143,1143,1143, +1144,1144,1145,1144,1144,1144,1146,297,297,297,297,297,297,297,297,297, /* block 163 */ -1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, -1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, -1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, -1070,1070,1070,1070,1070,1070,262,262,262,1071,1072,1072,1072,1072,1072,1072, -1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, -1073,1073,1073,1073,1073,1073,262,262,1074,1074,1074,1074,1074,1074,1074,1074, -1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, -1075,1075,1075,262,262,262,262,262,1076,1076,1076,1076,1076,1076,1076,1076, +1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147, +1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147, +1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147, +1147,1147,1147,1147,1147,1147,297,297,297,1148,1149,1149,1149,1149,1149,1149, +1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150, +1150,1150,1150,1150,1150,1150,297,297,1151,1151,1151,1151,1151,1151,1151,1151, +1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152, +1152,1152,1152,297,297,297,297,297,1153,1153,1153,1153,1153,1153,1153,1153, /* block 164 */ -1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, -1077,1077,262,262,262,262,262,262,262,1078,1078,1078,1078,262,262,262, -262,262,262,262,262,262,262,262,262,1079,1079,1079,1079,1079,1079,1079, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, +1154,1154,297,297,297,297,297,297,297,1155,1155,1155,1155,297,297,297, +297,297,297,297,297,297,297,297,297,1156,1156,1156,1156,1156,1156,1156, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 165 */ -1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, -1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, -1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, -1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, -1080,1080,1080,1080,1080,1080,1080,1080,1080,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, +1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, +1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, +1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, +1157,1157,1157,1157,1157,1157,1157,1157,1157,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 166 */ -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,262,262,262,262,262,262,262,262,262,262,262,262,262, -1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, -1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, -1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, -1082,1082,1082,262,262,262,262,262,262,262,1083,1083,1083,1083,1083,1083, +1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158, +1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158, +1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158, +1158,1158,1158,297,297,297,297,297,297,297,297,297,297,297,297,297, +1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159, +1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159, +1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159, +1159,1159,1159,297,297,297,297,297,297,297,1160,1160,1160,1160,1160,1160, /* block 167 */ -1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, -1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, -1084,1084,1085,1085,1086,1086,1086,1086,302,302,302,302,302,302,302,302, -1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,302,302,302,302,302,302, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161, +1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161, +1161,1161,1162,1162,1163,1163,1163,1163,340,340,340,340,340,340,340,340, +1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,340,340,340,340,340,340, +1165,1165,1165,1165,1165,1165,1165,1165,1165,1165,1166,1166,1166,1166,1167,1166, +1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168, +1168,1168,1168,1168,1168,1168,297,297,297,1169,1170,1171,1171,1171,1172,1173, +1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174, /* block 168 */ -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1174,1174,1174,1174,1174,1174,297,297,297,297,297,297,297,297,1175,1175, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 169 */ -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088, -1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,262, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176, +1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,297, /* block 170 */ -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,262,1090,1090,1091,262,262, -1089,1089,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,291,291,291, +1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177, +1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177, +1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,297,1178,1178,1179,297,297, +1177,1177,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +340,340,321,321,321,340,340,340,340,340,340,340,340,340,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,316,333,333,333, /* block 171 */ -1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092, -1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1093,1093,1093, -1093,1093,1093,1093,1093,1093,1093,1092,262,262,262,262,262,262,262,262, -1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, -1094,1094,1094,1094,1094,1094,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, -1095,1096,1096,1096,1096,1097,1097,1097,1097,1097,302,302,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098, +1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180, +1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1181,1181,1181, +1181,1181,1181,1181,1181,1181,1181,1180,297,297,297,297,297,297,297,297, +1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182, +1182,1182,1182,1182,1182,1182,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, +1183,1184,1184,1184,1184,1185,1185,1185,1185,1185,340,340,340,340,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186, /* block 172 */ -1098,1098,1099,1099,1099,1099,1100,1100,1100,1100,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, -1101,1101,1101,1101,1101,1102,1102,1102,1102,1102,1102,1102,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103, -1103,1103,1103,1103,1103,1103,1103,262,262,262,262,262,262,262,262,262, +1186,1186,1187,1187,1187,1187,1188,1188,1188,1188,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, +1189,1189,1189,1189,1189,1190,1190,1190,1190,1190,1190,1190,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191, +1191,1191,1191,1191,1191,1191,1191,297,297,297,297,297,297,297,297,297, /* block 173 */ -1104,1105,1104,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,1106,1106,1106,1106,1105,1105,1105,1105,1105,1105,1105,1105, -1105,1105,1105,1105,1105,1105,1107,1108,1108,1109,1109,1109,1109,1109,163,163, -163,163,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110, -1110,1110,1110,1110,1110,1110,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111, -1107,1106,1106,1105,1105,1106,163,163,163,163,163,163,163,163,163,1112, +1192,1193,1192,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194, +1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194, +1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194, +1194,1194,1194,1194,1194,1194,1194,1194,1193,1193,1193,1193,1193,1193,1193,1193, +1193,1193,1193,1193,1193,1193,1195,1196,1196,1197,1197,1197,1197,1197,196,196, +196,196,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198, +1198,1198,1198,1198,1198,1198,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1195,1194,1194,1193,1193,1194,196,196,196,196,196,196,196,196,196,1200, /* block 174 */ -1113,1113,1114,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, -1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, -1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, -1114,1114,1114,1113,1113,1113,1113,1114,1114,1116,1117,1118,1118,1119,1120,1120, -1120,1120,1113,163,163,163,163,163,163,163,163,163,163,1119,163,163, -1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121, -1121,1121,1121,1121,1121,1121,1121,1121,1121,163,163,163,163,163,163,163, -1122,1122,1122,1122,1122,1122,1122,1122,1122,1122,163,163,163,163,163,163, +1201,1201,1202,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203, +1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203, +1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203, +1202,1202,1202,1201,1201,1201,1201,1202,1202,1204,1205,1206,1206,1207,1208,1208, +1208,1208,1201,196,196,196,196,196,196,196,196,196,196,1207,196,196, +1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209, +1209,1209,1209,1209,1209,1209,1209,1209,1209,196,196,196,196,196,196,196, +1210,1210,1210,1210,1210,1210,1210,1210,1210,1210,196,196,196,196,196,196, /* block 175 */ -1123,1123,1123,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, -1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, -1124,1124,1124,1124,1124,1124,1124,1123,1123,1123,1123,1123,1125,1123,1123,1123, -1123,1123,1123,1126,1126,163,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, -1128,1129,1129,1129,1124,1125,1125,1124,163,163,163,163,163,163,163,163, -1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, -1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, -1130,1130,1130,1131,1132,1132,1130,163,163,163,163,163,163,163,163,163, +1211,1211,1211,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212, +1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212, +1212,1212,1212,1212,1212,1212,1212,1211,1211,1211,1211,1211,1213,1211,1211,1211, +1211,1211,1211,1214,1214,196,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215, +1216,1217,1217,1217,1212,1213,1213,1212,196,196,196,196,196,196,196,196, +1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218, +1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218, +1218,1218,1218,1219,1220,1220,1218,196,196,196,196,196,196,196,196,196, /* block 176 */ -1133,1133,1134,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, -1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, -1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, -1135,1135,1135,1134,1134,1134,1133,1133,1133,1133,1133,1133,1133,1133,1133,1134, -1136,1135,1137,1137,1135,1138,1138,1139,1139,1140,1141,1141,1141,1138,1134,1133, -1142,1142,1142,1142,1142,1142,1142,1142,1142,1142,1135,1139,1135,1139,1138,1138, -163,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143, -1143,1143,1143,1143,1143,163,163,163,163,163,163,163,163,163,163,163, +1221,1221,1222,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223, +1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223, +1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223, +1223,1223,1223,1222,1222,1222,1221,1221,1221,1221,1221,1221,1221,1221,1221,1222, +1224,1223,1225,1225,1223,1226,1226,1227,1227,1228,1229,1229,1229,1226,1222,1221, +1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1223,1227,1223,1227,1226,1226, +196,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231, +1231,1231,1231,1231,1231,196,196,196,196,196,196,196,196,196,196,196, /* block 177 */ -1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, -1144,1144,163,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, -1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1145,1145,1145,1146, -1146,1146,1145,1145,1146,1147,1148,1146,1149,1149,1150,1149,1149,1151,1146,1144, -1144,1146,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232, +1232,1232,196,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232, +1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1233,1233,1233,1234, +1234,1234,1233,1233,1234,1235,1236,1237,1238,1238,1239,1238,1238,1240,1234,1232, +1232,1234,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 178 */ -1152,1152,1152,1152,1152,1152,1152,163,1152,163,1152,1152,1152,1152,163,1152, -1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,163,1152, -1152,1152,1152,1152,1152,1152,1152,1152,1152,1153,163,163,163,163,163,163, -1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, -1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, -1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1155, -1156,1156,1156,1155,1155,1155,1155,1155,1155,1157,1158,163,163,163,163,163, -1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,163,163,163,163,163,163, +1241,1241,1241,1241,1241,1241,1241,196,1241,196,1241,1241,1241,1241,196,1241, +1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,196,1241, +1241,1241,1241,1241,1241,1241,1241,1241,1241,1242,196,196,196,196,196,196, +1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243, +1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243, +1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1244, +1245,1245,1245,1244,1244,1244,1244,1244,1244,1246,1247,196,196,196,196,196, +1248,1248,1248,1248,1248,1248,1248,1248,1248,1248,196,196,196,196,196,196, /* block 179 */ -1160,1161,1162,1163,163,1164,1164,1164,1164,1164,1164,1164,1164,163,163,1164, -1164,163,163,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164, -1164,1164,1164,1164,1164,1164,1164,1164,1164,163,1164,1164,1164,1164,1164,1164, -1164,163,1164,1164,163,1164,1164,1164,1164,1164,163,1165,1166,1164,1167,1162, -1160,1162,1162,1162,1162,163,163,1162,1162,163,163,1162,1162,1168,163,163, -1164,163,163,163,163,163,163,1167,163,163,163,163,163,1169,1164,1164, -1164,1164,1162,1162,163,163,1170,1170,1170,1170,1170,1170,1170,163,163,163, -1170,1170,1170,1170,1170,163,163,163,163,163,163,163,163,163,163,163, +1249,1250,1251,1252,196,1253,1253,1253,1253,1253,1253,1253,1253,196,196,1253, +1253,196,196,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253, +1253,1253,1253,1253,1253,1253,1253,1253,1253,196,1253,1253,1253,1253,1253,1253, +1253,196,1253,1253,196,1253,1253,1253,1253,1253,196,1254,1255,1253,1256,1251, +1249,1251,1251,1251,1251,196,196,1251,1251,196,196,1251,1251,1257,196,196, +1253,196,196,196,196,196,196,1256,196,196,196,196,196,1258,1253,1253, +1253,1253,1251,1251,196,196,1259,1259,1259,1259,1259,1259,1259,196,196,196, +1259,1259,1259,1259,1259,196,196,196,196,196,196,196,196,196,196,196, /* block 180 */ -1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, -1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, -1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, -1171,1171,1171,1171,1171,1172,1172,1172,1173,1173,1173,1173,1173,1173,1173,1173, -1172,1172,1174,1173,1173,1172,1175,1171,1171,1171,1171,1176,1176,1177,1178,1178, -1179,1179,1179,1179,1179,1179,1179,1179,1179,1179,1177,1177,163,1178,1180,1171, -1171,1171,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,196,1260,196,196,1260,196, +1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, +1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, +1260,1260,1260,1260,1260,1260,196,1260,1261,1262,1262,1263,1263,1263,1263,1263, +1263,196,1261,196,196,1261,196,1261,1261,1261,1262,196,1262,1262,1264,1265, +1264,1266,1267,1268,1269,1269,196,1270,1270,196,196,196,196,196,196,196, +196,1271,1271,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 181 */ -1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, -1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, -1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, -1182,1183,1183,1184,1184,1184,1184,1184,1184,1183,1184,1183,1183,1182,1183,1184, -1184,1183,1185,1186,1181,1181,1187,1181,163,163,163,163,163,163,163,163, -1188,1188,1188,1188,1188,1188,1188,1188,1188,1188,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272, +1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272, +1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272, +1272,1272,1272,1272,1272,1273,1273,1273,1274,1274,1274,1274,1274,1274,1274,1274, +1273,1273,1275,1274,1274,1273,1276,1272,1272,1272,1272,1277,1277,1278,1279,1279, +1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1278,1278,196,1279,1281,1272, +1272,1272,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 182 */ -1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, -1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, -1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1190, -1191,1191,1192,1192,1192,1192,163,163,1191,1191,1191,1191,1192,1192,1191,1193, -1194,1195,1196,1196,1197,1197,1198,1198,1198,1196,1196,1196,1196,1196,1196,1196, -1196,1196,1196,1196,1196,1196,1196,1196,1189,1189,1189,1189,1192,1192,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1283,1284,1284,1285,1285,1285,1285,1285,1285,1284,1285,1284,1284,1283,1284,1285, +1285,1284,1286,1287,1282,1282,1288,1282,196,196,196,196,196,196,196,196, +1289,1289,1289,1289,1289,1289,1289,1289,1289,1289,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 183 */ -1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, -1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, -1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, -1200,1200,1200,1201,1201,1201,1201,1201,1201,1201,1201,1200,1200,1201,1200,1202, -1201,1203,1203,1204,1199,163,163,163,163,163,163,163,163,163,163,163, -1205,1205,1205,1205,1205,1205,1205,1205,1205,1205,163,163,163,163,163,163, -531,531,531,531,531,531,531,531,531,531,531,531,531,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290, +1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290, +1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1291, +1292,1292,1293,1293,1293,1293,196,196,1292,1292,1292,1292,1293,1293,1292,1294, +1295,1296,1297,1297,1298,1298,1299,1299,1299,1297,1297,1297,1297,1297,1297,1297, +1297,1297,1297,1297,1297,1297,1297,1297,1290,1290,1290,1290,1293,1293,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 184 */ -1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, -1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, -1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1207,1208,1207,1208,1208, -1207,1207,1207,1207,1207,1207,1209,1210,1206,1211,163,163,163,163,163,163, -1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1301,1301,1301,1302,1302,1302,1302,1302,1302,1302,1302,1301,1301,1302,1301,1303, +1302,1304,1304,1305,1300,196,196,196,196,196,196,196,196,196,196,196, +1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,196,196,196,196,196,196, +581,581,581,581,581,581,581,581,581,581,581,581,581,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 185 */ -1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213, -1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,163,163,1214,1214,1214, -1215,1215,1214,1214,1214,1214,1216,1214,1214,1214,1214,1217,163,163,163,163, -1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1219,1219,1220,1220,1220,1221, -1213,1213,1213,1213,1213,1213,1213,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307, +1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307, +1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1308,1309,1308,1309,1309, +1308,1308,1308,1308,1308,1308,1310,1311,1307,1312,196,196,196,196,196,196, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,196,196,196,196,196,196, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 186 */ -1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, -1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, -1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1223,1223,1223,1224, -1224,1224,1224,1224,1224,1224,1224,1224,1223,1225,1226,1227,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, +1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,196,196,1315,1316,1315, +1317,1317,1315,1315,1315,1315,1316,1315,1315,1315,1315,1318,196,196,196,196, +1319,1319,1319,1319,1319,1319,1319,1319,1319,1319,1320,1320,1321,1321,1321,1322, +1314,1314,1314,1314,1314,1314,1314,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 187 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, -1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, -1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, -1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, -1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1231,1231,1231,1231,1231,1231, -1231,1231,1231,163,163,163,163,163,163,163,163,163,163,163,163,1232, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1324,1324,1324,1325, +1325,1325,1325,1325,1325,1325,1325,1325,1324,1326,1327,1328,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 188 */ -1233,1233,1233,1233,1233,1233,1233,163,163,1233,163,163,1233,1233,1233,1233, -1233,1233,1233,1233,163,1233,1233,163,1233,1233,1233,1233,1233,1233,1233,1233, -1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233, -1234,1235,1235,1235,1235,1235,163,1235,1235,163,163,1236,1236,1237,1238,1239, -1235,1239,1235,1240,1241,1242,1241,163,163,163,163,163,163,163,163,163, -1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329, +1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329, +1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330, +1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330, +1331,1331,1331,1331,1331,1331,1331,1331,1331,1331,1332,1332,1332,1332,1332,1332, +1332,1332,1332,196,196,196,196,196,196,196,196,196,196,196,196,1333, /* block 189 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1244,1244,1244,1244,1244,1244,1244,1244,163,163,1244,1244,1244,1244,1244,1244, -1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, -1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, -1244,1245,1245,1245,1246,1246,1246,1246,163,163,1246,1246,1245,1245,1245,1245, -1247,1244,1248,1244,1245,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1334,1334,1334,1334,1334,1334,1334,196,196,1334,196,196,1334,1334,1334,1334, +1334,1334,1334,1334,196,1334,1334,196,1334,1334,1334,1334,1334,1334,1334,1334, +1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334, +1335,1336,1336,1336,1336,1336,196,1336,1336,196,196,1337,1337,1338,1339,1340, +1336,1340,1336,1341,1342,1343,1342,196,196,196,196,196,196,196,196,196, +1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 190 */ -1249,1250,1250,1250,1250,1250,1250,1251,1251,1250,1250,1249,1249,1249,1249,1249, -1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, -1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, -1249,1249,1249,1252,1253,1250,1250,1250,1250,1254,1255,1250,1250,1250,1250,1256, -1256,1256,1257,1257,1256,1256,1256,1253,163,163,163,163,163,163,163,163, -1258,1259,1259,1259,1259,1259,1259,1260,1260,1259,1259,1259,1258,1258,1258,1258, -1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, -1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1345,1345,1345,1345,1345,1345,1345,1345,196,196,1345,1345,1345,1345,1345,1345, +1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345, +1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345, +1345,1346,1346,1346,1347,1347,1347,1347,196,196,1347,1347,1346,1346,1346,1346, +1348,1345,1349,1345,1346,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 191 */ -1258,1258,1258,1258,1261,1261,1261,1261,1261,1261,1259,1259,1259,1259,1259,1259, -1259,1259,1259,1259,1259,1259,1259,1260,1262,1263,1264,1265,1265,1258,1264,1264, -1264,1266,1266,163,163,163,163,163,163,163,163,163,163,163,163,163, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, -1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, -1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, -1267,1267,1267,1267,1267,1267,1267,1267,1267,163,163,163,163,163,163,163, +1350,1351,1351,1351,1351,1351,1351,1352,1352,1351,1351,1350,1350,1350,1350,1350, +1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350, +1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350, +1350,1350,1350,1353,1354,1351,1351,1351,1351,1355,1356,1351,1351,1351,1351,1357, +1357,1357,1358,1358,1357,1357,1357,1354,196,196,196,196,196,196,196,196, +1359,1360,1360,1360,1360,1360,1360,1361,1361,1360,1360,1360,1359,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, +1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, /* block 192 */ -343,343,343,343,343,343,343,343,343,343,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1359,1359,1359,1359,1362,1362,1362,1362,1362,1362,1360,1360,1360,1360,1360,1360, +1360,1360,1360,1360,1360,1360,1360,1361,1363,1364,1365,1366,1366,1359,1365,1365, +1365,1367,1367,196,196,196,196,196,196,196,196,196,196,196,196,196, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,196,196,196,196,196,196,196, /* block 193 */ -1268,1268,1268,1268,1268,1268,1268,1268,1268,163,1268,1268,1268,1268,1268,1268, -1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268, -1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1269, -1270,1270,1270,1270,1270,1270,1270,163,1270,1270,1270,1270,1270,1270,1269,1271, -1268,1272,1272,1273,1274,1274,163,163,163,163,163,163,163,163,163,163, -1275,1275,1275,1275,1275,1275,1275,1275,1275,1275,1276,1276,1276,1276,1276,1276, -1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,163,163,163, -1277,1278,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, +385,385,385,385,385,385,385,385,385,385,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 194 */ -1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, -163,163,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280, -1280,1280,1280,1280,1280,1280,1280,1280,163,1281,1280,1280,1280,1280,1280,1280, -1280,1281,1280,1280,1281,1280,1280,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1370,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1371,1371,1371,1371,1371,1371,1371,1371,1371,1371,196,196,196,196,196,196, /* block 195 */ -1282,1282,1282,1282,1282,1282,1282,163,1282,1282,163,1282,1282,1282,1282,1282, -1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, -1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, -1282,1283,1283,1283,1283,1283,1283,163,163,163,1283,163,1283,1283,163,1283, -1283,1283,1284,1283,1285,1285,1286,1283,163,163,163,163,163,163,163,163, -1287,1287,1287,1287,1287,1287,1287,1287,1287,1287,163,163,163,163,163,163, -1288,1288,1288,1288,1288,1288,163,1288,1288,163,1288,1288,1288,1288,1288,1288, -1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288, +1372,1372,1372,1372,1372,1372,1372,1372,1372,196,1372,1372,1372,1372,1372,1372, +1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372, +1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1373, +1374,1374,1374,1374,1374,1374,1374,196,1374,1374,1374,1374,1374,1374,1373,1375, +1372,1376,1376,1377,1378,1378,196,196,196,196,196,196,196,196,196,196, +1379,1379,1379,1379,1379,1379,1379,1379,1379,1379,1380,1380,1380,1380,1380,1380, +1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,196,196,196, +1381,1382,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383, /* block 196 */ -1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1289,1289,1289,1289,1289,163, -1290,1290,163,1289,1289,1290,1289,1291,1288,163,163,163,163,163,163,163, -1292,1292,1292,1292,1292,1292,1292,1292,1292,1292,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383, +196,196,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, +1384,1384,1384,1384,1384,1384,1384,1384,196,1385,1384,1384,1384,1384,1384,1384, +1384,1385,1384,1384,1385,1384,1384,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 197 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293, -1293,1293,1293,1294,1294,1295,1295,1296,1296,163,163,163,163,163,163,163, +1386,1386,1386,1386,1386,1386,1386,196,1386,1386,196,1386,1386,1386,1386,1386, +1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386, +1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386, +1386,1387,1387,1387,1387,1387,1387,196,196,196,1387,196,1387,1387,196,1387, +1387,1387,1388,1387,1389,1389,1390,1387,196,196,196,196,196,196,196,196, +1391,1391,1391,1391,1391,1391,1391,1391,1391,1391,196,196,196,196,196,196, +1392,1392,1392,1392,1392,1392,196,1392,1392,196,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, /* block 198 */ -1297,1297,1298,1299,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, -1300,163,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, -1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, -1300,1300,1300,1300,1299,1299,1297,1297,1297,1297,1297,163,163,163,1299,1299, -1297,1301,1302,1303,1303,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1305,1305,1305,1305,1305,1305,1305,1305,1305,1305,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1393,1393,1393,1393,1393,196, +1394,1394,196,1393,1393,1394,1393,1395,1392,196,196,196,196,196,196,196, +1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 199 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -843,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -388,388,1306,388,1306,390,390,390,390,390,390,390,390,391,391,391, -391,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390, -390,390,163,163,163,163,163,163,163,163,163,163,163,163,163,1307, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397, +1397,1397,1397,1398,1398,1399,1399,1400,1400,196,196,196,196,196,196,196, /* block 200 */ -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1401,1401,1402,1403,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404, +1404,196,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404, +1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404, +1404,1404,1404,1404,1403,1403,1401,1401,1401,1401,1401,196,196,196,1403,1403, +1401,1405,1406,1407,1407,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1410,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 201 */ -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +914,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411, +435,435,1411,435,1411,437,437,437,437,437,437,437,437,438,438,438, +438,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, +437,437,196,196,196,196,196,196,196,196,196,196,196,196,196,1412, /* block 202 */ -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,163, -1310,1310,1310,1310,1310,163,163,163,163,163,163,163,163,163,163,163, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, /* block 203 */ -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 204 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, -1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, -1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, -1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, -1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, -1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, -1311,1312,1312,163,163,163,163,163,163,163,163,163,163,163,163,163, +1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, +1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, +1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, +1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, +1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, +1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, +1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,196, +1415,1415,1415,1415,1415,196,196,196,196,196,196,196,196,196,196,196, /* block 205 */ -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 206 */ -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, -1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, -1315,1313,1313,1313,1313,1313,1313,1316,1316,1316,1316,1316,1316,1316,1316,1316, -1316,1316,1316,1316,1316,1316,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, +1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, +1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, +1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, +1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, +1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, +1416,1417,1417,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 207 */ -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, /* block 208 */ -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419, +1420,1418,1418,1418,1418,1418,1418,1421,1421,1421,1421,1421,1421,1421,1421,1421, +1421,1421,1421,1421,1421,1421,196,196,196,196,196,196,196,196,196,196, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, /* block 209 */ -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,196,196,196,196,196, /* block 210 */ -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,859,163,163,163,163,163,163,163, -1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318, -1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,163, -1319,1319,1319,1319,1319,1319,1319,1319,1319,1319,163,163,163,163,1320,1320, -1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, /* block 211 */ -1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, -1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, -1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, -1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,163, -1322,1322,1322,1322,1322,1322,1322,1322,1322,1322,163,163,163,163,163,163, -1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, -1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,163,163, -1324,1324,1324,1324,1324,1325,163,163,163,163,163,163,163,163,163,163, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 212 */ -1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, -1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, -1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, -1327,1327,1327,1327,1327,1327,1327,1328,1328,1329,1330,1330,1331,1331,1331,1331, -1332,1332,1333,1333,1328,1331,163,163,163,163,163,163,163,163,163,163, -1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,163,1335,1335,1335,1335,1335, -1335,1335,163,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, -1326,1326,1326,1326,1326,1326,1326,1326,163,163,163,163,163,1326,1326,1326, +1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423, +1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1424,1424, +1424,1424,1424,1424,1424,1424,1424,1424,1424,1424,1425,1425,1425,1424,1424,1426, +1427,1427,1427,1427,1427,1427,1427,1427,1427,1427,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 213 */ -1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, /* block 214 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, -1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, -1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, -1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,196,196,196,196,196,196,196, +1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428, +1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,196, +1429,1429,1429,1429,1429,1429,1429,1429,1429,1429,196,196,196,196,1430,1430, +1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, /* block 215 */ -1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338, -1338,1338,1338,1338,1338,1338,1338,1339,1340,1341,1341,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, +1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, +1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, +1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,196, +1432,1432,1432,1432,1432,1432,1432,1432,1432,1432,196,196,196,196,196,196, +1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433, +1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,196,196, +1434,1434,1434,1434,1434,1435,196,196,196,196,196,196,196,196,196,196, /* block 216 */ -1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, -1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, -1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, -1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, -1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,163,163,163,163,1343, -1342,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, +1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, +1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, +1437,1437,1437,1437,1437,1437,1437,1438,1438,1439,1440,1440,1441,1441,1441,1441, +1442,1442,1443,1443,1438,1441,196,196,196,196,196,196,196,196,196,196, +1444,1444,1444,1444,1444,1444,1444,1444,1444,1444,196,1445,1445,1445,1445,1445, +1445,1445,196,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, +1436,1436,1436,1436,1436,1436,1436,1436,196,196,196,196,196,1436,1436,1436, /* block 217 */ -1344,1344,1344,1344,1344,1344,1344,1344,163,163,163,163,163,163,163,1345, -1345,1345,1345,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1347,1348,1349,800,1350,163,163,163,163,163,163,163,163,163,163,163, -1351,1351,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 218 */ -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1446,1446,1446,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447, +1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447, +1447,1447,1447,1448,1447,1447,1447,1448,1448,1448,1448,1449,1449,1450,1451,1451, +1452,1452,1452,1452,1452,1452,1452,1452,1452,1452,196,196,196,196,196,196, /* block 219 */ -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, -1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163,163, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453, +1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453, +1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454, +1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454, /* block 220 */ -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455, +1455,1455,1455,1455,1455,1455,1455,1456,1457,1458,1458,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 221 */ -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, -1353,1353,1353,1353,1353,1353,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, +1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, +1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, +1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, +1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,196,196,196,196,1460, +1459,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461, +1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461, +1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461, /* block 222 */ -1352,1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1461,1461,1461,1461,1461,1461,1461,1461,196,196,196,196,196,196,196,1462, +1462,1462,1462,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1464,1465,1466,867,1467,196,196,196,196,196,196,196,196,196,196,196, +1468,1468,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 223 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1354,1354,1354,1354,163,1354,1354,1354,1354,1354,1354,1354,163,1354,1354,163, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, /* block 224 */ -825,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +1469,1469,1469,1469,1469,1469,1469,1469,196,196,196,196,196,196,196,196, /* block 225 */ -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, /* block 226 */ -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -825,825,825,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,820,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -820,820,820,163,163,825,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,825,825,825,825,163,163,163,163,163,163,163,163, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +1470,1470,1470,1470,1470,1470,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,1470, /* block 227 */ -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1469,1469,1469,1469,1469,1469,1469,1469,1469,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 228 */ -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, -1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,163,163,163,163, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1471,1471,1471,1471,196,1471,1471,1471,1471,1471,1471,1471,196,1471,1471,196, /* block 229 */ -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163, +896,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, /* block 230 */ -1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163,163,163, -1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,1357,1358,1359,1360, -1361,1361,1361,1361,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, /* block 231 */ -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,163,163,163,163,163,163,163,163,163, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +896,896,896,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,891,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +891,891,891,196,196,896,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,896,896,896,896,196,196,196,196,196,196,196,196, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, /* block 232 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, /* block 233 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,196,196,196,196, /* block 234 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,163,163,163,163,163,163,163,163,163,163, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196,196,196, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196, /* block 235 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,163,163,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,1362,1363,154,154,154,461,461,461,1364,1365,1365, -1365,1365,1365, 51, 51, 51, 51, 51, 51, 51, 51,154,154,154,154,154, +1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196,196,196,196,196, +1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,1474,1475,1476,1477, +1478,1478,1478,1478,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 236 */ -154,154,154,461,461,154,154,154,154,154,154,154,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,154,154,154,154,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,724,724,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, /* block 237 */ -1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, -1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, -1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, -1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, -1001,1001,1366,1366,1366,1001,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +1479,1479,1479,1479,1479,1479,1479,1479,1479,1479,196,196,196,196,196,196, /* block 238 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, -836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, -836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, -836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 239 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,163,163,163,163,163,163,163,163,163, -833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, -833,833,836,836,836,836,836,836,836,163,163,163,163,163,163,163, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,196,196, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,196,196,196,196,196,196,196,196,196, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, /* block 240 */ -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, -726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, -726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, -726,726,726,726,726,163,737,737,726,726,726,726,726,726,726,726, -726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 241 */ -725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, -726,726,726,726,726,726,726,726,726,726,726,726,725,163,725,725, -163,163,725,163,163,725,725,163,163,725,725,725,725,163,725,725, -725,725,725,725,725,725,726,726,726,726,163,726,163,726,737,737, -726,726,726,726,163,726,726,726,726,726,726,726,726,726,726,726, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, -726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, /* block 242 */ -726,726,726,726,725,725,163,725,725,725,725,163,163,725,725,725, -725,725,725,725,725,163,725,725,725,725,725,725,725,163,726,726, -726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, -726,726,726,726,726,726,726,726,725,725,163,725,725,725,725,163, -725,725,725,725,725,163,725,163,163,163,725,725,725,725,725,725, -725,163,726,726,726,726,726,726,726,726,737,737,726,726,726,726, -726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,196,196,196,196,196,196,196,196,196,196, /* block 243 */ -725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, -726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, -726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, -726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, -726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,196,196,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,1480,1480,176,176,176,510,510,510,1481,1481,1481, +1481,1481,1481, 51, 51, 51, 51, 51, 51, 51, 51,176,176,176,176,176, /* block 244 */ -726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, -726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, -726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +176,176,176,510,510,176,176,176,176,176,176,176,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,176,176,176,176,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,781,781,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 245 */ -725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, -726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, -726,726,726,726,726,726,163,163,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,1367,726,726,726,726,726,726,726,726,726,726,726,726,726,726, -726,726,726,726,726,726,726,726,726,726,726,716,726,726,726,726, -726,726,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,1367,726,726,726,726, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, +1077,1077,1482,1482,1482,1077,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 246 */ -726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, -726,726,726,726,726,716,726,726,726,726,726,726,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,1367,726,726,726,726,726,726,726,726,726,726, -726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,716, -726,726,726,726,726,726,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,1367, -726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,196,196,196,196,196,196,196,196,196,196,196,196, +907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, +907,907,907,907,196,196,196,196,196,196,196,196,196,196,196,196, /* block 247 */ -726,726,726,726,726,726,726,726,726,716,726,726,726,726,726,726, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,1367,726,726,726,726,726,726, -726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, -726,726,726,716,726,726,726,726,726,726,725,726,163,163,1368,1368, -1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, -1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, -1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,196,196,196,196,196,196,196,196,196, +904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,904, +904,904,907,907,907,907,907,907,907,196,196,196,196,196,196,196, /* block 248 */ -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, +783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,783,783, +783,783,783,783,783,196,795,795,783,783,783,783,783,783,783,783, +783,783,783,783,783,783,783,783,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, /* block 249 */ -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, -1370,1370,1370,1370,1370,1370,1370,1369,1369,1369,1369,1370,1370,1370,1370,1370, -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1369,1369,1369, -1369,1369,1369,1369,1369,1370,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +782,782,783,783,783,783,783,783,783,783,795,795,783,783,783,783, +783,783,783,783,783,783,783,783,783,783,783,783,782,196,782,782, +196,196,782,196,196,782,782,196,196,782,782,782,782,196,782,782, +782,782,782,782,782,782,783,783,783,783,196,783,196,783,795,795, +783,783,783,783,196,783,783,783,783,783,783,783,783,783,783,783, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, +783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, /* block 250 */ -1369,1369,1369,1369,1370,1369,1369,1371,1372,1371,1371,1373,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,1370,1370,1370,1370,1370, -163,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +783,783,783,783,782,782,196,782,782,782,782,196,196,782,782,782, +782,782,782,782,782,196,782,782,782,782,782,782,782,196,783,783, +783,783,783,783,783,783,795,795,783,783,783,783,783,783,783,783, +783,783,783,783,783,783,783,783,782,782,196,782,782,782,782,196, +782,782,782,782,782,196,782,196,196,196,782,782,782,782,782,782, +782,196,783,783,783,783,783,783,783,783,795,795,783,783,783,783, +783,783,783,783,783,783,783,783,783,783,783,783,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, /* block 251 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 92, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,163, -163,163,163,163,163, 70, 70, 70, 70, 70, 70,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +782,782,782,782,782,782,783,783,783,783,783,783,783,783,795,795, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, +783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,783,783, +783,783,783,783,783,783,795,795,783,783,783,783,783,783,783,783, /* block 252 */ -1374,1374,1374,1374,1374,1374,1374,163,1374,1374,1374,1374,1374,1374,1374,1374, -1374,1374,1374,1374,1374,1374,1374,1374,1374,163,163,1374,1374,1374,1374,1374, -1374,1374,163,1374,1374,163,1374,1374,1374,1374,1374,163,163,163,163,163, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,1375,1375,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,1375,858,858,858,858,858,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +783,783,783,783,783,783,783,783,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,783,783,783,783,783,783,783,783,795,795,783,783,783,783, +783,783,783,783,783,783,783,783,783,783,783,783,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,783,783,783,783,783,783,783,783,795,795, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, /* block 253 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,788, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, +783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,783,783,196,196,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,1483,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,783,783,783,783,783,783,783,1483,783,783,783,783, +783,783,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,1483,783,783,783,783, /* block 254 */ -1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, -1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, -1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,163,163,163, -1377,1377,1377,1377,1377,1377,1377,1378,1378,1378,1378,1378,1379,1379,163,163, -1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,163,163,163,163,1376,1381, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,783,1483,783,783,783,783,783,783,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,1483,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,1483, +783,783,783,783,783,783,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,1483, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, /* block 255 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, -1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1383,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, -1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, -1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1385,1385,1385,1385, -1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,163,163,163,163,163,1387, +783,783,783,783,783,783,783,783,783,1483,783,783,783,783,783,783, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,1483,783,783,783,783,783,783, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,1483,783,783,783,783,783,783,782,783,196,196,1484,1484, +1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484, +1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484, +1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484, /* block 256 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388, -1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1389,1390,1390,1390,1390, -1391,1391,1391,1391,1391,1391,1391,1391,1391,1391,163,163,163,163,163,163, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, /* block 257 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -484,484,484,484,484,484,484,163,484,484,484,484,163,484,484,163, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,163, +1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, +1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, +1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, +1486,1486,1486,1486,1486,1486,1486,1485,1485,1485,1485,1486,1486,1486,1486,1486, +1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, +1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, +1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1485,1485,1485, +1485,1485,1485,1485,1485,1486,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, /* block 258 */ -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1485,1485,1485,1485,1486,1485,1485,1487,1488,1487,1487,1489,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,1486,1486,1486,1486,1486, +196,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 259 */ -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,262,262,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1394,1394,1394,1394,1394,1394,1394,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 93, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,694, 70, 70, 70, 70,196, +196,196,196,196,196, 70, 70, 70, 70, 70, 70,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 260 */ -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, -1396,1396,1396,1396,1397,1397,1397,1398,1399,1399,1399,1400,262,262,262,262, -1401,1401,1401,1401,1401,1401,1401,1401,1401,1401,262,262,262,262,1402,1402, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1490,1490,1490,1490,1490,1490,1490,196,1490,1490,1490,1490,1490,1490,1490,1490, +1490,1490,1490,1490,1490,1490,1490,1490,1490,196,196,1490,1490,1490,1490,1490, +1490,1490,196,1490,1490,196,1490,1490,1490,1490,1490,196,196,196,196,196, +929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, +929,929,929,929,929,929,929,929,929,929,929,929,1491,1491,929,929, +929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, +929,929,929,929,929,929,929,929,1491,929,929,929,929,929,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 261 */ -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,849, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 262 */ -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403,1403,1403, -1405,1403,1403,1403,1403,302,302,302,302,302,302,302,302,302,302,302, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492, +1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492, +1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,196,196,196, +1493,1493,1493,1493,1493,1493,1493,1494,1494,1494,1494,1494,1495,1495,196,196, +1496,1496,1496,1496,1496,1496,1496,1496,1496,1496,196,196,196,196,1492,1497, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 263 */ -302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498, +1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1499,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500, +1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500, +1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1501,1501,1501,1501, +1502,1502,1502,1502,1502,1502,1502,1502,1502,1502,196,196,196,196,196,1503, /* block 264 */ -1406,1406,1406,1406,302,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, -1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, -302,1406,1406,302,1406,302,302,1406,302,1406,1406,1406,1406,1406,1406,1406, -1406,1406,1406,302,1406,1406,1406,1406,302,1406,302,1406,302,302,302,302, -302,302,1406,302,302,302,302,1406,302,1406,302,1406,302,1406,1406,1406, -302,1406,1406,302,1406,302,302,1406,302,1406,302,1406,302,1406,302,1406, -302,1406,1406,302,1406,302,302,1406,1406,1406,1406,302,1406,1406,1406,1406, -1406,1406,1406,302,1406,1406,1406,1406,302,1406,1406,1406,1406,302,1406,302, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504, +1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1505,1506,1506,1506,1506, +1507,1507,1507,1507,1507,1507,1507,1507,1507,1507,196,196,196,196,196,196, /* block 265 */ -1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, -1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, -302,1406,1406,1406,302,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, -1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -274,274,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508, +1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1509,1510, +1508,1511,1511,1511,1511,1511,1511,1511,1511,1511,1511,196,196,196,196,1512, /* block 266 */ -1407,1407,1407,1407,1408,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409,1409,1409, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +533,533,533,533,533,533,533,196,533,533,533,533,196,533,533,196, +533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,196, /* block 267 */ -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409, -1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1408, -1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, /* block 268 */ - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 58, 58,1407,1407,1407, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1407, -1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, -1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,461,461, -1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, -1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,724,724,1407,1407,1407,1407, -1411,1411,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1411,1411, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1513,1513,1513,1513,1513,297,297,1514,1514,1514,1514,1514,1514,1514,1514,1514, +1515,1515,1515,1515,1515,1515,1515,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 269 */ -1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,1412,461, -461,1412,1412,1412,1412,1412,1412,1412,1412,1412,1412,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,1407,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516, +1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516, +1516,1516,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517, +1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517, +1517,1517,1517,1517,1518,1518,1518,1519,1520,1520,1520,1521,297,297,297,297, +1522,1522,1522,1522,1522,1522,1522,1522,1522,1522,297,297,297,297,1523,1523, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 270 */ -1414,1412,1415,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -461,461,461,461,461,461,461,461,461,461,1412,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1412, -461,461,1412,1412,1412,1412,1412,1415,1412,1412,1412,461,1409,1409,1409,1409, -461,461,461,461,461,461,461,461,461,1409,1409,1409,1409,1409,1409,1409, -1416,1416,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 271 */ -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +340,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, /* block 272 */ -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,728,1407,1407,728,728,728,728,728,728,728,728,728,1408,1408,1408, -1408,1408,1408,1408,1408,1408,728,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1408,1408, +1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, +1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, +1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1525,1524,1524,1524, +1526,1524,1524,1524,1524,340,340,340,340,340,340,340,340,340,340,340, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 273 */ -1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1407,1407,728,728,1407,728,728,728,1407,1407,728,728, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1417,1417,1417,1408,1408,1417,1408,1408,1417,1418,1418,728,728,1408, -1408,1408,1408,1408,728,728,728,728,728,728,728,728,728,728,728,728, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1407,1407,728,1408,728,1407,728,1408,1408,1408,1419,1419,1419,1419,1419, +340,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, +1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, +1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1525,1524, +1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, /* block 274 */ -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728, -1408,728,1417,1417,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, -1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, -1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408,1408,1417,1408,1408,1408, +1527,1527,1527,1527,340,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527, +1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527, +340,1527,1527,340,1527,340,340,1527,340,1527,1527,1527,1527,1527,1527,1527, +1527,1527,1527,340,1527,1527,1527,1527,340,1527,340,1527,340,340,340,340, +340,340,1527,340,340,340,340,1527,340,1527,340,1527,340,1527,1527,1527, +340,1527,1527,340,1527,340,340,1527,340,1527,340,1527,340,1527,340,1527, +340,1527,1527,340,1527,340,340,1527,1527,1527,1527,340,1527,1527,1527,1527, +1527,1527,1527,340,1527,1527,1527,1527,340,1527,1527,1527,1527,340,1527,340, /* block 275 */ -1408,1417,1417,1417,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1417, -1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1407,1408, +1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,1527,1527,1527,1527,1527, +1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,340,340,340, +340,1527,1527,1527,340,1527,1527,1527,1527,1527,340,1527,1527,1527,1527,1527, +1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,340,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +309,309,340,340,340,340,340,340,340,340,340,340,340,340,340,340, /* block 276 */ -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,724,724, -724,724,724,724,724,724,1407,1407,1407,728,728,1408,1408,1408,1408,1407, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,1407,1407,728, -728,1407,1407,728,1418,1418,728,728,728,728,1417,1407,1407,1407,1407,1407, +1528,1528,1528,1528,1529,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530,1530,1530, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, /* block 277 */ -1407,1407,1407,1407,1407,1407,1407,728,1407,1407,728,728,728,728,1407,1407, -1418,1407,1407,1407,1407,1417,1417,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1408,728,1407,1407,728,1407,1407,1407,1407,1407,1407,1407, -1407,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,728,1407,1407,1407, -1407,1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,728,728,728,1407, -1407,728,1407,728,1407,1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728, -1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728,1408,1408,1408,1408,1408, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530, +1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1529, +1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, /* block 278 */ -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1417,1417,1417,1417,1417, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +814,814,814,814,814,814,814,814,814,814,814, 58, 58,1528,1528,1528, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,1528, +1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531, +1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,510,510,510,510,510,510, +1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531, +1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,781,781,1528,1528,1528,1528, +1532,1532,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1532,1532, /* block 279 */ -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1417,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,728,1417,728,728,728, -1408,1408,1408,1407,1407,1408,1408,1408,1409,1409,1409,1409,1408,1408,1408,1408, -728,728,728,728,728,728,1407,1407,1407,728,1407,1408,1408,1409,1409,1409, -728,1407,1407,728,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, +1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,510,510,510,510,1533,510, +510,1533,1533,1533,1533,1533,1533,1533,1533,1533,1533,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,1528,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534, +1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534, /* block 280 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,1407,1407,1407,1409,1409,1409,1409,1407,1407,1407,1407,1407, +1535,1533,1536,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +510,510,510,510,510,510,510,510,510,510,1533,510,510,510,510,510, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,1533, +510,510,1533,1533,1533,1533,1533,1536,1533,1533,1533,510,1530,1530,1530,1530, +510,510,510,510,510,510,510,510,510,1530,1530,1530,1530,1530,1530,1530, +1537,1537,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, /* block 281 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, -1408,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, /* block 282 */ -724,724,724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, -724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,785,1528,1528,785,785,785,785,785,785,785,785,785,1529,1529,1529, +1529,1529,1529,1529,1529,1529,785,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785,1529,1529, /* block 283 */ -724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,1409,1409, -1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1528,1528,785,785,1528,785,785,785,1528,1528,785,785, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1538,1538,1538,1529,1529,1538,1529,1529,1538,1539,1539,785,785,1529, +1529,1529,1529,1529,785,785,785,785,785,785,785,785,785,785,785,785, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1528,1528,785,1529,785,1528,785,1529,1529,1529,1540,1540,1540,1540,1540, /* block 284 */ -724,724,724,724,724,724,724,724,724,724,724,724,1417,1408,1408,1417, -1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417, -1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,724,1417,1417,1417,1408, -1408,1408,1408,1408,1408,1408,724,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785, +1529,785,1538,1538,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538, +1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538, +1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,1529,1529,1538,1529,1529,1529, /* block 285 */ -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1420,1420,1420,1420,1408,1417,1417,1408,1417,1417,1408,1417,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417, -1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1529,1538,1538,1538,1529,1538,1538,1538,1529,1529,1529,1529,1529,1529,1529,1538, +1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785,1528,1529, /* block 286 */ -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, -1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,781,781, +781,781,781,781,781,781,1528,1528,1528,785,785,1529,1529,1529,1529,1528, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1528,1528,1528,1528,1528,1528,1528,785, +785,1528,1528,785,1539,1539,785,785,785,785,1538,1528,1528,1528,1528,1528, /* block 287 */ -1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1408, -1408,1408,1408,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409,1409,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, -1417,1417,1417,1417,1417,1417,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409, +1528,1528,1528,1528,1528,1528,1528,785,1528,1528,785,785,785,785,1528,1528, +1539,1528,1528,1528,1528,1538,1538,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1529,785,1528,1528,785,1528,1528,1528,1528,1528,1528,1528, +1528,785,785,1528,1528,1528,1528,1528,1528,1528,1528,1528,785,1528,1528,1528, +1528,1528,785,785,785,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,785,785,785,1528,1528,1528,1528,1528,1528,1528,1528,785,785,785,1528, +1528,785,1528,785,1528,1528,1528,1528,785,1528,1528,1528,1528,1528,1528,785, +1528,1528,1528,785,1528,1528,1528,1528,1528,1528,785,1529,1529,1529,1529,1529, /* block 288 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1538,1538,1538,1529,1529,1529,1538,1538,1538,1538,1538, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, /* block 289 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,163,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1421,1421,1421,1421,1421,1421,1421,1421,1421,1421,163,163,163,163,163,163, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1538,1538,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1538,1529,1529,1529,1529,1529,1528,1528,1528,1528,1528,785,1538,785,785,785, +1529,1529,1529,1528,1528,1529,1529,1529,1530,1530,1530,1530,1529,1529,1529,1529, +785,785,785,785,785,785,1528,1528,1528,785,1528,1529,1529,1530,1530,1530, +785,1528,1528,785,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530, /* block 290 */ -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,957,957, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,1528,1528,1528,1530,1530,1530,1530,1528,1528,1528,1528,1528, /* block 291 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530, +1529,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, /* block 292 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,163,163,163,163,163,163, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +781,781,781,781,781,781,781,781,781,781,781,781,1530,1530,1530,1530, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530,1530,1530, +781,781,781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, /* block 293 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,163,163, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530,1530,1530, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,1530,1530, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530,1530,1530, +1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, /* block 294 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +781,781,781,781,781,781,781,781,781,781,781,781,1538,1529,1529,1538, +1529,1529,1529,1529,1529,1529,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538, +1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,781,1538,1538,1538,1529, +1529,1529,1529,1529,1529,1529,781,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529, /* block 295 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1541,1541,1541,1541,1529,1538,1538,1529,1538,1538,1529,1538,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1538,1538,1538, +1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, /* block 296 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530, /* block 297 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,957,957, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530,1530,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +1529,1529,1529,1538,1538,1538,1529,1530,1530,1530,1530,1530,1530,1530,1529,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1529, +1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530,1530,1530, +1538,1538,1538,1538,1538,1538,1538,1538,1538,1530,1530,1530,1530,1530,1530,1530, /* block 298 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,163,163,163,163,163, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,196,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +1479,1479,1479,1479,1479,1479,1479,1479,1479,1479,196,196,196,196,196,196, /* block 299 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1032,1032, /* block 300 */ -708,713,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, /* block 301 */ -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,196,196,196,196,196,196, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, /* block 302 */ -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,196,196, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, /* block 303 */ -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, -708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, /* block 304 */ -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,957,957, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, + +/* block 305 */ +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, + +/* block 306 */ +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, + +/* block 307 */ +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,1032,1032, + +/* block 308 */ +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,196,196,196,196,196, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, + +/* block 309 */ +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, + +/* block 310 */ +765,770,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, +1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, +1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, +1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, +1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, +1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, + +/* block 311 */ +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, + +/* block 312 */ +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, + +/* block 313 */ +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, +765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, + +/* block 314 */ +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1032,1032, }; #if UCD_BLOCK_SIZE != 128 diff --git a/ext/pcre/pcre2lib/pcre2_ucp.h b/ext/pcre/pcre2lib/pcre2_ucp.h index 9ccc82975080e..513c54e29e6b7 100644 --- a/ext/pcre/pcre2lib/pcre2_ucp.h +++ b/ext/pcre/pcre2lib/pcre2_ucp.h @@ -132,13 +132,18 @@ enum { ucp_Hex_Digit, ucp_IDS_Binary_Operator, ucp_IDS_Trinary_Operator, + ucp_IDS_Unary_Operator, + ucp_ID_Compat_Math_Continue, + ucp_ID_Compat_Math_Start, ucp_ID_Continue, ucp_ID_Start, ucp_Ideographic, + ucp_InCB, ucp_Join_Control, ucp_Logical_Order_Exception, ucp_Lowercase, ucp_Math, + ucp_Modifier_Combining_Mark, ucp_Noncharacter_Code_Point, ucp_Pattern_Syntax, ucp_Pattern_White_Space, @@ -219,6 +224,8 @@ enum { ucp_Latin, ucp_Greek, ucp_Cyrillic, + ucp_Armenian, + ucp_Hebrew, ucp_Arabic, ucp_Syriac, ucp_Thaana, @@ -232,15 +239,21 @@ enum { ucp_Kannada, ucp_Malayalam, ucp_Sinhala, + ucp_Thai, + ucp_Tibetan, ucp_Myanmar, ucp_Georgian, ucp_Hangul, + ucp_Ethiopic, + ucp_Cherokee, + ucp_Runic, ucp_Mongolian, ucp_Hiragana, ucp_Katakana, ucp_Bopomofo, ucp_Han, ucp_Yi, + ucp_Gothic, ucp_Tagalog, ucp_Hanunoo, ucp_Buhid, @@ -248,21 +261,33 @@ enum { ucp_Limbu, ucp_Tai_Le, ucp_Linear_B, + ucp_Shavian, ucp_Cypriot, ucp_Buginese, ucp_Coptic, ucp_Glagolitic, + ucp_Tifinagh, ucp_Syloti_Nagri, ucp_Phags_Pa, ucp_Nko, ucp_Kayah_Li, + ucp_Lycian, + ucp_Carian, + ucp_Lydian, + ucp_Avestan, + ucp_Samaritan, + ucp_Lisu, ucp_Javanese, + ucp_Old_Turkic, ucp_Kaithi, ucp_Mandaic, ucp_Chakma, + ucp_Meroitic_Hieroglyphs, ucp_Sharada, ucp_Takri, + ucp_Caucasian_Albanian, ucp_Duployan, + ucp_Elbasan, ucp_Grantha, ucp_Khojki, ucp_Linear_A, @@ -274,7 +299,10 @@ enum { ucp_Khudawadi, ucp_Tirhuta, ucp_Multani, + ucp_Old_Hungarian, ucp_Adlam, + ucp_Osage, + ucp_Tangut, ucp_Masaram_Gondi, ucp_Dogra, ucp_Gunjala_Gondi, @@ -284,31 +312,28 @@ enum { ucp_Yezidi, ucp_Cypro_Minoan, ucp_Old_Uyghur, + ucp_Toto, + ucp_Garay, + ucp_Gurung_Khema, + ucp_Ol_Onal, + ucp_Sunuwar, + ucp_Todhri, + ucp_Tulu_Tigalari, /* Scripts which has no characters in other scripts. */ ucp_Unknown, ucp_Common, - ucp_Armenian, - ucp_Hebrew, - ucp_Thai, ucp_Lao, - ucp_Tibetan, - ucp_Ethiopic, - ucp_Cherokee, ucp_Canadian_Aboriginal, ucp_Ogham, - ucp_Runic, ucp_Khmer, ucp_Old_Italic, - ucp_Gothic, ucp_Deseret, ucp_Inherited, ucp_Ugaritic, - ucp_Shavian, ucp_Osmanya, ucp_Braille, ucp_New_Tai_Lue, - ucp_Tifinagh, ucp_Old_Persian, ucp_Kharoshthi, ucp_Balinese, @@ -320,32 +345,22 @@ enum { ucp_Vai, ucp_Saurashtra, ucp_Rejang, - ucp_Lycian, - ucp_Carian, - ucp_Lydian, ucp_Cham, ucp_Tai_Tham, ucp_Tai_Viet, - ucp_Avestan, ucp_Egyptian_Hieroglyphs, - ucp_Samaritan, - ucp_Lisu, ucp_Bamum, ucp_Meetei_Mayek, ucp_Imperial_Aramaic, ucp_Old_South_Arabian, ucp_Inscriptional_Parthian, ucp_Inscriptional_Pahlavi, - ucp_Old_Turkic, ucp_Batak, ucp_Brahmi, ucp_Meroitic_Cursive, - ucp_Meroitic_Hieroglyphs, ucp_Miao, ucp_Sora_Sompeng, - ucp_Caucasian_Albanian, ucp_Bassa_Vah, - ucp_Elbasan, ucp_Pahawh_Hmong, ucp_Mende_Kikakui, ucp_Mro, @@ -358,13 +373,10 @@ enum { ucp_Ahom, ucp_Anatolian_Hieroglyphs, ucp_Hatran, - ucp_Old_Hungarian, ucp_SignWriting, ucp_Bhaiksuki, ucp_Marchen, ucp_Newa, - ucp_Osage, - ucp_Tangut, ucp_Nushu, ucp_Soyombo, ucp_Zanabazar_Square, @@ -378,10 +390,10 @@ enum { ucp_Dives_Akuru, ucp_Khitan_Small_Script, ucp_Tangsa, - ucp_Toto, ucp_Vithkuqi, ucp_Kawi, ucp_Nag_Mundari, + ucp_Kirat_Rai, /* This must be last */ ucp_Script_Count @@ -389,7 +401,7 @@ enum { /* Size of entries in ucd_script_sets[] */ -#define ucd_script_sets_item_size 3 +#define ucd_script_sets_item_size 4 #endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */ diff --git a/ext/pcre/pcre2lib/pcre2_ucptables.c b/ext/pcre/pcre2lib/pcre2_ucptables.c index 2110014c29ed8..d2b34037bea67 100644 --- a/ext/pcre/pcre2lib/pcre2_ucptables.c +++ b/ext/pcre/pcre2lib/pcre2_ucptables.c @@ -199,6 +199,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_extendedpictographic0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_d STR_p STR_i STR_c STR_t STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c "\0" #define STRING_extender0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_r "\0" #define STRING_extpict0 STR_e STR_x STR_t STR_p STR_i STR_c STR_t "\0" +#define STRING_gara0 STR_g STR_a STR_r STR_a "\0" +#define STRING_garay0 STR_g STR_a STR_r STR_a STR_y "\0" #define STRING_geor0 STR_g STR_e STR_o STR_r "\0" #define STRING_georgian0 STR_g STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0" #define STRING_glag0 STR_g STR_l STR_a STR_g "\0" @@ -219,9 +221,11 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_grlink0 STR_g STR_r STR_l STR_i STR_n STR_k "\0" #define STRING_gujarati0 STR_g STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0" #define STRING_gujr0 STR_g STR_u STR_j STR_r "\0" +#define STRING_gukh0 STR_g STR_u STR_k STR_h "\0" #define STRING_gunjalagondi0 STR_g STR_u STR_n STR_j STR_a STR_l STR_a STR_g STR_o STR_n STR_d STR_i "\0" #define STRING_gurmukhi0 STR_g STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0" #define STRING_guru0 STR_g STR_u STR_r STR_u "\0" +#define STRING_gurungkhema0 STR_g STR_u STR_r STR_u STR_n STR_g STR_k STR_h STR_e STR_m STR_a "\0" #define STRING_han0 STR_h STR_a STR_n "\0" #define STRING_hang0 STR_h STR_a STR_n STR_g "\0" #define STRING_hangul0 STR_h STR_a STR_n STR_g STR_u STR_l "\0" @@ -242,6 +246,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_hmnp0 STR_h STR_m STR_n STR_p "\0" #define STRING_hung0 STR_h STR_u STR_n STR_g "\0" #define STRING_idc0 STR_i STR_d STR_c "\0" +#define STRING_idcompatmathcontinue0 STR_i STR_d STR_c STR_o STR_m STR_p STR_a STR_t STR_m STR_a STR_t STR_h STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e "\0" +#define STRING_idcompatmathstart0 STR_i STR_d STR_c STR_o STR_m STR_p STR_a STR_t STR_m STR_a STR_t STR_h STR_s STR_t STR_a STR_r STR_t "\0" #define STRING_idcontinue0 STR_i STR_d STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e "\0" #define STRING_ideo0 STR_i STR_d STR_e STR_o "\0" #define STRING_ideographic0 STR_i STR_d STR_e STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c "\0" @@ -251,7 +257,10 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_idst0 STR_i STR_d STR_s STR_t "\0" #define STRING_idstart0 STR_i STR_d STR_s STR_t STR_a STR_r STR_t "\0" #define STRING_idstrinaryoperator0 STR_i STR_d STR_s STR_t STR_r STR_i STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r "\0" +#define STRING_idsu0 STR_i STR_d STR_s STR_u "\0" +#define STRING_idsunaryoperator0 STR_i STR_d STR_s STR_u STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r "\0" #define STRING_imperialaramaic0 STR_i STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_a STR_r STR_a STR_m STR_a STR_i STR_c "\0" +#define STRING_incb0 STR_i STR_n STR_c STR_b "\0" #define STRING_inherited0 STR_i STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0" #define STRING_inscriptionalpahlavi0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_h STR_l STR_a STR_v STR_i "\0" #define STRING_inscriptionalparthian0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0" @@ -275,8 +284,10 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_khoj0 STR_k STR_h STR_o STR_j "\0" #define STRING_khojki0 STR_k STR_h STR_o STR_j STR_k STR_i "\0" #define STRING_khudawadi0 STR_k STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0" +#define STRING_kiratrai0 STR_k STR_i STR_r STR_a STR_t STR_r STR_a STR_i "\0" #define STRING_kits0 STR_k STR_i STR_t STR_s "\0" #define STRING_knda0 STR_k STR_n STR_d STR_a "\0" +#define STRING_krai0 STR_k STR_r STR_a STR_i "\0" #define STRING_kthi0 STR_k STR_t STR_h STR_i "\0" #define STRING_l0 STR_l "\0" #define STRING_l_AMPERSAND0 STR_l STR_AMPERSAND "\0" @@ -323,6 +334,7 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_masaramgondi0 STR_m STR_a STR_s STR_a STR_r STR_a STR_m STR_g STR_o STR_n STR_d STR_i "\0" #define STRING_math0 STR_m STR_a STR_t STR_h "\0" #define STRING_mc0 STR_m STR_c "\0" +#define STRING_mcm0 STR_m STR_c STR_m "\0" #define STRING_me0 STR_m STR_e "\0" #define STRING_medefaidrin0 STR_m STR_e STR_d STR_e STR_f STR_a STR_i STR_d STR_r STR_i STR_n "\0" #define STRING_medf0 STR_m STR_e STR_d STR_f "\0" @@ -337,6 +349,7 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_mlym0 STR_m STR_l STR_y STR_m "\0" #define STRING_mn0 STR_m STR_n "\0" #define STRING_modi0 STR_m STR_o STR_d STR_i "\0" +#define STRING_modifiercombiningmark0 STR_m STR_o STR_d STR_i STR_f STR_i STR_e STR_r STR_c STR_o STR_m STR_b STR_i STR_n STR_i STR_n STR_g STR_m STR_a STR_r STR_k "\0" #define STRING_mong0 STR_m STR_o STR_n STR_g "\0" #define STRING_mongolian0 STR_m STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0" #define STRING_mro0 STR_m STR_r STR_o "\0" @@ -379,6 +392,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_oldsoutharabian0 STR_o STR_l STR_d STR_s STR_o STR_u STR_t STR_h STR_a STR_r STR_a STR_b STR_i STR_a STR_n "\0" #define STRING_oldturkic0 STR_o STR_l STR_d STR_t STR_u STR_r STR_k STR_i STR_c "\0" #define STRING_olduyghur0 STR_o STR_l STR_d STR_u STR_y STR_g STR_h STR_u STR_r "\0" +#define STRING_olonal0 STR_o STR_l STR_o STR_n STR_a STR_l "\0" +#define STRING_onao0 STR_o STR_n STR_a STR_o "\0" #define STRING_oriya0 STR_o STR_r STR_i STR_y STR_a "\0" #define STRING_orkh0 STR_o STR_r STR_k STR_h "\0" #define STRING_orya0 STR_o STR_r STR_y STR_a "\0" @@ -463,6 +478,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_sterm0 STR_s STR_t STR_e STR_r STR_m "\0" #define STRING_sund0 STR_s STR_u STR_n STR_d "\0" #define STRING_sundanese0 STR_s STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0" +#define STRING_sunu0 STR_s STR_u STR_n STR_u "\0" +#define STRING_sunuwar0 STR_s STR_u STR_n STR_u STR_w STR_a STR_r "\0" #define STRING_sylo0 STR_s STR_y STR_l STR_o "\0" #define STRING_sylotinagri0 STR_s STR_y STR_l STR_o STR_t STR_i STR_n STR_a STR_g STR_r STR_i "\0" #define STRING_syrc0 STR_s STR_y STR_r STR_c "\0" @@ -498,7 +515,11 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_tirh0 STR_t STR_i STR_r STR_h "\0" #define STRING_tirhuta0 STR_t STR_i STR_r STR_h STR_u STR_t STR_a "\0" #define STRING_tnsa0 STR_t STR_n STR_s STR_a "\0" +#define STRING_todhri0 STR_t STR_o STR_d STR_h STR_r STR_i "\0" +#define STRING_todr0 STR_t STR_o STR_d STR_r "\0" #define STRING_toto0 STR_t STR_o STR_t STR_o "\0" +#define STRING_tulutigalari0 STR_t STR_u STR_l STR_u STR_t STR_i STR_g STR_a STR_l STR_a STR_r STR_i "\0" +#define STRING_tutg0 STR_t STR_u STR_t STR_g "\0" #define STRING_ugar0 STR_u STR_g STR_a STR_r "\0" #define STRING_ugaritic0 STR_u STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0" #define STRING_uideo0 STR_u STR_i STR_d STR_e STR_o "\0" @@ -690,6 +711,8 @@ const char PRIV(utt_names)[] = STRING_extendedpictographic0 STRING_extender0 STRING_extpict0 + STRING_gara0 + STRING_garay0 STRING_geor0 STRING_georgian0 STRING_glag0 @@ -710,9 +733,11 @@ const char PRIV(utt_names)[] = STRING_grlink0 STRING_gujarati0 STRING_gujr0 + STRING_gukh0 STRING_gunjalagondi0 STRING_gurmukhi0 STRING_guru0 + STRING_gurungkhema0 STRING_han0 STRING_hang0 STRING_hangul0 @@ -733,6 +758,8 @@ const char PRIV(utt_names)[] = STRING_hmnp0 STRING_hung0 STRING_idc0 + STRING_idcompatmathcontinue0 + STRING_idcompatmathstart0 STRING_idcontinue0 STRING_ideo0 STRING_ideographic0 @@ -742,7 +769,10 @@ const char PRIV(utt_names)[] = STRING_idst0 STRING_idstart0 STRING_idstrinaryoperator0 + STRING_idsu0 + STRING_idsunaryoperator0 STRING_imperialaramaic0 + STRING_incb0 STRING_inherited0 STRING_inscriptionalpahlavi0 STRING_inscriptionalparthian0 @@ -766,8 +796,10 @@ const char PRIV(utt_names)[] = STRING_khoj0 STRING_khojki0 STRING_khudawadi0 + STRING_kiratrai0 STRING_kits0 STRING_knda0 + STRING_krai0 STRING_kthi0 STRING_l0 STRING_l_AMPERSAND0 @@ -814,6 +846,7 @@ const char PRIV(utt_names)[] = STRING_masaramgondi0 STRING_math0 STRING_mc0 + STRING_mcm0 STRING_me0 STRING_medefaidrin0 STRING_medf0 @@ -828,6 +861,7 @@ const char PRIV(utt_names)[] = STRING_mlym0 STRING_mn0 STRING_modi0 + STRING_modifiercombiningmark0 STRING_mong0 STRING_mongolian0 STRING_mro0 @@ -870,6 +904,8 @@ const char PRIV(utt_names)[] = STRING_oldsoutharabian0 STRING_oldturkic0 STRING_olduyghur0 + STRING_olonal0 + STRING_onao0 STRING_oriya0 STRING_orkh0 STRING_orya0 @@ -954,6 +990,8 @@ const char PRIV(utt_names)[] = STRING_sterm0 STRING_sund0 STRING_sundanese0 + STRING_sunu0 + STRING_sunuwar0 STRING_sylo0 STRING_sylotinagri0 STRING_syrc0 @@ -989,7 +1027,11 @@ const char PRIV(utt_names)[] = STRING_tirh0 STRING_tirhuta0 STRING_tnsa0 + STRING_todhri0 + STRING_todr0 STRING_toto0 + STRING_tulutigalari0 + STRING_tutg0 STRING_ugar0 STRING_ugaritic0 STRING_uideo0 @@ -1037,7 +1079,7 @@ const char PRIV(utt_names)[] = const ucp_type_table PRIV(utt)[] = { { 0, PT_SCX, ucp_Adlam }, { 6, PT_SCX, ucp_Adlam }, - { 11, PT_SC, ucp_Caucasian_Albanian }, + { 11, PT_SCX, ucp_Caucasian_Albanian }, { 16, PT_BOOL, ucp_ASCII_Hex_Digit }, { 21, PT_SC, ucp_Ahom }, { 26, PT_BOOL, ucp_Alphabetic }, @@ -1046,13 +1088,13 @@ const ucp_type_table PRIV(utt)[] = { { 64, PT_ANY, 0 }, { 68, PT_SCX, ucp_Arabic }, { 73, PT_SCX, ucp_Arabic }, - { 80, PT_SC, ucp_Armenian }, + { 80, PT_SCX, ucp_Armenian }, { 89, PT_SC, ucp_Imperial_Aramaic }, - { 94, PT_SC, ucp_Armenian }, + { 94, PT_SCX, ucp_Armenian }, { 99, PT_BOOL, ucp_ASCII }, { 105, PT_BOOL, ucp_ASCII_Hex_Digit }, - { 119, PT_SC, ucp_Avestan }, - { 127, PT_SC, ucp_Avestan }, + { 119, PT_SCX, ucp_Avestan }, + { 127, PT_SCX, ucp_Avestan }, { 132, PT_SC, ucp_Balinese }, { 137, PT_SC, ucp_Balinese }, { 146, PT_SC, ucp_Bamum }, @@ -1106,11 +1148,11 @@ const ucp_type_table PRIV(utt)[] = { { 480, PT_SCX, ucp_Chakma }, { 485, PT_SC, ucp_Canadian_Aboriginal }, { 504, PT_SC, ucp_Canadian_Aboriginal }, - { 509, PT_SC, ucp_Carian }, - { 514, PT_SC, ucp_Carian }, + { 509, PT_SCX, ucp_Carian }, + { 514, PT_SCX, ucp_Carian }, { 521, PT_BOOL, ucp_Cased }, { 527, PT_BOOL, ucp_Case_Ignorable }, - { 541, PT_SC, ucp_Caucasian_Albanian }, + { 541, PT_SCX, ucp_Caucasian_Albanian }, { 559, PT_PC, ucp_Cc }, { 562, PT_PC, ucp_Cf }, { 565, PT_SCX, ucp_Chakma }, @@ -1120,8 +1162,8 @@ const ucp_type_table PRIV(utt)[] = { { 621, PT_BOOL, ucp_Changes_When_Lowercased }, { 643, PT_BOOL, ucp_Changes_When_Titlecased }, { 665, PT_BOOL, ucp_Changes_When_Uppercased }, - { 687, PT_SC, ucp_Cherokee }, - { 692, PT_SC, ucp_Cherokee }, + { 687, PT_SCX, ucp_Cherokee }, + { 692, PT_SCX, ucp_Cherokee }, { 701, PT_SC, ucp_Chorasmian }, { 712, PT_SC, ucp_Chorasmian }, { 717, PT_BOOL, ucp_Case_Ignorable }, @@ -1164,8 +1206,8 @@ const ucp_type_table PRIV(utt)[] = { { 963, PT_BOOL, ucp_Emoji_Component }, { 969, PT_SC, ucp_Egyptian_Hieroglyphs }, { 974, PT_SC, ucp_Egyptian_Hieroglyphs }, - { 994, PT_SC, ucp_Elbasan }, - { 999, PT_SC, ucp_Elbasan }, + { 994, PT_SCX, ucp_Elbasan }, + { 999, PT_SCX, ucp_Elbasan }, { 1007, PT_SC, ucp_Elymaic }, { 1012, PT_SC, ucp_Elymaic }, { 1020, PT_BOOL, ucp_Emoji_Modifier }, @@ -1175,355 +1217,376 @@ const ucp_type_table PRIV(utt)[] = { { 1060, PT_BOOL, ucp_Emoji_Modifier_Base }, { 1078, PT_BOOL, ucp_Emoji_Presentation }, { 1096, PT_BOOL, ucp_Emoji_Presentation }, - { 1102, PT_SC, ucp_Ethiopic }, - { 1107, PT_SC, ucp_Ethiopic }, + { 1102, PT_SCX, ucp_Ethiopic }, + { 1107, PT_SCX, ucp_Ethiopic }, { 1116, PT_BOOL, ucp_Extender }, { 1120, PT_BOOL, ucp_Extended_Pictographic }, { 1141, PT_BOOL, ucp_Extender }, { 1150, PT_BOOL, ucp_Extended_Pictographic }, - { 1158, PT_SCX, ucp_Georgian }, - { 1163, PT_SCX, ucp_Georgian }, - { 1172, PT_SCX, ucp_Glagolitic }, - { 1177, PT_SCX, ucp_Glagolitic }, - { 1188, PT_SCX, ucp_Gunjala_Gondi }, - { 1193, PT_SCX, ucp_Masaram_Gondi }, - { 1198, PT_SC, ucp_Gothic }, - { 1203, PT_SC, ucp_Gothic }, - { 1210, PT_SCX, ucp_Grantha }, - { 1215, PT_SCX, ucp_Grantha }, - { 1223, PT_BOOL, ucp_Grapheme_Base }, - { 1236, PT_BOOL, ucp_Grapheme_Extend }, - { 1251, PT_BOOL, ucp_Grapheme_Link }, - { 1264, PT_BOOL, ucp_Grapheme_Base }, - { 1271, PT_SCX, ucp_Greek }, - { 1277, PT_SCX, ucp_Greek }, - { 1282, PT_BOOL, ucp_Grapheme_Extend }, - { 1288, PT_BOOL, ucp_Grapheme_Link }, - { 1295, PT_SCX, ucp_Gujarati }, - { 1304, PT_SCX, ucp_Gujarati }, - { 1309, PT_SCX, ucp_Gunjala_Gondi }, - { 1322, PT_SCX, ucp_Gurmukhi }, - { 1331, PT_SCX, ucp_Gurmukhi }, - { 1336, PT_SCX, ucp_Han }, - { 1340, PT_SCX, ucp_Hangul }, - { 1345, PT_SCX, ucp_Hangul }, - { 1352, PT_SCX, ucp_Han }, - { 1357, PT_SCX, ucp_Hanifi_Rohingya }, - { 1372, PT_SCX, ucp_Hanunoo }, - { 1377, PT_SCX, ucp_Hanunoo }, - { 1385, PT_SC, ucp_Hatran }, - { 1390, PT_SC, ucp_Hatran }, - { 1397, PT_SC, ucp_Hebrew }, - { 1402, PT_SC, ucp_Hebrew }, - { 1409, PT_BOOL, ucp_Hex_Digit }, - { 1413, PT_BOOL, ucp_Hex_Digit }, - { 1422, PT_SCX, ucp_Hiragana }, - { 1427, PT_SCX, ucp_Hiragana }, - { 1436, PT_SC, ucp_Anatolian_Hieroglyphs }, - { 1441, PT_SC, ucp_Pahawh_Hmong }, - { 1446, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, - { 1451, PT_SC, ucp_Old_Hungarian }, - { 1456, PT_BOOL, ucp_ID_Continue }, - { 1460, PT_BOOL, ucp_ID_Continue }, - { 1471, PT_BOOL, ucp_Ideographic }, - { 1476, PT_BOOL, ucp_Ideographic }, - { 1488, PT_BOOL, ucp_ID_Start }, - { 1492, PT_BOOL, ucp_IDS_Binary_Operator }, - { 1497, PT_BOOL, ucp_IDS_Binary_Operator }, - { 1515, PT_BOOL, ucp_IDS_Trinary_Operator }, - { 1520, PT_BOOL, ucp_ID_Start }, - { 1528, PT_BOOL, ucp_IDS_Trinary_Operator }, - { 1547, PT_SC, ucp_Imperial_Aramaic }, - { 1563, PT_SC, ucp_Inherited }, - { 1573, PT_SC, ucp_Inscriptional_Pahlavi }, - { 1594, PT_SC, ucp_Inscriptional_Parthian }, - { 1616, PT_SC, ucp_Old_Italic }, - { 1621, PT_SCX, ucp_Javanese }, - { 1626, PT_SCX, ucp_Javanese }, - { 1635, PT_BOOL, ucp_Join_Control }, - { 1641, PT_BOOL, ucp_Join_Control }, - { 1653, PT_SCX, ucp_Kaithi }, - { 1660, PT_SCX, ucp_Kayah_Li }, - { 1665, PT_SCX, ucp_Katakana }, - { 1670, PT_SCX, ucp_Kannada }, - { 1678, PT_SCX, ucp_Katakana }, - { 1687, PT_SC, ucp_Kawi }, - { 1692, PT_SCX, ucp_Kayah_Li }, - { 1700, PT_SC, ucp_Kharoshthi }, - { 1705, PT_SC, ucp_Kharoshthi }, - { 1716, PT_SC, ucp_Khitan_Small_Script }, - { 1734, PT_SC, ucp_Khmer }, - { 1740, PT_SC, ucp_Khmer }, - { 1745, PT_SCX, ucp_Khojki }, - { 1750, PT_SCX, ucp_Khojki }, - { 1757, PT_SCX, ucp_Khudawadi }, - { 1767, PT_SC, ucp_Khitan_Small_Script }, - { 1772, PT_SCX, ucp_Kannada }, - { 1777, PT_SCX, ucp_Kaithi }, - { 1782, PT_GC, ucp_L }, - { 1784, PT_LAMP, 0 }, - { 1787, PT_SC, ucp_Tai_Tham }, - { 1792, PT_SC, ucp_Lao }, - { 1796, PT_SC, ucp_Lao }, - { 1801, PT_SCX, ucp_Latin }, - { 1807, PT_SCX, ucp_Latin }, - { 1812, PT_LAMP, 0 }, - { 1815, PT_SC, ucp_Lepcha }, - { 1820, PT_SC, ucp_Lepcha }, - { 1827, PT_SCX, ucp_Limbu }, - { 1832, PT_SCX, ucp_Limbu }, - { 1838, PT_SCX, ucp_Linear_A }, - { 1843, PT_SCX, ucp_Linear_B }, - { 1848, PT_SCX, ucp_Linear_A }, - { 1856, PT_SCX, ucp_Linear_B }, - { 1864, PT_SC, ucp_Lisu }, - { 1869, PT_PC, ucp_Ll }, - { 1872, PT_PC, ucp_Lm }, - { 1875, PT_PC, ucp_Lo }, - { 1878, PT_BOOL, ucp_Logical_Order_Exception }, - { 1882, PT_BOOL, ucp_Logical_Order_Exception }, - { 1904, PT_BOOL, ucp_Lowercase }, - { 1910, PT_BOOL, ucp_Lowercase }, - { 1920, PT_PC, ucp_Lt }, - { 1923, PT_PC, ucp_Lu }, - { 1926, PT_SC, ucp_Lycian }, - { 1931, PT_SC, ucp_Lycian }, - { 1938, PT_SC, ucp_Lydian }, - { 1943, PT_SC, ucp_Lydian }, - { 1950, PT_GC, ucp_M }, - { 1952, PT_SCX, ucp_Mahajani }, - { 1961, PT_SCX, ucp_Mahajani }, - { 1966, PT_SC, ucp_Makasar }, - { 1971, PT_SC, ucp_Makasar }, - { 1979, PT_SCX, ucp_Malayalam }, - { 1989, PT_SCX, ucp_Mandaic }, - { 1994, PT_SCX, ucp_Mandaic }, - { 2002, PT_SCX, ucp_Manichaean }, - { 2007, PT_SCX, ucp_Manichaean }, - { 2018, PT_SC, ucp_Marchen }, - { 2023, PT_SC, ucp_Marchen }, - { 2031, PT_SCX, ucp_Masaram_Gondi }, - { 2044, PT_BOOL, ucp_Math }, - { 2049, PT_PC, ucp_Mc }, - { 2052, PT_PC, ucp_Me }, - { 2055, PT_SC, ucp_Medefaidrin }, - { 2067, PT_SC, ucp_Medefaidrin }, - { 2072, PT_SC, ucp_Meetei_Mayek }, - { 2084, PT_SC, ucp_Mende_Kikakui }, - { 2089, PT_SC, ucp_Mende_Kikakui }, - { 2102, PT_SC, ucp_Meroitic_Cursive }, - { 2107, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 2112, PT_SC, ucp_Meroitic_Cursive }, - { 2128, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 2148, PT_SC, ucp_Miao }, - { 2153, PT_SCX, ucp_Malayalam }, - { 2158, PT_PC, ucp_Mn }, - { 2161, PT_SCX, ucp_Modi }, - { 2166, PT_SCX, ucp_Mongolian }, - { 2171, PT_SCX, ucp_Mongolian }, - { 2181, PT_SC, ucp_Mro }, - { 2185, PT_SC, ucp_Mro }, - { 2190, PT_SC, ucp_Meetei_Mayek }, - { 2195, PT_SCX, ucp_Multani }, - { 2200, PT_SCX, ucp_Multani }, - { 2208, PT_SCX, ucp_Myanmar }, - { 2216, PT_SCX, ucp_Myanmar }, - { 2221, PT_GC, ucp_N }, - { 2223, PT_SC, ucp_Nabataean }, - { 2233, PT_SC, ucp_Nag_Mundari }, - { 2238, PT_SC, ucp_Nag_Mundari }, - { 2249, PT_SCX, ucp_Nandinagari }, - { 2254, PT_SCX, ucp_Nandinagari }, - { 2266, PT_SC, ucp_Old_North_Arabian }, - { 2271, PT_SC, ucp_Nabataean }, - { 2276, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2282, PT_PC, ucp_Nd }, - { 2285, PT_SC, ucp_Newa }, - { 2290, PT_SC, ucp_New_Tai_Lue }, - { 2300, PT_SCX, ucp_Nko }, - { 2304, PT_SCX, ucp_Nko }, - { 2309, PT_PC, ucp_Nl }, - { 2312, PT_PC, ucp_No }, - { 2315, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2337, PT_SC, ucp_Nushu }, - { 2342, PT_SC, ucp_Nushu }, - { 2348, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, - { 2369, PT_SC, ucp_Ogham }, - { 2374, PT_SC, ucp_Ogham }, - { 2380, PT_SC, ucp_Ol_Chiki }, - { 2388, PT_SC, ucp_Ol_Chiki }, - { 2393, PT_SC, ucp_Old_Hungarian }, - { 2406, PT_SC, ucp_Old_Italic }, - { 2416, PT_SC, ucp_Old_North_Arabian }, - { 2432, PT_SCX, ucp_Old_Permic }, - { 2442, PT_SC, ucp_Old_Persian }, - { 2453, PT_SC, ucp_Old_Sogdian }, - { 2464, PT_SC, ucp_Old_South_Arabian }, - { 2480, PT_SC, ucp_Old_Turkic }, - { 2490, PT_SCX, ucp_Old_Uyghur }, - { 2500, PT_SCX, ucp_Oriya }, - { 2506, PT_SC, ucp_Old_Turkic }, - { 2511, PT_SCX, ucp_Oriya }, - { 2516, PT_SC, ucp_Osage }, - { 2522, PT_SC, ucp_Osage }, - { 2527, PT_SC, ucp_Osmanya }, - { 2532, PT_SC, ucp_Osmanya }, - { 2540, PT_SCX, ucp_Old_Uyghur }, - { 2545, PT_GC, ucp_P }, - { 2547, PT_SC, ucp_Pahawh_Hmong }, - { 2559, PT_SC, ucp_Palmyrene }, - { 2564, PT_SC, ucp_Palmyrene }, - { 2574, PT_BOOL, ucp_Pattern_Syntax }, - { 2581, PT_BOOL, ucp_Pattern_Syntax }, - { 2595, PT_BOOL, ucp_Pattern_White_Space }, - { 2613, PT_BOOL, ucp_Pattern_White_Space }, - { 2619, PT_SC, ucp_Pau_Cin_Hau }, - { 2624, PT_SC, ucp_Pau_Cin_Hau }, - { 2634, PT_PC, ucp_Pc }, - { 2637, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2641, PT_PC, ucp_Pd }, - { 2644, PT_PC, ucp_Pe }, - { 2647, PT_SCX, ucp_Old_Permic }, - { 2652, PT_PC, ucp_Pf }, - { 2655, PT_SCX, ucp_Phags_Pa }, - { 2660, PT_SCX, ucp_Phags_Pa }, - { 2668, PT_SC, ucp_Inscriptional_Pahlavi }, - { 2673, PT_SCX, ucp_Psalter_Pahlavi }, - { 2678, PT_SC, ucp_Phoenician }, - { 2683, PT_SC, ucp_Phoenician }, - { 2694, PT_PC, ucp_Pi }, - { 2697, PT_SC, ucp_Miao }, - { 2702, PT_PC, ucp_Po }, - { 2705, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2732, PT_SC, ucp_Inscriptional_Parthian }, - { 2737, PT_PC, ucp_Ps }, - { 2740, PT_SCX, ucp_Psalter_Pahlavi }, - { 2755, PT_SCX, ucp_Coptic }, - { 2760, PT_SC, ucp_Inherited }, - { 2765, PT_BOOL, ucp_Quotation_Mark }, - { 2771, PT_BOOL, ucp_Quotation_Mark }, - { 2785, PT_BOOL, ucp_Radical }, - { 2793, PT_BOOL, ucp_Regional_Indicator }, - { 2811, PT_SC, ucp_Rejang }, - { 2818, PT_BOOL, ucp_Regional_Indicator }, - { 2821, PT_SC, ucp_Rejang }, - { 2826, PT_SCX, ucp_Hanifi_Rohingya }, - { 2831, PT_SC, ucp_Runic }, - { 2837, PT_SC, ucp_Runic }, - { 2842, PT_GC, ucp_S }, - { 2844, PT_SC, ucp_Samaritan }, - { 2854, PT_SC, ucp_Samaritan }, - { 2859, PT_SC, ucp_Old_South_Arabian }, - { 2864, PT_SC, ucp_Saurashtra }, - { 2869, PT_SC, ucp_Saurashtra }, - { 2880, PT_PC, ucp_Sc }, - { 2883, PT_BOOL, ucp_Soft_Dotted }, - { 2886, PT_BOOL, ucp_Sentence_Terminal }, - { 2903, PT_SC, ucp_SignWriting }, - { 2908, PT_SCX, ucp_Sharada }, - { 2916, PT_SC, ucp_Shavian }, - { 2924, PT_SC, ucp_Shavian }, - { 2929, PT_SCX, ucp_Sharada }, - { 2934, PT_SC, ucp_Siddham }, - { 2939, PT_SC, ucp_Siddham }, - { 2947, PT_SC, ucp_SignWriting }, - { 2959, PT_SCX, ucp_Khudawadi }, - { 2964, PT_SCX, ucp_Sinhala }, - { 2969, PT_SCX, ucp_Sinhala }, - { 2977, PT_PC, ucp_Sk }, - { 2980, PT_PC, ucp_Sm }, - { 2983, PT_PC, ucp_So }, - { 2986, PT_BOOL, ucp_Soft_Dotted }, - { 2997, PT_SCX, ucp_Sogdian }, - { 3002, PT_SCX, ucp_Sogdian }, - { 3010, PT_SC, ucp_Old_Sogdian }, - { 3015, PT_SC, ucp_Sora_Sompeng }, - { 3020, PT_SC, ucp_Sora_Sompeng }, - { 3032, PT_SC, ucp_Soyombo }, - { 3037, PT_SC, ucp_Soyombo }, - { 3045, PT_BOOL, ucp_White_Space }, - { 3051, PT_BOOL, ucp_Sentence_Terminal }, - { 3057, PT_SC, ucp_Sundanese }, - { 3062, PT_SC, ucp_Sundanese }, - { 3072, PT_SCX, ucp_Syloti_Nagri }, - { 3077, PT_SCX, ucp_Syloti_Nagri }, - { 3089, PT_SCX, ucp_Syriac }, - { 3094, PT_SCX, ucp_Syriac }, - { 3101, PT_SCX, ucp_Tagalog }, - { 3109, PT_SCX, ucp_Tagbanwa }, - { 3114, PT_SCX, ucp_Tagbanwa }, - { 3123, PT_SCX, ucp_Tai_Le }, - { 3129, PT_SC, ucp_Tai_Tham }, - { 3137, PT_SC, ucp_Tai_Viet }, - { 3145, PT_SCX, ucp_Takri }, - { 3150, PT_SCX, ucp_Takri }, - { 3156, PT_SCX, ucp_Tai_Le }, - { 3161, PT_SC, ucp_New_Tai_Lue }, - { 3166, PT_SCX, ucp_Tamil }, - { 3172, PT_SCX, ucp_Tamil }, - { 3177, PT_SC, ucp_Tangut }, - { 3182, PT_SC, ucp_Tangsa }, - { 3189, PT_SC, ucp_Tangut }, - { 3196, PT_SC, ucp_Tai_Viet }, - { 3201, PT_SCX, ucp_Telugu }, - { 3206, PT_SCX, ucp_Telugu }, - { 3213, PT_BOOL, ucp_Terminal_Punctuation }, - { 3218, PT_BOOL, ucp_Terminal_Punctuation }, - { 3238, PT_SC, ucp_Tifinagh }, - { 3243, PT_SCX, ucp_Tagalog }, - { 3248, PT_SCX, ucp_Thaana }, - { 3253, PT_SCX, ucp_Thaana }, - { 3260, PT_SC, ucp_Thai }, - { 3265, PT_SC, ucp_Tibetan }, - { 3273, PT_SC, ucp_Tibetan }, - { 3278, PT_SC, ucp_Tifinagh }, - { 3287, PT_SCX, ucp_Tirhuta }, - { 3292, PT_SCX, ucp_Tirhuta }, - { 3300, PT_SC, ucp_Tangsa }, - { 3305, PT_SC, ucp_Toto }, - { 3310, PT_SC, ucp_Ugaritic }, - { 3315, PT_SC, ucp_Ugaritic }, - { 3324, PT_BOOL, ucp_Unified_Ideograph }, - { 3330, PT_BOOL, ucp_Unified_Ideograph }, - { 3347, PT_SC, ucp_Unknown }, - { 3355, PT_BOOL, ucp_Uppercase }, - { 3361, PT_BOOL, ucp_Uppercase }, - { 3371, PT_SC, ucp_Vai }, - { 3375, PT_SC, ucp_Vai }, - { 3380, PT_BOOL, ucp_Variation_Selector }, - { 3398, PT_SC, ucp_Vithkuqi }, - { 3403, PT_SC, ucp_Vithkuqi }, - { 3412, PT_BOOL, ucp_Variation_Selector }, - { 3415, PT_SC, ucp_Wancho }, - { 3422, PT_SC, ucp_Warang_Citi }, - { 3427, PT_SC, ucp_Warang_Citi }, - { 3438, PT_SC, ucp_Wancho }, - { 3443, PT_BOOL, ucp_White_Space }, - { 3454, PT_BOOL, ucp_White_Space }, - { 3461, PT_ALNUM, 0 }, - { 3465, PT_BOOL, ucp_XID_Continue }, - { 3470, PT_BOOL, ucp_XID_Continue }, - { 3482, PT_BOOL, ucp_XID_Start }, - { 3487, PT_BOOL, ucp_XID_Start }, - { 3496, PT_SC, ucp_Old_Persian }, - { 3501, PT_PXSPACE, 0 }, - { 3505, PT_SPACE, 0 }, - { 3509, PT_SC, ucp_Cuneiform }, - { 3514, PT_UCNC, 0 }, - { 3518, PT_WORD, 0 }, - { 3522, PT_SCX, ucp_Yezidi }, - { 3527, PT_SCX, ucp_Yezidi }, - { 3534, PT_SCX, ucp_Yi }, - { 3537, PT_SCX, ucp_Yi }, - { 3542, PT_GC, ucp_Z }, - { 3544, PT_SC, ucp_Zanabazar_Square }, - { 3560, PT_SC, ucp_Zanabazar_Square }, - { 3565, PT_SC, ucp_Inherited }, - { 3570, PT_PC, ucp_Zl }, - { 3573, PT_PC, ucp_Zp }, - { 3576, PT_PC, ucp_Zs }, - { 3579, PT_SC, ucp_Common }, - { 3584, PT_SC, ucp_Unknown } + { 1158, PT_SCX, ucp_Garay }, + { 1163, PT_SCX, ucp_Garay }, + { 1169, PT_SCX, ucp_Georgian }, + { 1174, PT_SCX, ucp_Georgian }, + { 1183, PT_SCX, ucp_Glagolitic }, + { 1188, PT_SCX, ucp_Glagolitic }, + { 1199, PT_SCX, ucp_Gunjala_Gondi }, + { 1204, PT_SCX, ucp_Masaram_Gondi }, + { 1209, PT_SCX, ucp_Gothic }, + { 1214, PT_SCX, ucp_Gothic }, + { 1221, PT_SCX, ucp_Grantha }, + { 1226, PT_SCX, ucp_Grantha }, + { 1234, PT_BOOL, ucp_Grapheme_Base }, + { 1247, PT_BOOL, ucp_Grapheme_Extend }, + { 1262, PT_BOOL, ucp_Grapheme_Link }, + { 1275, PT_BOOL, ucp_Grapheme_Base }, + { 1282, PT_SCX, ucp_Greek }, + { 1288, PT_SCX, ucp_Greek }, + { 1293, PT_BOOL, ucp_Grapheme_Extend }, + { 1299, PT_BOOL, ucp_Grapheme_Link }, + { 1306, PT_SCX, ucp_Gujarati }, + { 1315, PT_SCX, ucp_Gujarati }, + { 1320, PT_SCX, ucp_Gurung_Khema }, + { 1325, PT_SCX, ucp_Gunjala_Gondi }, + { 1338, PT_SCX, ucp_Gurmukhi }, + { 1347, PT_SCX, ucp_Gurmukhi }, + { 1352, PT_SCX, ucp_Gurung_Khema }, + { 1364, PT_SCX, ucp_Han }, + { 1368, PT_SCX, ucp_Hangul }, + { 1373, PT_SCX, ucp_Hangul }, + { 1380, PT_SCX, ucp_Han }, + { 1385, PT_SCX, ucp_Hanifi_Rohingya }, + { 1400, PT_SCX, ucp_Hanunoo }, + { 1405, PT_SCX, ucp_Hanunoo }, + { 1413, PT_SC, ucp_Hatran }, + { 1418, PT_SC, ucp_Hatran }, + { 1425, PT_SCX, ucp_Hebrew }, + { 1430, PT_SCX, ucp_Hebrew }, + { 1437, PT_BOOL, ucp_Hex_Digit }, + { 1441, PT_BOOL, ucp_Hex_Digit }, + { 1450, PT_SCX, ucp_Hiragana }, + { 1455, PT_SCX, ucp_Hiragana }, + { 1464, PT_SC, ucp_Anatolian_Hieroglyphs }, + { 1469, PT_SC, ucp_Pahawh_Hmong }, + { 1474, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 1479, PT_SCX, ucp_Old_Hungarian }, + { 1484, PT_BOOL, ucp_ID_Continue }, + { 1488, PT_BOOL, ucp_ID_Compat_Math_Continue }, + { 1509, PT_BOOL, ucp_ID_Compat_Math_Start }, + { 1527, PT_BOOL, ucp_ID_Continue }, + { 1538, PT_BOOL, ucp_Ideographic }, + { 1543, PT_BOOL, ucp_Ideographic }, + { 1555, PT_BOOL, ucp_ID_Start }, + { 1559, PT_BOOL, ucp_IDS_Binary_Operator }, + { 1564, PT_BOOL, ucp_IDS_Binary_Operator }, + { 1582, PT_BOOL, ucp_IDS_Trinary_Operator }, + { 1587, PT_BOOL, ucp_ID_Start }, + { 1595, PT_BOOL, ucp_IDS_Trinary_Operator }, + { 1614, PT_BOOL, ucp_IDS_Unary_Operator }, + { 1619, PT_BOOL, ucp_IDS_Unary_Operator }, + { 1636, PT_SC, ucp_Imperial_Aramaic }, + { 1652, PT_BOOL, ucp_InCB }, + { 1657, PT_SC, ucp_Inherited }, + { 1667, PT_SC, ucp_Inscriptional_Pahlavi }, + { 1688, PT_SC, ucp_Inscriptional_Parthian }, + { 1710, PT_SC, ucp_Old_Italic }, + { 1715, PT_SCX, ucp_Javanese }, + { 1720, PT_SCX, ucp_Javanese }, + { 1729, PT_BOOL, ucp_Join_Control }, + { 1735, PT_BOOL, ucp_Join_Control }, + { 1747, PT_SCX, ucp_Kaithi }, + { 1754, PT_SCX, ucp_Kayah_Li }, + { 1759, PT_SCX, ucp_Katakana }, + { 1764, PT_SCX, ucp_Kannada }, + { 1772, PT_SCX, ucp_Katakana }, + { 1781, PT_SC, ucp_Kawi }, + { 1786, PT_SCX, ucp_Kayah_Li }, + { 1794, PT_SC, ucp_Kharoshthi }, + { 1799, PT_SC, ucp_Kharoshthi }, + { 1810, PT_SC, ucp_Khitan_Small_Script }, + { 1828, PT_SC, ucp_Khmer }, + { 1834, PT_SC, ucp_Khmer }, + { 1839, PT_SCX, ucp_Khojki }, + { 1844, PT_SCX, ucp_Khojki }, + { 1851, PT_SCX, ucp_Khudawadi }, + { 1861, PT_SC, ucp_Kirat_Rai }, + { 1870, PT_SC, ucp_Khitan_Small_Script }, + { 1875, PT_SCX, ucp_Kannada }, + { 1880, PT_SC, ucp_Kirat_Rai }, + { 1885, PT_SCX, ucp_Kaithi }, + { 1890, PT_GC, ucp_L }, + { 1892, PT_LAMP, 0 }, + { 1895, PT_SC, ucp_Tai_Tham }, + { 1900, PT_SC, ucp_Lao }, + { 1904, PT_SC, ucp_Lao }, + { 1909, PT_SCX, ucp_Latin }, + { 1915, PT_SCX, ucp_Latin }, + { 1920, PT_LAMP, 0 }, + { 1923, PT_SC, ucp_Lepcha }, + { 1928, PT_SC, ucp_Lepcha }, + { 1935, PT_SCX, ucp_Limbu }, + { 1940, PT_SCX, ucp_Limbu }, + { 1946, PT_SCX, ucp_Linear_A }, + { 1951, PT_SCX, ucp_Linear_B }, + { 1956, PT_SCX, ucp_Linear_A }, + { 1964, PT_SCX, ucp_Linear_B }, + { 1972, PT_SCX, ucp_Lisu }, + { 1977, PT_PC, ucp_Ll }, + { 1980, PT_PC, ucp_Lm }, + { 1983, PT_PC, ucp_Lo }, + { 1986, PT_BOOL, ucp_Logical_Order_Exception }, + { 1990, PT_BOOL, ucp_Logical_Order_Exception }, + { 2012, PT_BOOL, ucp_Lowercase }, + { 2018, PT_BOOL, ucp_Lowercase }, + { 2028, PT_PC, ucp_Lt }, + { 2031, PT_PC, ucp_Lu }, + { 2034, PT_SCX, ucp_Lycian }, + { 2039, PT_SCX, ucp_Lycian }, + { 2046, PT_SCX, ucp_Lydian }, + { 2051, PT_SCX, ucp_Lydian }, + { 2058, PT_GC, ucp_M }, + { 2060, PT_SCX, ucp_Mahajani }, + { 2069, PT_SCX, ucp_Mahajani }, + { 2074, PT_SC, ucp_Makasar }, + { 2079, PT_SC, ucp_Makasar }, + { 2087, PT_SCX, ucp_Malayalam }, + { 2097, PT_SCX, ucp_Mandaic }, + { 2102, PT_SCX, ucp_Mandaic }, + { 2110, PT_SCX, ucp_Manichaean }, + { 2115, PT_SCX, ucp_Manichaean }, + { 2126, PT_SC, ucp_Marchen }, + { 2131, PT_SC, ucp_Marchen }, + { 2139, PT_SCX, ucp_Masaram_Gondi }, + { 2152, PT_BOOL, ucp_Math }, + { 2157, PT_PC, ucp_Mc }, + { 2160, PT_BOOL, ucp_Modifier_Combining_Mark }, + { 2164, PT_PC, ucp_Me }, + { 2167, PT_SC, ucp_Medefaidrin }, + { 2179, PT_SC, ucp_Medefaidrin }, + { 2184, PT_SC, ucp_Meetei_Mayek }, + { 2196, PT_SC, ucp_Mende_Kikakui }, + { 2201, PT_SC, ucp_Mende_Kikakui }, + { 2214, PT_SC, ucp_Meroitic_Cursive }, + { 2219, PT_SCX, ucp_Meroitic_Hieroglyphs }, + { 2224, PT_SC, ucp_Meroitic_Cursive }, + { 2240, PT_SCX, ucp_Meroitic_Hieroglyphs }, + { 2260, PT_SC, ucp_Miao }, + { 2265, PT_SCX, ucp_Malayalam }, + { 2270, PT_PC, ucp_Mn }, + { 2273, PT_SCX, ucp_Modi }, + { 2278, PT_BOOL, ucp_Modifier_Combining_Mark }, + { 2300, PT_SCX, ucp_Mongolian }, + { 2305, PT_SCX, ucp_Mongolian }, + { 2315, PT_SC, ucp_Mro }, + { 2319, PT_SC, ucp_Mro }, + { 2324, PT_SC, ucp_Meetei_Mayek }, + { 2329, PT_SCX, ucp_Multani }, + { 2334, PT_SCX, ucp_Multani }, + { 2342, PT_SCX, ucp_Myanmar }, + { 2350, PT_SCX, ucp_Myanmar }, + { 2355, PT_GC, ucp_N }, + { 2357, PT_SC, ucp_Nabataean }, + { 2367, PT_SC, ucp_Nag_Mundari }, + { 2372, PT_SC, ucp_Nag_Mundari }, + { 2383, PT_SCX, ucp_Nandinagari }, + { 2388, PT_SCX, ucp_Nandinagari }, + { 2400, PT_SC, ucp_Old_North_Arabian }, + { 2405, PT_SC, ucp_Nabataean }, + { 2410, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2416, PT_PC, ucp_Nd }, + { 2419, PT_SC, ucp_Newa }, + { 2424, PT_SC, ucp_New_Tai_Lue }, + { 2434, PT_SCX, ucp_Nko }, + { 2438, PT_SCX, ucp_Nko }, + { 2443, PT_PC, ucp_Nl }, + { 2446, PT_PC, ucp_No }, + { 2449, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2471, PT_SC, ucp_Nushu }, + { 2476, PT_SC, ucp_Nushu }, + { 2482, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 2503, PT_SC, ucp_Ogham }, + { 2508, PT_SC, ucp_Ogham }, + { 2514, PT_SC, ucp_Ol_Chiki }, + { 2522, PT_SC, ucp_Ol_Chiki }, + { 2527, PT_SCX, ucp_Old_Hungarian }, + { 2540, PT_SC, ucp_Old_Italic }, + { 2550, PT_SC, ucp_Old_North_Arabian }, + { 2566, PT_SCX, ucp_Old_Permic }, + { 2576, PT_SC, ucp_Old_Persian }, + { 2587, PT_SC, ucp_Old_Sogdian }, + { 2598, PT_SC, ucp_Old_South_Arabian }, + { 2614, PT_SCX, ucp_Old_Turkic }, + { 2624, PT_SCX, ucp_Old_Uyghur }, + { 2634, PT_SCX, ucp_Ol_Onal }, + { 2641, PT_SCX, ucp_Ol_Onal }, + { 2646, PT_SCX, ucp_Oriya }, + { 2652, PT_SCX, ucp_Old_Turkic }, + { 2657, PT_SCX, ucp_Oriya }, + { 2662, PT_SCX, ucp_Osage }, + { 2668, PT_SCX, ucp_Osage }, + { 2673, PT_SC, ucp_Osmanya }, + { 2678, PT_SC, ucp_Osmanya }, + { 2686, PT_SCX, ucp_Old_Uyghur }, + { 2691, PT_GC, ucp_P }, + { 2693, PT_SC, ucp_Pahawh_Hmong }, + { 2705, PT_SC, ucp_Palmyrene }, + { 2710, PT_SC, ucp_Palmyrene }, + { 2720, PT_BOOL, ucp_Pattern_Syntax }, + { 2727, PT_BOOL, ucp_Pattern_Syntax }, + { 2741, PT_BOOL, ucp_Pattern_White_Space }, + { 2759, PT_BOOL, ucp_Pattern_White_Space }, + { 2765, PT_SC, ucp_Pau_Cin_Hau }, + { 2770, PT_SC, ucp_Pau_Cin_Hau }, + { 2780, PT_PC, ucp_Pc }, + { 2783, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2787, PT_PC, ucp_Pd }, + { 2790, PT_PC, ucp_Pe }, + { 2793, PT_SCX, ucp_Old_Permic }, + { 2798, PT_PC, ucp_Pf }, + { 2801, PT_SCX, ucp_Phags_Pa }, + { 2806, PT_SCX, ucp_Phags_Pa }, + { 2814, PT_SC, ucp_Inscriptional_Pahlavi }, + { 2819, PT_SCX, ucp_Psalter_Pahlavi }, + { 2824, PT_SC, ucp_Phoenician }, + { 2829, PT_SC, ucp_Phoenician }, + { 2840, PT_PC, ucp_Pi }, + { 2843, PT_SC, ucp_Miao }, + { 2848, PT_PC, ucp_Po }, + { 2851, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2878, PT_SC, ucp_Inscriptional_Parthian }, + { 2883, PT_PC, ucp_Ps }, + { 2886, PT_SCX, ucp_Psalter_Pahlavi }, + { 2901, PT_SCX, ucp_Coptic }, + { 2906, PT_SC, ucp_Inherited }, + { 2911, PT_BOOL, ucp_Quotation_Mark }, + { 2917, PT_BOOL, ucp_Quotation_Mark }, + { 2931, PT_BOOL, ucp_Radical }, + { 2939, PT_BOOL, ucp_Regional_Indicator }, + { 2957, PT_SC, ucp_Rejang }, + { 2964, PT_BOOL, ucp_Regional_Indicator }, + { 2967, PT_SC, ucp_Rejang }, + { 2972, PT_SCX, ucp_Hanifi_Rohingya }, + { 2977, PT_SCX, ucp_Runic }, + { 2983, PT_SCX, ucp_Runic }, + { 2988, PT_GC, ucp_S }, + { 2990, PT_SCX, ucp_Samaritan }, + { 3000, PT_SCX, ucp_Samaritan }, + { 3005, PT_SC, ucp_Old_South_Arabian }, + { 3010, PT_SC, ucp_Saurashtra }, + { 3015, PT_SC, ucp_Saurashtra }, + { 3026, PT_PC, ucp_Sc }, + { 3029, PT_BOOL, ucp_Soft_Dotted }, + { 3032, PT_BOOL, ucp_Sentence_Terminal }, + { 3049, PT_SC, ucp_SignWriting }, + { 3054, PT_SCX, ucp_Sharada }, + { 3062, PT_SCX, ucp_Shavian }, + { 3070, PT_SCX, ucp_Shavian }, + { 3075, PT_SCX, ucp_Sharada }, + { 3080, PT_SC, ucp_Siddham }, + { 3085, PT_SC, ucp_Siddham }, + { 3093, PT_SC, ucp_SignWriting }, + { 3105, PT_SCX, ucp_Khudawadi }, + { 3110, PT_SCX, ucp_Sinhala }, + { 3115, PT_SCX, ucp_Sinhala }, + { 3123, PT_PC, ucp_Sk }, + { 3126, PT_PC, ucp_Sm }, + { 3129, PT_PC, ucp_So }, + { 3132, PT_BOOL, ucp_Soft_Dotted }, + { 3143, PT_SCX, ucp_Sogdian }, + { 3148, PT_SCX, ucp_Sogdian }, + { 3156, PT_SC, ucp_Old_Sogdian }, + { 3161, PT_SC, ucp_Sora_Sompeng }, + { 3166, PT_SC, ucp_Sora_Sompeng }, + { 3178, PT_SC, ucp_Soyombo }, + { 3183, PT_SC, ucp_Soyombo }, + { 3191, PT_BOOL, ucp_White_Space }, + { 3197, PT_BOOL, ucp_Sentence_Terminal }, + { 3203, PT_SC, ucp_Sundanese }, + { 3208, PT_SC, ucp_Sundanese }, + { 3218, PT_SCX, ucp_Sunuwar }, + { 3223, PT_SCX, ucp_Sunuwar }, + { 3231, PT_SCX, ucp_Syloti_Nagri }, + { 3236, PT_SCX, ucp_Syloti_Nagri }, + { 3248, PT_SCX, ucp_Syriac }, + { 3253, PT_SCX, ucp_Syriac }, + { 3260, PT_SCX, ucp_Tagalog }, + { 3268, PT_SCX, ucp_Tagbanwa }, + { 3273, PT_SCX, ucp_Tagbanwa }, + { 3282, PT_SCX, ucp_Tai_Le }, + { 3288, PT_SC, ucp_Tai_Tham }, + { 3296, PT_SC, ucp_Tai_Viet }, + { 3304, PT_SCX, ucp_Takri }, + { 3309, PT_SCX, ucp_Takri }, + { 3315, PT_SCX, ucp_Tai_Le }, + { 3320, PT_SC, ucp_New_Tai_Lue }, + { 3325, PT_SCX, ucp_Tamil }, + { 3331, PT_SCX, ucp_Tamil }, + { 3336, PT_SCX, ucp_Tangut }, + { 3341, PT_SC, ucp_Tangsa }, + { 3348, PT_SCX, ucp_Tangut }, + { 3355, PT_SC, ucp_Tai_Viet }, + { 3360, PT_SCX, ucp_Telugu }, + { 3365, PT_SCX, ucp_Telugu }, + { 3372, PT_BOOL, ucp_Terminal_Punctuation }, + { 3377, PT_BOOL, ucp_Terminal_Punctuation }, + { 3397, PT_SCX, ucp_Tifinagh }, + { 3402, PT_SCX, ucp_Tagalog }, + { 3407, PT_SCX, ucp_Thaana }, + { 3412, PT_SCX, ucp_Thaana }, + { 3419, PT_SCX, ucp_Thai }, + { 3424, PT_SCX, ucp_Tibetan }, + { 3432, PT_SCX, ucp_Tibetan }, + { 3437, PT_SCX, ucp_Tifinagh }, + { 3446, PT_SCX, ucp_Tirhuta }, + { 3451, PT_SCX, ucp_Tirhuta }, + { 3459, PT_SC, ucp_Tangsa }, + { 3464, PT_SCX, ucp_Todhri }, + { 3471, PT_SCX, ucp_Todhri }, + { 3476, PT_SCX, ucp_Toto }, + { 3481, PT_SCX, ucp_Tulu_Tigalari }, + { 3494, PT_SCX, ucp_Tulu_Tigalari }, + { 3499, PT_SC, ucp_Ugaritic }, + { 3504, PT_SC, ucp_Ugaritic }, + { 3513, PT_BOOL, ucp_Unified_Ideograph }, + { 3519, PT_BOOL, ucp_Unified_Ideograph }, + { 3536, PT_SC, ucp_Unknown }, + { 3544, PT_BOOL, ucp_Uppercase }, + { 3550, PT_BOOL, ucp_Uppercase }, + { 3560, PT_SC, ucp_Vai }, + { 3564, PT_SC, ucp_Vai }, + { 3569, PT_BOOL, ucp_Variation_Selector }, + { 3587, PT_SC, ucp_Vithkuqi }, + { 3592, PT_SC, ucp_Vithkuqi }, + { 3601, PT_BOOL, ucp_Variation_Selector }, + { 3604, PT_SC, ucp_Wancho }, + { 3611, PT_SC, ucp_Warang_Citi }, + { 3616, PT_SC, ucp_Warang_Citi }, + { 3627, PT_SC, ucp_Wancho }, + { 3632, PT_BOOL, ucp_White_Space }, + { 3643, PT_BOOL, ucp_White_Space }, + { 3650, PT_ALNUM, 0 }, + { 3654, PT_BOOL, ucp_XID_Continue }, + { 3659, PT_BOOL, ucp_XID_Continue }, + { 3671, PT_BOOL, ucp_XID_Start }, + { 3676, PT_BOOL, ucp_XID_Start }, + { 3685, PT_SC, ucp_Old_Persian }, + { 3690, PT_PXSPACE, 0 }, + { 3694, PT_SPACE, 0 }, + { 3698, PT_SC, ucp_Cuneiform }, + { 3703, PT_UCNC, 0 }, + { 3707, PT_WORD, 0 }, + { 3711, PT_SCX, ucp_Yezidi }, + { 3716, PT_SCX, ucp_Yezidi }, + { 3723, PT_SCX, ucp_Yi }, + { 3726, PT_SCX, ucp_Yi }, + { 3731, PT_GC, ucp_Z }, + { 3733, PT_SC, ucp_Zanabazar_Square }, + { 3749, PT_SC, ucp_Zanabazar_Square }, + { 3754, PT_SC, ucp_Inherited }, + { 3759, PT_PC, ucp_Zl }, + { 3762, PT_PC, ucp_Zp }, + { 3765, PT_PC, ucp_Zs }, + { 3768, PT_SC, ucp_Common }, + { 3773, PT_SC, ucp_Unknown } }; const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); diff --git a/ext/pcre/pcre2lib/pcre2_util.h b/ext/pcre/pcre2lib/pcre2_util.h new file mode 100644 index 0000000000000..ea8635552a15e --- /dev/null +++ b/ext/pcre/pcre2lib/pcre2_util.h @@ -0,0 +1,132 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE2 is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifndef PCRE2_UTIL_H_IDEMPOTENT_GUARD +#define PCRE2_UTIL_H_IDEMPOTENT_GUARD + +/* Assertion macros */ + +#ifdef PCRE2_DEBUG + +#if defined(HAVE_ASSERT_H) && !defined(NDEBUG) +#include +#endif + +/* PCRE2_ASSERT(x) can be used to inject an assert() for conditions +that the code below doesn't support. It is a NOP for non debug builds +but in debug builds will print information about the location of the +code where it triggered and crash. + +It is meant to work like assert(), and therefore the expression used +should indicate what the expected state is, and shouldn't have any +side-effects. */ + +#if defined(HAVE_ASSERT_H) && !defined(NDEBUG) +#define PCRE2_ASSERT(x) assert(x) +#else +#define PCRE2_ASSERT(x) do \ +{ \ + if (!(x)) \ + { \ + fprintf(stderr, "Assertion failed at " __FILE__ ":%d\n", __LINE__); \ + abort(); \ + } \ +} while(0) +#endif + +/* PCRE2_UNREACHABLE() can be used to mark locations on the code that +shouldn't be reached. In non debug builds is defined as a hint for +the compiler to eliminate any code after it, so it is useful also for +performance reasons, but should be used with care because if it is +ever reached will trigger Undefined Behaviour and if you are lucky a +crash. In debug builds it will report the location where it was triggered +and crash. One important point to consider when using this macro, is +that it is only implemented for a few compilers, and therefore can't +be relied on to always be active either, so if it is followed by some +code it is important to make sure that the whole thing is safe to +use even if the macro is not there (ex: make sure there is a `break` +after it if used at the end of a `case`) and to test your code also +with a configuration where the macro will be a NOP. */ + +#if defined(HAVE_ASSERT_H) && !defined(NDEBUG) +#define PCRE2_UNREACHABLE() \ +assert(((void)"Execution reached unexpected point", 0)) +#else +#define PCRE2_UNREACHABLE() do \ +{ \ +fprintf(stderr, "Execution reached unexpected point at " __FILE__ \ + ":%d\n", __LINE__); \ +abort(); \ +} while(0) +#endif + +/* PCRE2_DEBUG_UNREACHABLE() is a debug only version of the previous +macro. It is meant to be used in places where the code is handling +an error situation in code that shouldn't be reached, but that has +some sort of fallback code to normally handle the error. When in +doubt you should use this instead of the previous macro. Like in +the previous case, it is a good idea to document as much as possible +the reason and the actions that should be taken if it ever triggers. */ + +#define PCRE2_DEBUG_UNREACHABLE() PCRE2_UNREACHABLE() + +#endif /* PCRE2_DEBUG */ + +#ifndef PCRE2_DEBUG_UNREACHABLE +#define PCRE2_DEBUG_UNREACHABLE() do {} while(0) +#endif + +#ifndef PCRE2_UNREACHABLE +#ifdef HAVE_BUILTIN_UNREACHABLE +#define PCRE2_UNREACHABLE() __builtin_unreachable() +#elif defined(HAVE_BUILTIN_ASSUME) +#define PCRE2_UNREACHABLE() __assume(0) +#else +#define PCRE2_UNREACHABLE() do {} while(0) +#endif +#endif /* !PCRE2_UNREACHABLE */ + +#ifndef PCRE2_ASSERT +#define PCRE2_ASSERT(x) do {} while(0) +#endif + +#endif /* PCRE2_UTIL_H_IDEMPOTENT_GUARD */ + +/* End of pcre2_util.h */ diff --git a/ext/pcre/pcre2lib/pcre2_xclass.c b/ext/pcre/pcre2lib/pcre2_xclass.c index 5df25d2c8dfa0..25de7cbf38b60 100644 --- a/ext/pcre/pcre2lib/pcre2_xclass.c +++ b/ext/pcre/pcre2lib/pcre2_xclass.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2023 University of Cambridge + New API code Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -38,9 +38,9 @@ POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ -/* This module contains an internal function that is used to match an extended -class. It is used by pcre2_auto_possessify() and by both pcre2_match() and -pcre2_def_match(). */ +/* This module contains two internal functions that are used to match +OP_XCLASS and OP_ECLASS. It is used by pcre2_auto_possessify() and by both +pcre2_match() and pcre2_dfa_match(). */ #ifdef HAVE_CONFIG_H @@ -66,114 +66,75 @@ Returns: TRUE if character matches, else FALSE */ BOOL -PRIV(xclass)(uint32_t c, PCRE2_SPTR data, BOOL utf) +PRIV(xclass)(uint32_t c, PCRE2_SPTR data, const uint8_t *char_lists_end, BOOL utf) { +/* Update PRIV(update_classbits) when this function is changed. */ PCRE2_UCHAR t; -BOOL negated = (*data & XCL_NOT) != 0; +BOOL not_negated = (*data & XCL_NOT) == 0; +uint32_t type, max_index, min_index, value; +const uint8_t *next_char; #if PCRE2_CODE_UNIT_WIDTH == 8 /* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */ utf = TRUE; #endif -/* Code points < 256 are matched against a bitmap, if one is present. If not, -we still carry on, because there may be ranges that start below 256 in the -additional data. */ +/* Code points < 256 are matched against a bitmap, if one is present. */ -if (c < 256) +if ((*data++ & XCL_MAP) != 0) { - if ((*data & XCL_HASPROP) == 0) - { - if ((*data & XCL_MAP) == 0) return negated; - return (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0; - } - if ((*data & XCL_MAP) != 0 && - (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0) - return !negated; /* char found */ + if (c < 256) + return (((const uint8_t *)data)[c/8] & (1u << (c&7))) != 0; + /* Skip bitmap. */ + data += 32 / sizeof(PCRE2_UCHAR); } -/* First skip the bit map if present. Then match against the list of Unicode -properties or large chars or ranges that end with a large char. We won't ever +/* Match against the list of Unicode properties. We won't ever encounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */ - -if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(PCRE2_UCHAR); - -while ((t = *data++) != XCL_END) - { - uint32_t x, y; - if (t == XCL_SINGLE) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - GETCHARINC(x, data); /* macro generates multiple statements */ - } - else -#endif - x = *data++; - if (c == x) return !negated; - } - else if (t == XCL_RANGE) - { #ifdef SUPPORT_UNICODE - if (utf) - { - GETCHARINC(x, data); /* macro generates multiple statements */ - GETCHARINC(y, data); /* macro generates multiple statements */ - } - else -#endif - { - x = *data++; - y = *data++; - } - if (c >= x && c <= y) return !negated; - } +if (*data == XCL_PROP || *data == XCL_NOTPROP) + { + /* The UCD record is the same for all properties. */ + const ucd_record *prop = GET_UCD(c); -#ifdef SUPPORT_UNICODE - else /* XCL_PROP & XCL_NOTPROP */ + do { int chartype; - const ucd_record *prop = GET_UCD(c); - BOOL isprop = t == XCL_PROP; + BOOL isprop = (*data++) == XCL_PROP; BOOL ok; switch(*data) { - case PT_ANY: - if (isprop) return !negated; - break; - case PT_LAMP: chartype = prop->chartype; if ((chartype == ucp_Lu || chartype == ucp_Ll || - chartype == ucp_Lt) == isprop) return !negated; + chartype == ucp_Lt) == isprop) return not_negated; break; case PT_GC: if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop) - return !negated; + return not_negated; break; case PT_PC: - if ((data[1] == prop->chartype) == isprop) return !negated; + if ((data[1] == prop->chartype) == isprop) return not_negated; break; case PT_SC: - if ((data[1] == prop->script) == isprop) return !negated; + if ((data[1] == prop->script) == isprop) return not_negated; break; case PT_SCX: ok = (data[1] == prop->script || MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), data[1]) != 0); - if (ok == isprop) return !negated; + if (ok == isprop) return not_negated; break; case PT_ALNUM: chartype = prop->chartype; if ((PRIV(ucp_gentype)[chartype] == ucp_L || PRIV(ucp_gentype)[chartype] == ucp_N) == isprop) - return !negated; + return not_negated; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -186,12 +147,12 @@ while ((t = *data++) != XCL_END) { HSPACE_CASES: VSPACE_CASES: - if (isprop) return !negated; + if (isprop) return not_negated; break; default: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop) - return !negated; + return not_negated; break; } break; @@ -201,7 +162,7 @@ while ((t = *data++) != XCL_END) if ((PRIV(ucp_gentype)[chartype] == ucp_L || PRIV(ucp_gentype)[chartype] == ucp_N || chartype == ucp_Mn || chartype == ucp_Pc) == isprop) - return !negated; + return not_negated; break; case PT_UCNC: @@ -209,24 +170,24 @@ while ((t = *data++) != XCL_END) { if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || c == CHAR_GRAVE_ACCENT) == isprop) - return !negated; + return not_negated; } else { if ((c < 0xd800 || c > 0xdfff) == isprop) - return !negated; + return not_negated; } break; case PT_BIDICL: if ((UCD_BIDICLASS_PROP(prop) == data[1]) == isprop) - return !negated; + return not_negated; break; case PT_BOOL: ok = MAPBIT(PRIV(ucd_boolprop_sets) + UCD_BPROPS_PROP(prop), data[1]) != 0; - if (ok == isprop) return !negated; + if (ok == isprop) return not_negated; break; /* The following three properties can occur only in an XCLASS, as there @@ -248,7 +209,7 @@ while ((t = *data++) != XCL_END) (chartype == ucp_Cf && c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) )) == isprop) - return !negated; + return not_negated; break; /* Printable character: same as graphic, with the addition of Zs, i.e. @@ -262,7 +223,7 @@ while ((t = *data++) != XCL_END) (chartype == ucp_Cf && c != 0x061c && (c < 0x2066 || c > 0x2069)) )) == isprop) - return !negated; + return not_negated; break; /* Punctuation: all Unicode punctuation, plus ASCII characters that @@ -273,7 +234,7 @@ while ((t = *data++) != XCL_END) chartype = prop->chartype; if ((PRIV(ucp_gentype)[chartype] == ucp_P || (c < 128 && PRIV(ucp_gentype)[chartype] == ucp_S)) == isprop) - return !negated; + return not_negated; break; /* Perl has two sets of hex digits */ @@ -285,24 +246,300 @@ while ((t = *data++) != XCL_END) (c >= 0xff10 && c <= 0xff19) || /* Fullwidth digits */ (c >= 0xff21 && c <= 0xff26) || /* Fullwidth letters */ (c >= 0xff41 && c <= 0xff46)) == isprop) - return !negated; + return not_negated; break; /* This should never occur, but compilers may mutter if there is no default. */ default: + PCRE2_DEBUG_UNREACHABLE(); return FALSE; } data += 2; } + while (*data == XCL_PROP || *data == XCL_NOTPROP); + } #else (void)utf; /* Avoid compiler warning */ #endif /* SUPPORT_UNICODE */ + +/* Match against large chars or ranges that end with a large char. */ +if (*data < XCL_LIST) + { + while ((t = *data++) != XCL_END) + { + uint32_t x, y; + +#ifdef SUPPORT_UNICODE + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + } + else +#endif + x = *data++; + + if (t == XCL_SINGLE) + { + /* Since character ranges follow the properties, and they are + sorted, early return is possible for all characters <= x. */ + if (c <= x) return (c == x) ? not_negated : !not_negated; + continue; + } + + PCRE2_ASSERT(t == XCL_RANGE); +#ifdef SUPPORT_UNICODE + if (utf) + { + GETCHARINC(y, data); /* macro generates multiple statements */ + } + else +#endif + y = *data++; + + /* Since character ranges follow the properties, and they are + sorted, early return is possible for all characters <= y. */ + if (c <= y) return (c >= x) ? not_negated : !not_negated; + } + + return !not_negated; /* char did not match */ + } + +#if PCRE2_CODE_UNIT_WIDTH == 8 +type = (uint32_t)(data[0] << 8) | data[1]; +data += 2; +#else +type = data[0]; +data++; +#endif /* CODE_UNIT_WIDTH */ + +/* Align characters. */ +next_char = char_lists_end - (GET(data, 0) << 1); +type &= XCL_TYPE_MASK; + +/* Alignment check. */ +PCRE2_ASSERT(((uintptr_t)next_char & 0x1) == 0); + +if (c >= XCL_CHAR_LIST_HIGH_16_START) + { + max_index = type & XCL_ITEM_COUNT_MASK; + if (max_index == XCL_ITEM_COUNT_MASK) + { + max_index = *(const uint16_t*)next_char; + PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); + next_char += 2; + } + + next_char += max_index << 1; + type >>= XCL_TYPE_BIT_LEN; } -return negated; /* char did not match */ +if (c < XCL_CHAR_LIST_LOW_32_START) + { + max_index = type & XCL_ITEM_COUNT_MASK; + + c = (uint16_t)((c << XCL_CHAR_SHIFT) | XCL_CHAR_END); + + if (max_index == XCL_ITEM_COUNT_MASK) + { + max_index = *(const uint16_t*)next_char; + PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); + next_char += 2; + } + + if (max_index == 0 || c < *(const uint16_t*)next_char) + return ((type & XCL_BEGIN_WITH_RANGE) != 0) == not_negated; + + min_index = 0; + value = ((const uint16_t*)next_char)[--max_index]; + if (c >= value) + return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; + + max_index--; + + /* Binary search of a range. */ + while (TRUE) + { + uint32_t mid_index = (min_index + max_index) >> 1; + value = ((const uint16_t*)next_char)[mid_index]; + + if (c < value) + max_index = mid_index - 1; + else if (((const uint16_t*)next_char)[mid_index + 1] <= c) + min_index = mid_index + 1; + else + return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; + } + } + +/* Skip the 16 bit ranges. */ +max_index = type & XCL_ITEM_COUNT_MASK; +if (max_index == XCL_ITEM_COUNT_MASK) + { + max_index = *(const uint16_t*)next_char; + PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); + next_char += 2; + } + +next_char += (max_index << 1); +type >>= XCL_TYPE_BIT_LEN; + +/* Alignment check. */ +PCRE2_ASSERT(((uintptr_t)next_char & 0x3) == 0); + +max_index = type & XCL_ITEM_COUNT_MASK; + +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (c >= XCL_CHAR_LIST_HIGH_32_START) + { + if (max_index == XCL_ITEM_COUNT_MASK) + { + max_index = *(const uint32_t*)next_char; + PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); + next_char += 4; + } + + next_char += max_index << 2; + type >>= XCL_TYPE_BIT_LEN; + max_index = type & XCL_ITEM_COUNT_MASK; + } +#endif + +c = (uint32_t)((c << XCL_CHAR_SHIFT) | XCL_CHAR_END); + +if (max_index == XCL_ITEM_COUNT_MASK) + { + max_index = *(const uint32_t*)next_char; + next_char += 4; + } + +if (max_index == 0 || c < *(const uint32_t*)next_char) + return ((type & XCL_BEGIN_WITH_RANGE) != 0) == not_negated; + +min_index = 0; +value = ((const uint32_t*)next_char)[--max_index]; +if (c >= value) + return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; + +max_index--; + +/* Binary search of a range. */ +while (TRUE) + { + uint32_t mid_index = (min_index + max_index) >> 1; + value = ((const uint32_t*)next_char)[mid_index]; + + if (c < value) + max_index = mid_index - 1; + else if (((const uint32_t*)next_char)[mid_index + 1] <= c) + min_index = mid_index + 1; + else + return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; + } +} + + + +/************************************************* +* Match character against an ECLASS * +*************************************************/ + +/* This function is called to match a character against an extended class +used for describing characters using boolean operations on sets. + +Arguments: + c the character + data_start points to the start of the ECLASS data + data_end points one-past-the-last of the ECLASS data + utf TRUE if in UTF mode + +Returns: TRUE if character matches, else FALSE +*/ + +BOOL +PRIV(eclass)(uint32_t c, PCRE2_SPTR data_start, PCRE2_SPTR data_end, + const uint8_t *char_lists_end, BOOL utf) +{ +PCRE2_SPTR ptr = data_start; +PCRE2_UCHAR flags; +uint32_t stack = 0; +int stack_depth = 0; + +PCRE2_ASSERT(data_start < data_end); +flags = *ptr++; +PCRE2_ASSERT((flags & ECL_MAP) == 0 || + (data_end - ptr) >= 32 / (int)sizeof(PCRE2_UCHAR)); + +/* Code points < 256 are matched against a bitmap, if one is present. +Otherwise all codepoints are checked later. */ + +if ((flags & ECL_MAP) != 0) + { + if (c < 256) + return (((const uint8_t *)ptr)[c/8] & (1u << (c&7))) != 0; + + /* Skip the bitmap. */ + ptr += 32 / sizeof(PCRE2_UCHAR); + } + +/* Do a little loop, until we reach the end of the ECLASS. */ +while (ptr < data_end) + { + switch (*ptr) + { + case ECL_AND: + ++ptr; + stack = (stack >> 1) & (stack | ~(uint32_t)1u); + PCRE2_ASSERT(stack_depth >= 2); + --stack_depth; + break; + + case ECL_OR: + ++ptr; + stack = (stack >> 1) | (stack & (uint32_t)1u); + PCRE2_ASSERT(stack_depth >= 2); + --stack_depth; + break; + + case ECL_XOR: + ++ptr; + stack = (stack >> 1) ^ (stack & (uint32_t)1u); + PCRE2_ASSERT(stack_depth >= 2); + --stack_depth; + break; + + case ECL_NOT: + ++ptr; + stack ^= (uint32_t)1u; + PCRE2_ASSERT(stack_depth >= 1); + break; + + case ECL_XCLASS: + { + uint32_t matched = PRIV(xclass)(c, ptr + 1 + LINK_SIZE, char_lists_end, utf); + + ptr += GET(ptr, 1); + stack = (stack << 1) | matched; + ++stack_depth; + break; + } + + /* This should never occur, but compilers may mutter if there is no + default. */ + + default: + PCRE2_DEBUG_UNREACHABLE(); + return FALSE; + } + } + +PCRE2_ASSERT(stack_depth == 1); +(void)stack_depth; /* Ignore unused variable, if assertions are disabled. */ + +/* The final bit left on the stack now holds the match result. */ +return (stack & 1u) != 0; } /* End of pcre2_xclass.c */ diff --git a/ext/pcre/pcre2lib/sljit/sljitConfig.h b/ext/pcre/pcre2lib/sljit/sljitConfig.h index 364c8bb7884af..993f4fe2fa168 100644 --- a/ext/pcre/pcre2lib/sljit/sljitConfig.h +++ b/ext/pcre/pcre2lib/sljit/sljitConfig.h @@ -29,7 +29,7 @@ #ifdef __cplusplus extern "C" { -#endif +#endif /* __cplusplus */ /* This file contains the basic configuration options for the SLJIT compiler @@ -47,19 +47,19 @@ extern "C" { #ifndef SLJIT_UTIL_STACK /* Enabled by default */ #define SLJIT_UTIL_STACK 1 -#endif +#endif /* SLJIT_UTIL_STACK */ /* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */ #ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION /* Disabled by default */ #define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0 -#endif +#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */ /* Single threaded application. Does not require any locks. */ #ifndef SLJIT_SINGLE_THREADED /* Disabled by default. */ #define SLJIT_SINGLE_THREADED 0 -#endif +#endif /* SLJIT_SINGLE_THREADED */ /* --------------------------------------------------------------------- */ /* Configuration */ @@ -70,7 +70,7 @@ extern "C" { #ifndef SLJIT_STD_MACROS_DEFINED /* Disabled by default. */ #define SLJIT_STD_MACROS_DEFINED 0 -#endif +#endif /* SLJIT_STD_MACROS_DEFINED */ /* Executable code allocation: If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should @@ -93,7 +93,7 @@ extern "C" { #ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR /* Disabled by default. */ #define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0 -#endif +#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */ /* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an allocator which does not set writable and executable permission @@ -104,7 +104,7 @@ extern "C" { #ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR /* Disabled by default. */ #define SLJIT_WX_EXECUTABLE_ALLOCATOR 0 -#endif +#endif /* SLJIT_WX_EXECUTABLE_ALLOCATOR */ #endif /* !SLJIT_EXECUTABLE_ALLOCATOR */ @@ -112,19 +112,19 @@ extern "C" { #ifndef SLJIT_ARGUMENT_CHECKS /* Disabled by default */ #define SLJIT_ARGUMENT_CHECKS 0 -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ /* Debug checks (assertions, etc.). */ #ifndef SLJIT_DEBUG /* Enabled by default */ #define SLJIT_DEBUG 1 -#endif +#endif /* SLJIT_DEBUG */ /* Verbose operations. */ #ifndef SLJIT_VERBOSE /* Enabled by default */ #define SLJIT_VERBOSE 1 -#endif +#endif /* SLJIT_VERBOSE */ /* SLJIT_IS_FPU_AVAILABLE @@ -137,6 +137,6 @@ extern "C" { #ifdef __cplusplus } /* extern "C" */ -#endif +#endif /* __cplusplus */ #endif /* SLJIT_CONFIG_H_ */ diff --git a/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h b/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h index 2720bdab0bd17..dcf88efbd4373 100644 --- a/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h +++ b/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h @@ -169,7 +169,7 @@ #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) #define SLJIT_CONFIG_ARM_32 1 -#endif +#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 || SLJIT_CONFIG_ARM_THUMB2 */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define SLJIT_CONFIG_X86 1 diff --git a/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h b/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h index de06dd8e0c021..3ae944efb8108 100644 --- a/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h +++ b/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h @@ -27,20 +27,6 @@ #ifndef SLJIT_CONFIG_INTERNAL_H_ #define SLJIT_CONFIG_INTERNAL_H_ -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE))) -#include -#endif - -#if (defined SLJIT_DEBUG && SLJIT_DEBUG \ - && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS))) -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - /* SLJIT defines the following architecture dependent types and macros: @@ -64,16 +50,26 @@ extern "C" { SLJIT_MASKED_SHIFT : all word shifts are always masked SLJIT_MASKED_SHIFT32 : all 32 bit shifts are always masked SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information + SLJIT_UPPER_BITS_IGNORED : 32 bit operations ignores the upper bits of source registers + SLJIT_UPPER_BITS_ZERO_EXTENDED : 32 bit operations clears the upper bits of destination registers + SLJIT_UPPER_BITS_SIGN_EXTENDED : 32 bit operations replicates the sign bit in the upper bits of destination registers + SLJIT_UPPER_BITS_PRESERVED : 32 bit operations preserves the upper bits of destination registers Constants: SLJIT_NUMBER_OF_REGISTERS : number of available registers SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers + SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available scratch floating point registers + SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available saved floating point registers + SLJIT_NUMBER_OF_VECTOR_REGISTERS : number of available vector registers + SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS : number of available scratch vector registers + SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS : number of available saved vector registers SLJIT_NUMBER_OF_TEMPORARY_REGISTERS : number of available temporary registers SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS : number of available temporary floating point registers + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS : number of available temporary vector registers + SLJIT_SEPARATE_VECTOR_REGISTERS : if this macro is defined, the vector registers do not + overlap with floating point registers SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index SLJIT_F32_SHIFT : the shift required to apply when accessing a single precision floating point array by index @@ -98,16 +94,33 @@ extern "C" { SLJIT_TMP_R(i) : accessing temporary registers SLJIT_TMP_FR0 .. FR9 : accessing temporary floating point registers SLJIT_TMP_FR(i) : accessing temporary floating point registers + SLJIT_TMP_VR0 .. VR9 : accessing temporary vector registers + SLJIT_TMP_VR(i) : accessing temporary vector registers SLJIT_TMP_DEST_REG : a temporary register for results SLJIT_TMP_MEM_REG : a temporary base register for accessing memory (can be the same as SLJIT_TMP_DEST_REG) SLJIT_TMP_DEST_FREG : a temporary register for float results + SLJIT_TMP_DEST_VREG : a temporary register for vector results SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper) SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero */ +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE))) +#include +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG \ + && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS))) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + /***********************************************************/ /* Intel Control-flow Enforcement Technology (CET) spport. */ /***********************************************************/ @@ -285,7 +298,7 @@ extern "C" { #elif defined(_WIN32) #define SLJIT_CACHE_FLUSH(from, to) \ - FlushInstructionCache(GetCurrentProcess(), (void*)(from), (char*)(to) - (char*)(from)) + FlushInstructionCache(GetCurrentProcess(), (void*)(from), (size_t)((char*)(to) - (char*)(from))) #elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || defined(__clang__) @@ -553,7 +566,7 @@ determine the next executed instruction after return. */ #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); +/* Note: sljitLir.h also defines sljit_free_unused_memory_exec() function. */ #define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size) #define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr) @@ -591,10 +604,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_DEST_REG SLJIT_TMP_R0 #define SLJIT_TMP_MEM_REG SLJIT_TMP_R0 #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 -#define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw)) +#define SLJIT_LOCALS_OFFSET_BASE (8 * (sljit_s32)sizeof(sljit_sw)) #define SLJIT_PREF_SHIFT_REG SLJIT_R2 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 +#define SLJIT_UPPER_BITS_IGNORED 1 +#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1 #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -609,7 +624,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #else /* _WIN64 */ #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 10 -#define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw)) +#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw)) #endif /* !_WIN64 */ #define SLJIT_TMP_DEST_REG SLJIT_TMP_R0 #define SLJIT_TMP_MEM_REG SLJIT_TMP_R0 @@ -617,6 +632,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_PREF_SHIFT_REG SLJIT_R3 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 +#define SLJIT_UPPER_BITS_IGNORED 1 +#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1 #elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) @@ -645,6 +662,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw)) #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 +#define SLJIT_UPPER_BITS_IGNORED 1 +#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) @@ -665,6 +684,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #else #define SLJIT_LOCALS_OFFSET_BASE (3 * (sljit_s32)sizeof(sljit_sw)) #endif /* SLJIT_CONFIG_PPC_64 || _AIX */ +#define SLJIT_UPPER_BITS_IGNORED 1 #elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) @@ -686,6 +706,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 +#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1 #elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) @@ -695,12 +716,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12 #define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 +#define SLJIT_SEPARATE_VECTOR_REGISTERS 1 +#define SLJIT_NUMBER_OF_VECTOR_REGISTERS 30 +#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS 0 +#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS 2 #define SLJIT_TMP_DEST_REG SLJIT_TMP_R1 #define SLJIT_TMP_MEM_REG SLJIT_TMP_R1 #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 +#define SLJIT_TMP_DEST_VREG SLJIT_TMP_VR0 #define SLJIT_LOCALS_OFFSET_BASE 0 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 +#define SLJIT_UPPER_BITS_IGNORED 1 +#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) @@ -736,6 +764,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 #define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE #define SLJIT_MASKED_SHIFT 1 +#define SLJIT_UPPER_BITS_IGNORED 1 +#define SLJIT_UPPER_BITS_PRESERVED 1 #elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) @@ -751,6 +781,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_LOCALS_OFFSET_BASE 0 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 +#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1 #elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) @@ -768,6 +799,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #endif +#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) +#define SLJIT_NUMBER_OF_VECTOR_REGISTERS (SLJIT_NUMBER_OF_FLOAT_REGISTERS) +#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS (SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) +#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS (SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS) +#define SLJIT_TMP_DEST_VREG (SLJIT_TMP_DEST_FREG) +#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ + #define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE) #define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \ @@ -776,12 +814,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \ (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) +#define SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS \ + (SLJIT_NUMBER_OF_VECTOR_REGISTERS - SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS) + +#if (defined SLJIT_UPPER_BITS_ZERO_EXTENDED && SLJIT_UPPER_BITS_ZERO_EXTENDED) \ + + (defined SLJIT_UPPER_BITS_SIGN_EXTENDED && SLJIT_UPPER_BITS_SIGN_EXTENDED) \ + + (defined SLJIT_UPPER_BITS_PRESERVED && SLJIT_UPPER_BITS_PRESERVED) > 1 +#error "Invalid upper bits defintion" +#endif + +#if (defined SLJIT_UPPER_BITS_PRESERVED && SLJIT_UPPER_BITS_PRESERVED) \ + && !(defined SLJIT_UPPER_BITS_IGNORED && SLJIT_UPPER_BITS_IGNORED) +#error "Upper bits preserved requires bits ignored" +#endif + /**********************************/ /* Temporary register management. */ /**********************************/ #define SLJIT_TMP_REGISTER_BASE (SLJIT_NUMBER_OF_REGISTERS + 2) #define SLJIT_TMP_FREGISTER_BASE (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) +#define SLJIT_TMP_VREGISTER_BASE (SLJIT_NUMBER_OF_VECTOR_REGISTERS + 1) /* WARNING: Accessing temporary registers is not recommended, because they are also used by the JIT compiler for various computations. Using them @@ -815,6 +868,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_FR9 (SLJIT_TMP_FREGISTER_BASE + 9) #define SLJIT_TMP_FR(i) (SLJIT_TMP_FREGISTER_BASE + (i)) +#define SLJIT_TMP_VR0 (SLJIT_TMP_VREGISTER_BASE + 0) +#define SLJIT_TMP_VR1 (SLJIT_TMP_VREGISTER_BASE + 1) +#define SLJIT_TMP_VR2 (SLJIT_TMP_VREGISTER_BASE + 2) +#define SLJIT_TMP_VR3 (SLJIT_TMP_VREGISTER_BASE + 3) +#define SLJIT_TMP_VR4 (SLJIT_TMP_VREGISTER_BASE + 4) +#define SLJIT_TMP_VR5 (SLJIT_TMP_VREGISTER_BASE + 5) +#define SLJIT_TMP_VR6 (SLJIT_TMP_VREGISTER_BASE + 6) +#define SLJIT_TMP_VR7 (SLJIT_TMP_VREGISTER_BASE + 7) +#define SLJIT_TMP_VR8 (SLJIT_TMP_VREGISTER_BASE + 8) +#define SLJIT_TMP_VR9 (SLJIT_TMP_VREGISTER_BASE + 9) +#define SLJIT_TMP_VR(i) (SLJIT_TMP_VREGISTER_BASE + (i)) + /********************************/ /* CPU status flags management. */ /********************************/ diff --git a/ext/pcre/pcre2lib/sljit/sljitLir.c b/ext/pcre/pcre2lib/sljit/sljitLir.c index 2dca17cd6f078..6b2d5564c7587 100644 --- a/ext/pcre/pcre2lib/sljit/sljitLir.c +++ b/ext/pcre/pcre2lib/sljit/sljitLir.c @@ -96,9 +96,10 @@ /* All variable flags are even. */ #define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT) #define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT) +#define GET_FLAG_TYPE_MASK(op) (((op) >> VARIABLE_FLAG_SHIFT) & 0x3e) #define GET_OPCODE(op) \ - ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) + ((op) & 0xff) #define HAS_FLAGS(op) \ ((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) @@ -118,9 +119,9 @@ #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) #define ABUF_SIZE 2048 -#else +#else /* !SLJIT_32BIT_ARCHITECTURE */ #define ABUF_SIZE 4096 -#endif +#endif /* SLJIT_32BIT_ARCHITECTURE */ /* Parameter parsing. */ #define REG_MASK 0x7f @@ -139,7 +140,10 @@ #define REG_PAIR_SECOND(reg) ((reg) >> 8) /* Mask for sljit_emit_enter. */ -#define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3) +#define ENTER_GET_REGS(regs) ((regs) & 0xff) +#define ENTER_GET_FLOAT_REGS(regs) (((regs) >> 8) & 0xff) +#define ENTER_GET_VECTOR_REGS(regs) (((regs) >> 16) & 0xff) +#define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3) /* Getters for simd operations, which returns with log2(size). */ #define SLJIT_SIMD_GET_OPCODE(type) ((type) & 0xff) @@ -334,19 +338,19 @@ #if defined(__NetBSD__) #include "allocator_src/sljitProtExecAllocatorNetBSD.c" -#else +#else /* !__NetBSD__ */ #include "allocator_src/sljitProtExecAllocatorPosix.c" -#endif +#endif /* __NetBSD__ */ #elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) #if defined(_WIN32) #include "allocator_src/sljitWXExecAllocatorWindows.c" -#else +#else /* !_WIN32 */ #include "allocator_src/sljitWXExecAllocatorPosix.c" -#endif +#endif /* _WIN32 */ -#else +#else /* !SLJIT_PROT_EXECUTABLAE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */ #if defined(_WIN32) #include "allocator_src/sljitExecAllocatorWindows.c" @@ -354,25 +358,25 @@ #include "allocator_src/sljitExecAllocatorApple.c" #elif defined(__FreeBSD__) #include "allocator_src/sljitExecAllocatorFreeBSD.c" -#else +#else /* !_WIN32 && !__APPLE__ && !__FreeBSD__ */ #include "allocator_src/sljitExecAllocatorPosix.c" -#endif +#endif /* _WIN32 */ -#endif +#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */ #else /* !SLJIT_EXECUTABLE_ALLOCATOR */ #ifndef SLJIT_UPDATE_WX_FLAGS #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) -#endif +#endif /* SLJIT_UPDATE_WX_FLAGS */ #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset)) -#else +#else /* !SLJIT_PROT_EXECUTABLE_ALLOCATOR */ #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr)) -#endif +#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */ /* Argument checking features. */ @@ -434,7 +438,7 @@ #define CHECK_PTR(x) x #define CHECK_REG_INDEX(x) x -#else +#else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_DEBUG && !SLJIT_VERBOSE */ /* Arguments are not checked. */ #define CHECK(x) @@ -452,7 +456,7 @@ static sljit_s32 compiler_initialized = 0; /* A thread safe initialization. */ static void init_compiler(void); -#endif +#endif /* SLJIT_CONFIG_X86 */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data) { @@ -501,6 +505,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo compiler->saveds = -1; compiler->fscratches = -1; compiler->fsaveds = -1; +#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + compiler->vscratches = -1; + compiler->vsaveds = -1; +#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ compiler->local_size = -1; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -526,17 +536,25 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) - compiler->last_flags = 0; + SLJIT_ASSERT(compiler->last_flags == 0 && compiler->logical_local_size == 0); compiler->last_return = -1; - compiler->logical_local_size = 0; #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) + compiler->real_fscratches = -1; + compiler->real_fsaveds = -1; +#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ + SLJIT_ASSERT(compiler->skip_checks == 0); +#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ + #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) if (!compiler_initialized) { init_compiler(); compiler_initialized = 1; } -#endif +#endif /* SLJIT_NEEDS_COMPILER_INIT */ return compiler; } @@ -564,7 +582,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_FREE(compiler->cpool, allocator_data); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ SLJIT_FREE(compiler, allocator_data); } @@ -607,14 +625,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *com #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) compiler->status_flags_state = current_flags; -#endif +#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_flags = 0; if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) { compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z)); } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ } /* --------------------------------------------------------------------- */ @@ -667,11 +685,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compile if (size <= 0 || size > 128) return NULL; size = (size + 7) & ~7; -#else +#else /* !SLJIT_64BIT_ARCHITECTURE */ if (size <= 0 || size > 64) return NULL; size = (size + 3) & ~3; -#endif +#endif /* SLJIT_64BIT_ARCHITECTURE */ return ensure_abuf(compiler, (sljit_uw)size); } @@ -752,40 +770,55 @@ static SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size, #endif /* !SLJIT_CONFIG_X86 */ -static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) +#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) + +static void update_float_register_count(struct sljit_compiler *compiler, sljit_s32 scratches, sljit_s32 saveds) { - SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(local_size); + sljit_s32 vscratches = ENTER_GET_VECTOR_REGS(scratches); + sljit_s32 vsaveds = ENTER_GET_VECTOR_REGS(saveds); - compiler->options = options; - compiler->scratches = scratches; - compiler->saveds = saveds; - compiler->fscratches = fscratches; - compiler->fsaveds = fsaveds; -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->last_return = args & SLJIT_ARG_MASK; - compiler->logical_local_size = local_size; -#endif + if (compiler->fscratches < vscratches) + compiler->fscratches = vscratches; + + if (compiler->fsaveds < vsaveds) + compiler->fsaveds = vsaveds; + + if (compiler->fsaveds + compiler->fscratches > SLJIT_NUMBER_OF_FLOAT_REGISTERS) + compiler->fscratches = SLJIT_NUMBER_OF_FLOAT_REGISTERS - compiler->fsaveds; } -static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) +#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ + +static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(local_size); compiler->options = options; - compiler->scratches = scratches; - compiler->saveds = saveds; - compiler->fscratches = fscratches; - compiler->fsaveds = fsaveds; + compiler->scratches = ENTER_GET_REGS(scratches); + compiler->saveds = ENTER_GET_REGS(saveds); + /* These members may be copied to real_* members below. */ + compiler->fscratches = ENTER_GET_FLOAT_REGS(scratches); + compiler->fsaveds = ENTER_GET_FLOAT_REGS(saveds); +#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) + compiler->vscratches = ENTER_GET_VECTOR_REGS(scratches); + compiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds); +#else /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + compiler->real_fscratches = compiler->fscratches; + compiler->real_fsaveds = compiler->fsaveds; + compiler->vscratches = ENTER_GET_VECTOR_REGS(scratches); + compiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds); +#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ + update_float_register_count(compiler, scratches, saveds); +#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_return = args & SLJIT_ARG_MASK; compiler->logical_local_size = local_size; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ } static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler) @@ -900,9 +933,9 @@ static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratch #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8) -#else +#else /* !SLJIT_CONFIG_X86_32 */ #define CHECK_IF_VIRTUAL_REGISTER(p) 0 -#endif +#endif /* SLJIT_CONFIG_X86_32 */ static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { @@ -994,17 +1027,47 @@ static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, s return function_check_src_mem(compiler, p, i); } +static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type); + +#define FUNCTION_CHECK_IS_VREG(vr, type) \ + function_check_is_vreg(compiler, (vr), (type)) + +#define FUNCTION_VCHECK(p, i, type) \ + CHECK_ARGUMENT(function_vcheck(compiler, (p), (i), (type))) + +static sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 type) +{ + if (compiler->scratches == -1) + return 0; + + if (FUNCTION_CHECK_IS_VREG(p, type)) + return (i == 0); + + return function_check_src_mem(compiler, p, i); +} + #else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */ + #define FUNCTION_CHECK_IS_FREG(fr, is_32) \ function_check_is_freg(compiler, (fr)) static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr) { + sljit_s32 fscratches, fsaveds; + if (compiler->scratches == -1) return 0; - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) - || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) +#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; +#else /* SLJIT_SEPARATE_VECTOR_REGISTERS */ + fscratches = compiler->real_fscratches; + fsaveds = compiler->real_fsaveds; +#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + fscratches)) + || (fr > (SLJIT_FS0 - fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } @@ -1016,9 +1079,34 @@ static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, s if (compiler->scratches == -1) return 0; - if ((p >= SLJIT_FR0 && p < (SLJIT_FR0 + compiler->fscratches)) - || (p > (SLJIT_FS0 - compiler->fsaveds) && p <= SLJIT_FS0) - || (p >= SLJIT_TMP_FREGISTER_BASE && p < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))) + if (function_check_is_freg(compiler, p)) + return (i == 0); + + return function_check_src_mem(compiler, p, i); +} + +#define FUNCTION_CHECK_IS_VREG(vr, type) \ + function_check_is_vreg(compiler, (vr)) + +static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr) +{ + if (compiler->scratches == -1) + return 0; + + return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches)) + || (vr > (SLJIT_VS0 - compiler->vsaveds) && vr <= SLJIT_VS0) + || (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)); +} + +#define FUNCTION_VCHECK(p, i, type) \ + CHECK_ARGUMENT(function_vcheck(compiler, (p), (i))) + +static sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) +{ + if (compiler->scratches == -1) + return 0; + + if (function_check_is_vreg(compiler, p)) return (i == 0); return function_check_src_mem(compiler, p, i); @@ -1039,15 +1127,15 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp #ifdef _WIN64 #ifdef __GNUC__ # define SLJIT_PRINT_D "ll" -#else +#else /* !__GNUC__ */ # define SLJIT_PRINT_D "I64" -#endif -#else +#endif /* __GNUC__ */ +#else /* !_WIN64 */ # define SLJIT_PRINT_D "l" -#endif -#else +#endif /* _WIN64 */ +#else /* !SLJIT_64BIT_ARCHITECTURE */ # define SLJIT_PRINT_D "" -#endif +#endif /* SLJIT_64BIT_ARCHITECTURE */ static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r) { @@ -1079,57 +1167,73 @@ static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r) fprintf(compiler->verbose, "ft%d", r - SLJIT_TMP_FREGISTER_BASE); } +static void sljit_verbose_vreg(struct sljit_compiler *compiler, sljit_s32 r) +{ +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + if (r >= SLJIT_F64_SECOND(SLJIT_VR0)) { + fprintf(compiler->verbose, "^"); + r -= SLJIT_F64_SECOND(0); + } +#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ + + if (r < (SLJIT_VR0 + compiler->vscratches)) + fprintf(compiler->verbose, "vr%d", r - SLJIT_VR0); + else if (r < SLJIT_TMP_VREGISTER_BASE) + fprintf(compiler->verbose, "vs%d", SLJIT_NUMBER_OF_VECTOR_REGISTERS - r); + else + fprintf(compiler->verbose, "vt%d", r - SLJIT_TMP_VREGISTER_BASE); +} + +static void sljit_verbose_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) +{ + if (!(p & REG_MASK)) { + fprintf(compiler->verbose, "[%" SLJIT_PRINT_D "d]", i); + return; + } + + fputc('[', compiler->verbose); + sljit_verbose_reg(compiler, (p) & REG_MASK); + if (p & OFFS_REG_MASK) { + fprintf(compiler->verbose, " + "); + sljit_verbose_reg(compiler, OFFS_REG(p)); + if (i) + fprintf(compiler->verbose, " * %d", 1 << (i)); + } else if (i) + fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); + fputc(']', compiler->verbose); +} + static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if ((p) == SLJIT_IMM) - fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); - else if ((p) & SLJIT_MEM) { - if ((p) & REG_MASK) { - fputc('[', compiler->verbose); - sljit_verbose_reg(compiler, (p) & REG_MASK); - if ((p) & OFFS_REG_MASK) { - fprintf(compiler->verbose, " + "); - sljit_verbose_reg(compiler, OFFS_REG(p)); - if (i) - fprintf(compiler->verbose, " * %d", 1 << (i)); - } - else if (i) - fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); - fputc(']', compiler->verbose); - } - else - fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); - } else + if (p == SLJIT_IMM) + fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", i); + else if (p & SLJIT_MEM) + sljit_verbose_mem(compiler, p, i); + else sljit_verbose_reg(compiler, p); } static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if ((p) & SLJIT_MEM) { - if ((p) & REG_MASK) { - fputc('[', compiler->verbose); - sljit_verbose_reg(compiler, (p) & REG_MASK); - if ((p) & OFFS_REG_MASK) { - fprintf(compiler->verbose, " + "); - sljit_verbose_reg(compiler, OFFS_REG(p)); - if (i) - fprintf(compiler->verbose, "%d", 1 << (i)); - } - else if (i) - fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); - fputc(']', compiler->verbose); - } - else - fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); - } + if (p & SLJIT_MEM) + sljit_verbose_mem(compiler, p, i); else sljit_verbose_freg(compiler, p); } +static void sljit_verbose_vparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) +{ + if (p & SLJIT_MEM) + sljit_verbose_mem(compiler, p, i); + else + sljit_verbose_vreg(compiler, p); +} + static const char* op0_names[] = { "breakpoint", "nop", "lmul.uw", "lmul.sw", "divmod.u", "divmod.s", "div.u", "div.s", - "endbr", "skip_frames_before_return" + "memory_barrier", "endbr", "skip_frames_before_return" }; static const char* op1_names[] = { @@ -1184,7 +1288,7 @@ static const char* fop2r_names[] = { }; static const char* simd_op2_names[] = { - "and", "or", "xor" + "and", "or", "xor", "shuffle" }; static const char* jump_names[] = { @@ -1224,12 +1328,13 @@ static const char* call_arg_names[] = { || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) #define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1 +#define SLJIT_CHECK_OPCODE(op, flags) ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK | (flags))) static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) struct sljit_jump *jump; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ SLJIT_UNUSED_ARG(compiler); @@ -1241,7 +1346,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com CHECK_ARGUMENT((jump->flags & JUMP_ADDR) || jump->u.label != NULL); jump = jump->next; } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ CHECK_RETURN_OK; } @@ -1252,9 +1357,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com #endif /* !SLJIT_CONFIG_X86 */ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + sljit_s32 real_scratches = ENTER_GET_REGS(scratches); + sljit_s32 real_saveds = ENTER_GET_REGS(saveds); + sljit_s32 real_fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 real_fsaveds = ENTER_GET_FLOAT_REGS(saveds); + sljit_s32 real_vscratches = ENTER_GET_VECTOR_REGS(scratches); + sljit_s32 real_vsaveds = ENTER_GET_VECTOR_REGS(saveds); +#endif /* SLJIT_ARGUMENT_CHECKS */ SLJIT_UNUSED_ARG(compiler); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1264,18 +1377,23 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0); } CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds); - CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); - CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); - CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT((scratches & ~0xffffff) == 0 && (saveds & ~0xffffff) == 0); + CHECK_ARGUMENT(real_scratches >= 0 && real_scratches <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(real_saveds >= 0 && real_saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); + CHECK_ARGUMENT(real_scratches + real_saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(real_fscratches >= 0 && real_fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(real_fsaveds >= 0 && real_fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); + CHECK_ARGUMENT(real_fscratches + real_fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(real_vscratches >= 0 && real_vscratches <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); + CHECK_ARGUMENT(real_vsaveds >= 0 && real_vsaveds <= SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS); + CHECK_ARGUMENT(real_vscratches + real_vsaveds <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) <= SLJIT_ARG_TYPE_F32); - CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches)); + CHECK_ARGUMENT(function_check_arguments(arg_types, real_scratches, + (options & SLJIT_ENTER_REG_ARG) ? 0 : real_saveds, real_fscratches)); compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " enter ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]); @@ -1307,17 +1425,26 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil } #endif /* !SLJIT_CONFIG_X86 */ - fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", - scratches, saveds, fscratches, fsaveds, local_size); + fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, vscratches:%d, vsaveds:%d, local_size:%d\n", + ENTER_GET_REGS(scratches), ENTER_GET_REGS(saveds), ENTER_GET_FLOAT_REGS(scratches), ENTER_GET_FLOAT_REGS(saveds), + ENTER_GET_VECTOR_REGS(scratches), ENTER_GET_VECTOR_REGS(saveds), local_size); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + sljit_s32 real_scratches = ENTER_GET_REGS(scratches); + sljit_s32 real_saveds = ENTER_GET_REGS(saveds); + sljit_s32 real_fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 real_fsaveds = ENTER_GET_FLOAT_REGS(saveds); + sljit_s32 real_vscratches = ENTER_GET_VECTOR_REGS(scratches); + sljit_s32 real_vsaveds = ENTER_GET_VECTOR_REGS(saveds); +#endif /* SLJIT_ARGUMENT_CHECKS */ SLJIT_UNUSED_ARG(compiler); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1327,18 +1454,23 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0); } CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds); - CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); - CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); - CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT((scratches & ~0xffffff) == 0 && (saveds & ~0xffffff) == 0); + CHECK_ARGUMENT(real_scratches >= 0 && real_scratches <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(real_saveds >= 0 && real_saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); + CHECK_ARGUMENT(real_scratches + real_saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(real_fscratches >= 0 && real_fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(real_fsaveds >= 0 && real_fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); + CHECK_ARGUMENT(real_fscratches + real_fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(real_vscratches >= 0 && real_vscratches <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); + CHECK_ARGUMENT(real_vsaveds >= 0 && real_vsaveds <= SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS); + CHECK_ARGUMENT(real_vscratches + real_vsaveds <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64); - CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches)); + CHECK_ARGUMENT(function_check_arguments(arg_types, real_scratches, + (options & SLJIT_ENTER_REG_ARG) ? 0 : real_saveds, real_fscratches)); compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " set_context ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]); @@ -1370,10 +1502,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi } #endif /* !SLJIT_CONFIG_X86 */ - fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", - scratches, saveds, fscratches, fsaveds, local_size); + fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, vscratches:%d, vsaveds:%d, local_size:%d\n", + ENTER_GET_REGS(scratches), ENTER_GET_REGS(saveds), ENTER_GET_FLOAT_REGS(scratches), ENTER_GET_FLOAT_REGS(saveds), + ENTER_GET_VECTOR_REGS(scratches), ENTER_GET_VECTOR_REGS(saveds), local_size); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1388,13 +1521,13 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_RET_VOID); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " return_void\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1427,13 +1560,13 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi break; } - if (GET_OPCODE(op) < SLJIT_MOV_F64) { + if (SLJIT_CHECK_OPCODE(op, 0) < SLJIT_MOV_F64) { FUNCTION_CHECK_SRC(src, srcw); } else { FUNCTION_FCHECK(src, srcw, op & SLJIT_32); } compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (GET_OPCODE(op) < SLJIT_MOV_F64) { @@ -1446,7 +1579,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi } fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1455,14 +1588,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_co { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_SRC(src, srcw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " return_to "); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1471,11 +1604,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW) || ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW) - || (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN)); - CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2); - if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN) + || (op >= SLJIT_MEMORY_BARRIER && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN)); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) < SLJIT_LMUL_UW || SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MEMORY_BARRIER || compiler->scratches >= 2); + if ((SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_LMUL_UW && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN) compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1485,7 +1618,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler } fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1499,7 +1632,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_REV_S32); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MOV && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_REV_S32); switch (GET_OPCODE(op)) { case SLJIT_MOV: @@ -1520,7 +1653,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler FUNCTION_CHECK_DST(dst, dstw); FUNCTION_CHECK_SRC(src, srcw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], @@ -1531,7 +1664,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1546,26 +1679,37 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); - CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z | VARIABLE_FLAG_MASK) >= SLJIT_MOV + && SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z | VARIABLE_FLAG_MASK) <= SLJIT_MOV_P); + CHECK_ARGUMENT((op & (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)) != (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)); /* All arguments must be valid registers. */ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); - if (op == SLJIT_MOV32_U8 || op == SLJIT_MOV32_U16) { - /* Only SLJIT_32 is allowed. */ - CHECK_ARGUMENT(!(op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z))); - } else { + if (GET_OPCODE(op) < SLJIT_MOV_U8 || GET_OPCODE(op) > SLJIT_MOV_S16) { /* Nothing allowed. */ - CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))); + CHECK_ARGUMENT(!(op & SLJIT_32)); } compiler->last_flags = 0; #endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " atomic_load%s%s ", !(op & SLJIT_32) ? "" : "32", + if (op & SLJIT_ATOMIC_TEST) + CHECK_RETURN_OK; + if (sljit_emit_atomic_load(compiler, op | SLJIT_ATOMIC_TEST, dst_reg, mem_reg)) { + fprintf(compiler->verbose, " # atomic_load: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " atomic_load"); + if (op & SLJIT_ATOMIC_USE_CAS) + fprintf(compiler->verbose, "_cas"); + if (op & SLJIT_ATOMIC_USE_LS) + fprintf(compiler->verbose, "_ls"); + + fprintf(compiler->verbose, "%s%s ", !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); sljit_verbose_reg(compiler, dst_reg); fprintf(compiler->verbose, ", ["); @@ -1588,29 +1732,40 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); - CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z) >= SLJIT_MOV + && SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z) <= SLJIT_MOV_P); + CHECK_ARGUMENT((op & (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)) != (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)); /* All arguments must be valid registers. */ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && src_reg != temp_reg); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && (src_reg != temp_reg || (op & SLJIT_ATOMIC_USE_LS))); - CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_ATOMIC_STORED); + CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE_MASK(op) == SLJIT_ATOMIC_STORED); - if (GET_OPCODE(op) == SLJIT_MOV_U8 || GET_OPCODE(op) == SLJIT_MOV_U16) { - /* Only SLJIT_32, SLJIT_ATOMIC_STORED are allowed. */ - CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); - } else { - /* Only SLJIT_ATOMIC_STORED is allowed. */ - CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z))); + if (GET_OPCODE(op) < SLJIT_MOV_U8 || GET_OPCODE(op) > SLJIT_MOV_S16) { + /* Nothing allowed. */ + CHECK_ARGUMENT(!(op & SLJIT_32)); } - compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32); + compiler->last_flags = GET_FLAG_TYPE_MASK(op) | (op & SLJIT_32); #endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " atomic_store%s%s%s ", !(op & SLJIT_32) ? "" : "32", + if (op & SLJIT_ATOMIC_TEST) + CHECK_RETURN_OK; + if (sljit_emit_atomic_store(compiler, op | SLJIT_ATOMIC_TEST, src_reg, mem_reg, temp_reg)) { + fprintf(compiler->verbose, " # atomic_store: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " atomic_store"); + if (op & SLJIT_ATOMIC_USE_CAS) + fprintf(compiler->verbose, "_cas"); + if (op & SLJIT_ATOMIC_USE_LS) + fprintf(compiler->verbose, "_ls"); + + fprintf(compiler->verbose, "%s%s%s ", !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & VARIABLE_FLAG_MASK) ? "" : ".stored"); sljit_verbose_reg(compiler, src_reg); fprintf(compiler->verbose, ", ["); @@ -1634,7 +1789,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ROTR); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ROTR); switch (GET_OPCODE(op)) { case SLJIT_AND: @@ -1687,7 +1842,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32", @@ -1703,7 +1858,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler sljit_verbose_param(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1718,7 +1873,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compile FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s ", op2r_names[GET_OPCODE(op) - SLJIT_OP2R_BASE], !(op & SLJIT_32) ? "" : "32"); @@ -1730,7 +1885,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compile sljit_verbose_param(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1741,15 +1896,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_c sljit_s32 src3, sljit_sw src3w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR - || GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_SHL || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_LSHR + || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_MSHL || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_MLSHR); CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src1_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg)); FUNCTION_CHECK_SRC(src3, src3w); CHECK_ARGUMENT(dst_reg != src2_reg); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32", @@ -1764,7 +1919,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_c sljit_verbose_param(compiler, src3, src3w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1781,14 +1936,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compi } else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) { CHECK_ARGUMENT(src & SLJIT_MEM); } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1801,14 +1956,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_dst(struct sljit_compi if (op == SLJIT_FAST_ENTER) compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1820,12 +1975,19 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 t if (type == SLJIT_GP_REGISTER) { CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS) || (reg >= SLJIT_TMP_REGISTER_BASE && reg < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS))); - } else { - CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6))); + } +#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) + else if (((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6))) { + CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_VECTOR_REGISTERS) + || (reg >= SLJIT_TMP_VREGISTER_BASE && reg < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS))); + } +#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */ + else { + CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6) || (type & (3 << 12)) || (type & (4 << 12)) || (type & (5 << 12)) || (type & (6 << 12)))); CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS) || (reg >= SLJIT_TMP_FREGISTER_BASE && reg < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))); } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ CHECK_RETURN_OK; } @@ -1834,7 +1996,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) sljit_u32 i; -#endif +#endif /* SLJIT_VERBOSE */ SLJIT_UNUSED_ARG(compiler); @@ -1848,12 +2010,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0)); #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) CHECK_ARGUMENT(size == 2 || size == 4 || size == 6); -#else +#else /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_CONFIG_S390X */ CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0); -#endif +#endif /* SLJIT_CONFIG_X86 */ compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " op_custom"); @@ -1861,7 +2023,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1876,11 +2038,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MOV_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ABS_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_FCHECK(src, srcw, op & SLJIT_32); FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) @@ -1895,7 +2057,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile sljit_verbose_fparam(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1905,7 +2067,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1914,13 +2076,13 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_CMP_F64); CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK) || (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL)); FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); @@ -1933,7 +2095,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1951,7 +2113,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_FCHECK(src, srcw, op & SLJIT_32); FUNCTION_CHECK_DST(dst, dstw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], @@ -1962,7 +2124,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str sljit_verbose_fparam(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -1980,7 +2142,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(stru CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_CHECK_SRC(src, srcw); FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from.%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], @@ -1991,7 +2153,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(stru sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2007,12 +2169,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_DIV_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); @@ -2023,7 +2185,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2034,11 +2196,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compil { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_COPYSIGN_F64); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_COPYSIGN_F64); FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, op & SLJIT_32)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s ", fop2r_names[GET_OPCODE(op) - SLJIT_FOP2R_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); @@ -2049,7 +2211,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compil sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2066,14 +2228,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset32(struct sljit_compi #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 1)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fset32 "); sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", %f\n", value); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2090,14 +2252,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset64(struct sljit_compi #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fset64 "); sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", %f\n", value); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2106,7 +2268,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compil { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_COPY_TO_F64 && GET_OPCODE(op) <= SLJIT_COPY_FROM_F64); + CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_COPY_TO_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_COPY_FROM_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32)); @@ -2135,7 +2297,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compil break; } #endif /* SLJIT_64BIT_ARCHITECTURE */ -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " copy%s_%s_f%s ", (op & SLJIT_32) ? "32" : "", @@ -2155,7 +2317,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compil fprintf(compiler->verbose, "\n"); } } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2170,12 +2332,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, "label:\n"); -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2185,9 +2347,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil #define CHECK_UNORDERED(type, last_flags) \ ((((type) & 0xfe) == SLJIT_ORDERED) && \ ((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL) -#else +#else /* !SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM */ #define CHECK_UNORDERED(type, last_flags) 0 -#endif +#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM */ #endif /* SLJIT_ARGUMENT_CHECKS */ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) @@ -2211,12 +2373,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(type, compiler->last_flags)); } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, " jump%s %s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2237,7 +2399,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compile CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG); } } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s ret[%s", jump_names[type & 0xff], @@ -2257,7 +2419,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compile } fprintf(compiler->verbose, "]\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2271,7 +2433,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " cmp%s%s %s, ", (type & SLJIT_32) ? "32" : "", @@ -2281,7 +2443,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler sljit_verbose_param(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2296,7 +2458,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile FUNCTION_FCHECK(src1, src1w, type & SLJIT_32); FUNCTION_FCHECK(src2, src2w, type & SLJIT_32); compiler->last_flags = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fcmp%s%s %s, ", (type & SLJIT_32) ? ".f32" : ".f64", @@ -2306,7 +2468,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2321,14 +2483,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compil #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL); FUNCTION_CHECK_SRC(src, srcw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " ijump.%s ", jump_names[type]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2351,7 +2513,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compil CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG); } } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " i%s%s ret[%s", jump_names[type & 0xff], @@ -2372,7 +2534,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compil sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2383,7 +2545,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32 - || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); + || (SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_AND && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_XOR)); CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)); if (type <= SLJIT_NOT_ZERO) @@ -2396,7 +2558,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com if (GET_OPCODE(op) >= SLJIT_ADD) compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " flags.%s%s%s ", @@ -2406,7 +2568,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", %s\n", jump_names[type]); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2433,7 +2595,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compi } else CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(cond, compiler->last_flags)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " select%s %s, ", @@ -2446,7 +2608,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compi sljit_verbose_reg(compiler, src2_reg); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2473,7 +2635,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_comp } else CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(cond, compiler->last_flags)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fselect%s %s, ", @@ -2486,7 +2648,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_comp sljit_verbose_freg(compiler, src2_freg); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2540,7 +2702,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler } FUNCTION_CHECK_SRC_MEM(mem, memw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if ((type & 0xff) == SLJIT_MOV32) @@ -2572,7 +2734,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2591,7 +2753,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_c CHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg); FUNCTION_CHECK_SRC_MEM(mem, memw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_MEM_SUPP) @@ -2617,7 +2779,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_c sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2641,7 +2803,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); FUNCTION_CHECK_SRC_MEM(mem, memw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s.%s", @@ -2661,7 +2823,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2675,7 +2837,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0); FUNCTION_CHECK_SRC_MEM(mem, memw); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_MEM_SUPP) @@ -2695,12 +2857,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2709,14 +2871,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_com CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); - FUNCTION_FCHECK(srcdst, srcdstw, 0); -#endif + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); + FUNCTION_VCHECK(srcdst, srcdstw, type); +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, freg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, vreg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_mem: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2732,17 +2894,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_com else fprintf(compiler->verbose, ".al%d ", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type))); - sljit_verbose_freg(compiler, freg); + sljit_verbose_vreg(compiler, vreg); fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, srcdst, srcdstw); + sljit_verbose_vparam(compiler, srcdst, srcdstw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2750,7 +2912,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) { @@ -2761,12 +2923,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj } else if (src != SLJIT_IMM) { FUNCTION_CHECK_DST(src, srcw); } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, vreg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_dup: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2776,7 +2938,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_freg(compiler, freg); + sljit_verbose_vreg(compiler, vreg); fprintf(compiler->verbose, ", "); if (type & SLJIT_SIMD_FLOAT) sljit_verbose_fparam(compiler, src, srcw); @@ -2784,12 +2946,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2801,7 +2963,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); CHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); CHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); if (type & SLJIT_SIMD_FLOAT) { @@ -2809,12 +2971,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji } else if ((type & SLJIT_SIMD_STORE) || srcdst != SLJIT_IMM) { FUNCTION_CHECK_DST(srcdst, srcdstw); } -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, freg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, vreg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_move_lane: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2828,7 +2990,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_freg(compiler, freg); + sljit_verbose_vreg(compiler, vreg); fprintf(compiler->verbose, "[%d], ", lane_index); if (type & SLJIT_SIMD_FLOAT) sljit_verbose_fparam(compiler, srcdst, srcdstw); @@ -2836,12 +2998,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji sljit_verbose_param(compiler, srcdst, srcdstw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2849,15 +3011,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struc CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src, type)); CHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, vreg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_lane_replicate: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2867,17 +3029,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struc (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_freg(compiler, freg); + sljit_verbose_vreg(compiler, vreg); fprintf(compiler->verbose, ", "); - sljit_verbose_freg(compiler, src); + sljit_verbose_vreg(compiler, src); fprintf(compiler->verbose, "[%d]\n", src_lane_index); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2887,14 +3049,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_ CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); - FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); -#endif + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); + FUNCTION_VCHECK(src, srcw, type); +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, vreg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_extend: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2907,17 +3069,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_ (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_freg(compiler, freg); + sljit_verbose_vreg(compiler, vreg); fprintf(compiler->verbose, ", "); - sljit_verbose_fparam(compiler, src, srcw); + sljit_verbose_vparam(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2925,14 +3087,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_co CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); FUNCTION_CHECK_DST(dst, dstw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, freg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, vreg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_sign: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2943,50 +3105,56 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_co (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_freg(compiler, freg); + sljit_verbose_vreg(compiler, vreg); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); - CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK(0)) <= SLJIT_SIMD_OP2_XOR); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK2(0)) <= SLJIT_SIMD_OP2_SHUFFLE); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, 0)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src1_freg, 0)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, 0)); -#endif + CHECK_ARGUMENT(SLJIT_SIMD_GET_OPCODE(type) != SLJIT_SIMD_OP2_SHUFFLE || (SLJIT_SIMD_GET_ELEM_SIZE(type) == 0 && !(type & SLJIT_SIMD_FLOAT))); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (src2 & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(dst_vreg, type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src1_vreg, type)); + FUNCTION_VCHECK(src2, src2w, type); +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_freg, src1_freg, src2_freg) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_vreg, src1_vreg, src2, src2w) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_op2: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } - fprintf(compiler->verbose, " simd_%s.%d.%s%d ", + fprintf(compiler->verbose, " simd_%s.%d.%s%d", simd_op2_names[SLJIT_SIMD_GET_OPCODE(type) - 1], (8 << SLJIT_SIMD_GET_REG_SIZE(type)), (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_freg(compiler, dst_freg); + if ((type & 0x3f000000) != SLJIT_SIMD_MEM_UNALIGNED) + fprintf(compiler->verbose, ".al%d", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type))); + + fprintf(compiler->verbose, " "); + sljit_verbose_vreg(compiler, dst_vreg); fprintf(compiler->verbose, ", "); - sljit_verbose_freg(compiler, src1_freg); + sljit_verbose_vreg(compiler, src1_vreg); fprintf(compiler->verbose, ", "); - sljit_verbose_freg(compiler, src2_freg); + sljit_verbose_vparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -2997,14 +3165,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " local_base "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -3014,14 +3182,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " const "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -3029,14 +3197,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mov_addr(struct sljit_com { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); -#endif +#endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " mov_addr "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, "\n"); } -#endif +#endif /* SLJIT_VERBOSE */ CHECK_RETURN_OK; } @@ -3114,23 +3282,23 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji #define SLJIT_CPUINFO_PART1 " 32bit (" #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) #define SLJIT_CPUINFO_PART1 " 64bit (" -#else +#else /* !SLJIT_32BIT_ARCHITECTURE && !SLJIT_64BIT_ARCHITECTURE */ #error "Internal error: CPU type info missing" -#endif +#endif /* SLJIT_32BIT_ARCHITECTURE */ #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) #define SLJIT_CPUINFO_PART2 "little endian + " #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) #define SLJIT_CPUINFO_PART2 "big endian + " -#else +#else /* !SLJIT_LITTLE_ENDIAN && !SLJIT_BIG_ENDIAN */ #error "Internal error: CPU type info missing" -#endif +#endif /* SLJIT_LITTLE_ENDIAN */ #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) #define SLJIT_CPUINFO_PART3 "unaligned)" -#else +#else /* !SLJIT_UNALIGNED */ #define SLJIT_CPUINFO_PART3 "aligned)" -#endif +#endif /* SLJIT_UNALIGNED */ #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 @@ -3154,7 +3322,7 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji # include "sljitNativeS390X.c" #elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) # include "sljitNativeLOONGARCH_64.c" -#endif +#endif /* SLJIT_CONFIG_X86 */ #include "sljitSerialize.c" @@ -3164,10 +3332,10 @@ static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *comp /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; -#else +#else /* !SLJIT_64BIT_ARCHITECTURE */ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; -#endif +#endif /* SLJIT_64BIT_ARCHITECTURE */ SLJIT_SKIP_CHECKS(compiler); return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw); @@ -3249,7 +3417,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler if (src2 == SLJIT_IMM && !src2w) return emit_cmp_to0(compiler, type, src1, src1w); } -#endif +#endif /* SLJIT_CONFIG_ARM_64 */ if (SLJIT_UNLIKELY(src1 == SLJIT_IMM && src2 != SLJIT_IMM)) { /* Immediate is preferred as second argument by most architectures. */ @@ -3389,17 +3557,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ && !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(vreg); SLJIT_UNUSED_ARG(srcdst); SLJIT_UNUSED_ARG(srcdstw); @@ -3407,14 +3576,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(vreg); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); @@ -3422,14 +3591,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(vreg); SLJIT_UNUSED_ARG(lane_index); SLJIT_UNUSED_ARG(srcdst); SLJIT_UNUSED_ARG(srcdstw); @@ -3438,14 +3607,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(vreg); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(src_lane_index); @@ -3453,14 +3622,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(vreg); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); @@ -3468,14 +3637,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(vreg); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); @@ -3483,56 +3652,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(dst_freg); - SLJIT_UNUSED_ARG(src1_freg); - SLJIT_UNUSED_ARG(src2_freg); - - return SLJIT_ERR_UNSUPPORTED; -} - -#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM */ - -#if !(defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86) \ - && !(defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM) \ - && !(defined(SLJIT_CONFIG_S390X) && SLJIT_CONFIG_S390X) \ - && !(defined(SLJIT_CONFIG_LOONGARCH) && SLJIT_CONFIG_LOONGARCH) - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, - sljit_s32 op, - sljit_s32 dst_reg, - sljit_s32 mem_reg) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst_reg); - SLJIT_UNUSED_ARG(mem_reg); - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, - sljit_s32 op, - sljit_s32 src_reg, - sljit_s32 mem_reg, - sljit_s32 temp_reg) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src_reg); - SLJIT_UNUSED_ARG(mem_reg); - SLJIT_UNUSED_ARG(temp_reg); - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + SLJIT_UNUSED_ARG(dst_vreg); + SLJIT_UNUSED_ARG(src1_vreg); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); return SLJIT_ERR_UNSUPPORTED; } diff --git a/ext/pcre/pcre2lib/sljit/sljitLir.h b/ext/pcre/pcre2lib/sljit/sljitLir.h index 8b6fa69a0a299..60d34f1543057 100644 --- a/ext/pcre/pcre2lib/sljit/sljitLir.h +++ b/ext/pcre/pcre2lib/sljit/sljitLir.h @@ -87,7 +87,7 @@ of sljitConfigInternal.h */ #ifdef __cplusplus extern "C" { -#endif +#endif /* __cplusplus */ /* Version numbers. */ #define SLJIT_MAJOR_VERSION 0 @@ -251,7 +251,7 @@ extern "C" { #define SLJIT_FS7 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 7) #define SLJIT_FS8 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 8) #define SLJIT_FS9 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 9) -/* All S registers provided by the architecture can be accessed by SLJIT_FS(i) +/* All FS registers provided by the architecture can be accessed by SLJIT_FS(i) The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */ #define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i)) @@ -262,6 +262,52 @@ extern "C" { #define SLJIT_RETURN_FREG SLJIT_FR0 +/* --------------------------------------------------------------------- */ +/* Vector registers */ +/* --------------------------------------------------------------------- */ + +/* Vector registers are storage areas, which are used for Single Instruction + Multiple Data (SIMD) computations. The VR and VS register sets overlap + in the same way as R and S register sets. See above. + + The storage space of vector registers often overlap with floating point + registers. In this case setting the value of SLJIT_VR(i) destroys the + value of SLJIT_FR(i) and vice versa. See SLJIT_SEPARATE_VECTOR_REGISTERS + macro. */ + +/* Vector scratch registers. */ +#define SLJIT_VR0 1 +#define SLJIT_VR1 2 +#define SLJIT_VR2 3 +#define SLJIT_VR3 4 +#define SLJIT_VR4 5 +#define SLJIT_VR5 6 +#define SLJIT_VR6 7 +#define SLJIT_VR7 8 +#define SLJIT_VR8 9 +#define SLJIT_VR9 10 +/* All VR registers provided by the architecture can be accessed by SLJIT_VR(i) + The i parameter must be >= 0 and < SLJIT_NUMBER_OF_VECTOR_REGISTERS. */ +#define SLJIT_VR(i) (1 + (i)) + +/* Vector saved registers. */ +#define SLJIT_VS0 (SLJIT_NUMBER_OF_VECTOR_REGISTERS) +#define SLJIT_VS1 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 1) +#define SLJIT_VS2 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 2) +#define SLJIT_VS3 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 3) +#define SLJIT_VS4 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 4) +#define SLJIT_VS5 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 5) +#define SLJIT_VS6 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 6) +#define SLJIT_VS7 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 7) +#define SLJIT_VS8 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 8) +#define SLJIT_VS9 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 9) +/* All VS registers provided by the architecture can be accessed by SLJIT_VS(i) + The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS. */ +#define SLJIT_VS(i) (SLJIT_NUMBER_OF_VECTOR_REGISTERS - (i)) + +/* Vector registers >= SLJIT_FIRST_SAVED_VECTOR_REG are saved registers. */ +#define SLJIT_FIRST_SAVED_VECTOR_REG (SLJIT_VS0 - SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS + 1) + /* --------------------------------------------------------------------- */ /* Argument type definitions */ /* --------------------------------------------------------------------- */ @@ -483,6 +529,15 @@ struct sljit_compiler { sljit_s32 fscratches; /* Available float saved registers. */ sljit_s32 fsaveds; +#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \ + || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ + || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ + || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + /* Available vector scratch registers. */ + sljit_s32 vscratches; + /* Available vector saved registers. */ + sljit_s32 vsaveds; +#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG || SLJIT_VERBOSE */ /* Local stack size. */ sljit_s32 local_size; /* Maximum code size. */ @@ -563,6 +618,7 @@ struct sljit_compiler { FILE* verbose; #endif /* SLJIT_VERBOSE */ + /* Note: SLJIT_DEBUG enables SLJIT_ARGUMENT_CHECKS. */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Flags specified by the last arithmetic instruction. @@ -577,6 +633,13 @@ struct sljit_compiler { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) + /* Available float scratch registers. */ + sljit_s32 real_fscratches; + /* Available float saved registers. */ + sljit_s32 real_fsaveds; +#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ + /* Trust arguments when an API function is called. Used internally for calling API functions. */ sljit_s32 skip_checks; @@ -634,7 +697,7 @@ static SLJIT_INLINE void* sljit_compiler_get_user_data(struct sljit_compiler *co #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); -#endif +#endif /* SLJIT_VERBOSE */ /* Option bits for sljit_generate_code. */ @@ -680,7 +743,9 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler support while others (e.g. move with update) are emulated if not available. However, even when a feature is emulated, specialized code paths may be faster than the emulation. Some limitations are emulated as well so their - general case is supported but it has extra performance costs. */ + general case is supported but it has extra performance costs. + + Note: sljitConfigInternal.h also provides several feature detection macros. */ /* [Not emulated] Floating-point support is available. */ #define SLJIT_HAS_FPU 0 @@ -715,20 +780,22 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler a simd operation represents the same 128 bit register, and both SLJIT_FR0 and SLJIT_FR1 are overwritten. */ #define SLJIT_SIMD_REGS_ARE_PAIRS 13 -/* [Not emulated] Atomic support is available (fine-grained). */ -#define SLJIT_HAS_ATOMIC 14 +/* [Not emulated] Atomic support is available. */ +#define SLJIT_HAS_ATOMIC 14 +/* [Not emulated] Memory barrier support is available. */ +#define SLJIT_HAS_MEMORY_BARRIER 15 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* [Not emulated] AVX support is available on x86. */ #define SLJIT_HAS_AVX 100 /* [Not emulated] AVX2 support is available on x86. */ #define SLJIT_HAS_AVX2 101 -#endif +#endif /* SLJIT_CONFIG_X86 */ #if (defined SLJIT_CONFIG_LOONGARCH) /* [Not emulated] LASX support is available on LoongArch */ #define SLJIT_HAS_LASX 201 -#endif +#endif /* SLJIT_CONFIG_LOONGARCH */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type); @@ -749,42 +816,65 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); with an error code. */ /* - The executable code is a function from the viewpoint of the C - language. The function calls must conform to the ABI (Application - Binary Interface) of the platform, which specify the purpose of - machine registers and stack handling among other things. The - sljit_emit_enter function emits the necessary instructions for - setting up a new context for the executable code. This is often - called as function prologue. Furthermore the options argument - can be used to pass configuration options to the compiler. The + The executable code is a callable function from the viewpoint + of the C language. Function calls must conform with the ABI + (Application Binary Interface) of the target platform, which + specify the purpose of machine registers and stack handling + among other things. The sljit_emit_enter function emits the + necessary instructions for setting up an entry point for the + executable code. This is often called as function prologue. + + The "options" argument can be used to pass configuration options + to the sljit compiler which affects the generated code, until + another sljit_emit_enter or sljit_set_context is called. The available options are listed before sljit_emit_enter. The function argument list is specified by the SLJIT_ARGSx (SLJIT_ARGS0 .. SLJIT_ARGS4) macros. Currently maximum four arguments are supported. See the description of SLJIT_ARGSx - macros about argument passing. Furthermore the register set - used by the function must be declared as well. The number of - scratch and saved registers available to the function must - be passed to sljit_emit_enter. Only R registers between R0 - and "scratches" argument can be used later. E.g. if "scratches" - is set to two, the scratch register set will be limited to - SLJIT_R0 and SLJIT_R1. The S registers and the floating point - registers ("fscratches" and "fsaveds") are specified in a - similar manner. The sljit_emit_enter is also capable of - allocating a stack space for local data. The "local_size" - argument contains the size in bytes of this local area, and - it can be accessed using SLJIT_MEM1(SLJIT_SP). The memory - area between SLJIT_SP (inclusive) and SLJIT_SP + local_size - (exclusive) can be modified freely until the function returns. - The stack space is not initialized to zero. + macros about argument passing. + + The register set used by the function must be declared as well. + The number of scratch and saved registers available to the + function must be passed to sljit_emit_enter. Only R registers + between R0 and "scratches" argument can be used later. E.g. + if "scratches" is set to two, the scratch register set will + be limited to SLJIT_R0 and SLJIT_R1. The S registers are + declared in a similar manner, but their count is specified + by "saveds" argument. The floating point scratch and saved + registers can be set by using "scratches" and "saveds" argument + as well, but their value must be passed to the SLJIT_ENTER_FLOAT + macro, see below. + + The sljit_emit_enter is also capable of allocating a stack + space for local data. The "local_size" argument contains the + size in bytes of this local area, and it can be accessed using + SLJIT_MEM1(SLJIT_SP). The memory area between SLJIT_SP (inclusive) + and SLJIT_SP + local_size (exclusive) can be modified freely + until the function returns. The alocated stack space is an + uninitialized memory area. + + Floating point scratch and saved registers must be specified + by the SLJIT_ENTER_FLOAT macro, which result value should be + combined with scratches / saveds argument. + + Examples: + To use three scratch and four floating point scratch + registers, the "scratches" argument must be set to: + 3 | SLJIT_ENTER_FLOAT(4) + + To use six saved and five floating point saved + registers, the "saveds" argument must be set to: + 6 | SLJIT_ENTER_FLOAT(5) Note: the following conditions must met: 0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS 0 <= saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS - 0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS - 0 <= fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS - fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS + + 0 <= float scratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS + 0 <= float saveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + float scratches + float saveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS Note: the compiler can use saved registers as scratch registers, but the opposite is not supported @@ -793,6 +883,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); overwrites the previous context. */ +/* The following options are available for sljit_emit_enter. */ + /* Saved registers between SLJIT_S0 and SLJIT_S(n - 1) (inclusive) are not saved / restored on function enter / return. Instead, these registers can be used to pass / return data (such as @@ -808,17 +900,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); and all arguments must be stored in scratch registers. */ #define SLJIT_ENTER_REG_ARG 0x00000004 -/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ -#define SLJIT_MAX_LOCAL_SIZE 1048576 - #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* Use VEX prefix for all SIMD operations on x86. */ #define SLJIT_ENTER_USE_VEX 0x00010000 #endif /* !SLJIT_CONFIG_X86 */ +/* Macros for other sljit_emit_enter arguments. */ + +/* Floating point scratch and saved registers can be + specified by SLJIT_ENTER_FLOAT. */ +#define SLJIT_ENTER_FLOAT(regs) ((regs) << 8) + +/* Vector scratch and saved registers can be specified + by SLJIT_ENTER_VECTOR. */ +#define SLJIT_ENTER_VECTOR(regs) ((regs) << 16) + +/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ +#define SLJIT_MAX_LOCAL_SIZE 1048576 + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size); /* The SLJIT compiler has a current context (which contains the local stack space size, number of used registers, etc.) which is initialized @@ -834,8 +936,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi the previous context. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size); /* Return to the caller function. The sljit_emit_return_void function does not return with any value. The sljit_emit_return function returns @@ -1092,16 +1194,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c the behaviour is undefined. */ #define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7) #define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_32) +/* Flags: - (does not modify flags) + May return with SLJIT_ERR_UNSUPPORTED if SLJIT_HAS_MEMORY_BARRIER + feature is not supported (calling sljit_has_cpu_feature() with + this feature option returns with 0). */ +#define SLJIT_MEMORY_BARRIER (SLJIT_OP0_BASE + 8) /* Flags: - (does not modify flags) ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64 when Intel Control-flow Enforcement Technology (CET) is enabled. No instructions are emitted for other architectures. */ -#define SLJIT_ENDBR (SLJIT_OP0_BASE + 8) +#define SLJIT_ENDBR (SLJIT_OP0_BASE + 9) /* Flags: - (may destroy flags) Skip stack frames before return when Intel Control-flow Enforcement Technology (CET) is enabled. No instructions are emitted for other architectures. */ -#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 9) +#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 10) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op); @@ -1890,21 +1997,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler /* The following options are used by several simd operations. */ -/* Load data into a simd register, this is the default */ +/* Load data into a vector register, this is the default */ #define SLJIT_SIMD_LOAD 0x000000 -/* Store data from a simd register */ +/* Store data from a vector register */ #define SLJIT_SIMD_STORE 0x000001 -/* The simd register contains floating point values */ +/* The vector register contains floating point values */ #define SLJIT_SIMD_FLOAT 0x000400 /* Tests whether the operation is available */ #define SLJIT_SIMD_TEST 0x000800 -/* Move data to/from a 64 bit (8 byte) long SIMD register */ +/* Move data to/from a 64 bit (8 byte) long vector register */ #define SLJIT_SIMD_REG_64 (3 << 12) -/* Move data to/from a 128 bit (16 byte) long SIMD register */ +/* Move data to/from a 128 bit (16 byte) long vector register */ #define SLJIT_SIMD_REG_128 (4 << 12) -/* Move data to/from a 256 bit (32 byte) long SIMD register */ +/* Move data to/from a 256 bit (32 byte) long vector register */ #define SLJIT_SIMD_REG_256 (5 << 12) -/* Move data to/from a 512 bit (64 byte) long SIMD register */ +/* Move data to/from a 512 bit (64 byte) long vector register */ #define SLJIT_SIMD_REG_512 (6 << 12) /* Element size is 8 bit long (this is the default), usually cannot be combined with SLJIT_SIMD_FLOAT */ #define SLJIT_SIMD_ELEM_8 (0 << 18) @@ -1919,7 +2026,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler /* Element size is 256 bit long */ #define SLJIT_SIMD_ELEM_256 (5 << 18) -/* The following options are used by sljit_emit_simd_mov(). */ +/* The following options are used by sljit_emit_simd_mov() + and sljit_emit_simd_op2(). */ /* Memory address is unaligned (this is the default) */ #define SLJIT_SIMD_MEM_UNALIGNED (0 << 24) @@ -1936,7 +2044,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler /* Memory address is 512 bit aligned */ #define SLJIT_SIMD_MEM_ALIGNED_512 (6 << 24) -/* Moves data between a simd register and memory. +/* Moves data between a vector register and memory. If the operation is not supported, it returns with SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, @@ -1944,21 +2052,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler type must be a combination of SLJIT_SIMD_* and SLJIT_SIMD_MEM_* options - freg is the source or destination simd register + vreg is the source or destination vector register of the operation - srcdst must be a memory operand or a simd register + srcdst must be a memory operand or a vector register Note: The alignment and element size must be - less or equal than simd register size. + less or equal than vector register size. Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw); -/* Replicates a scalar value to all lanes of a simd +/* Replicates a scalar value to all lanes of a vector register. If the operation is not supported, it returns with @@ -1967,7 +2075,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co type must be a combination of SLJIT_SIMD_* options except SLJIT_SIMD_STORE. - freg is the destination simd register of the operation + vreg is the destination vector register of the operation src is the value which is replicated Note: @@ -1977,7 +2085,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw); /* The following options are used by sljit_emit_simd_lane_mov(). */ @@ -1987,7 +2095,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil /* Sign extend the integer value stored from the lane. */ #define SLJIT_SIMD_LANE_SIGNED 0x000004 -/* Moves data between a simd register lane and a register or +/* Moves data between a vector register lane and a register or memory. If the srcdst argument is a register, it must be a floating point register when SLJIT_SIMD_FLOAT is specified, or a general purpose register otherwise. @@ -2003,7 +2111,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil is set and SLJIT_SIMD_FLOAT is not set SLJIT_SIMD_LANE_ZERO - when SLJIT_SIMD_LOAD is specified - freg is the source or destination simd register + vreg is the source or destination vector register of the operation lane_index is the index of the lane srcdst is the destination operand for loads, and @@ -2015,11 +2123,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw); /* Replicates a scalar value from a lane to all lanes - of a simd register. + of a vector register. If the operation is not supported, it returns with SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, @@ -2027,14 +2135,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile type must be a combination of SLJIT_SIMD_* options except SLJIT_SIMD_STORE. - freg is the destination simd register of the operation - src is the simd register which lane is replicated + vreg is the destination vector register of the operation + src is the vector register which lane is replicated src_lane_index is the lane index of the src register Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index); /* The following options are used by sljit_emit_simd_load_extend(). */ @@ -2048,7 +2156,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c /* Extend data to 64 bit */ #define SLJIT_SIMD_EXTEND_64 (3 << 24) -/* Extend elements and stores them in a simd register. +/* Extend elements and stores them in a vector register. The extension operation increases the size of the elements (e.g. from 16 bit to 64 bit). For integer values, the extension can be signed or unsigned. @@ -2059,15 +2167,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c type must be a combination of SLJIT_SIMD_*, and SLJIT_SIMD_EXTEND_* options except SLJIT_SIMD_STORE - freg is the destination simd register of the operation - src must be a memory operand or a simd register. + vreg is the destination vector register of the operation + src must be a memory operand or a vector register. In the latter case, the source elements are stored in the lower half of the register. Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw); /* Extract the highest bit (usually the sign bit) from @@ -2079,16 +2187,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler type must be a combination of SLJIT_SIMD_* and SLJIT_32 options except SLJIT_SIMD_LOAD - freg is the source simd register of the operation + vreg is the source vector register of the operation dst is the destination operand Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw); -/* The following options are used by sljit_emit_simd_op2(). */ +/* The following operations are used by sljit_emit_simd_op2(). */ /* Binary 'and' operation */ #define SLJIT_SIMD_OP2_AND 0x000001 @@ -2096,23 +2204,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c #define SLJIT_SIMD_OP2_OR 0x000002 /* Binary 'xor' operation */ #define SLJIT_SIMD_OP2_XOR 0x000003 +/* Shuffle bytes of src1 using the indicies in src2 */ +#define SLJIT_SIMD_OP2_SHUFFLE 0x000004 -/* Perform simd operations using simd registers. +/* Perform simd operations using vector registers. If the operation is not supported, it returns with SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, it does not emit any instructions. - type must be a combination of SLJIT_SIMD_* and SLJIT_SIMD_OP2_ - options except SLJIT_SIMD_LOAD and SLJIT_SIMD_STORE - dst_freg is the destination register of the operation - src1_freg is the first source register of the operation - src1_freg is the second source register of the operation + type must be a combination of SLJIT_SIMD_*, SLJIT_SIMD_MEM_* + and SLJIT_SIMD_OP2_* options except SLJIT_SIMD_LOAD + and SLJIT_SIMD_STORE + dst_vreg is the destination register of the operation + src1_vreg is the first source register of the operation + src2 is the second source operand of the operation Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg); + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w); + +/* The following operations are used by sljit_emit_atomic_load() and + sljit_emit_atomic_store() operations. */ + +/* Tests whether the atomic operation is available (does not generate + any instructions). When a load from is allowed, its corresponding + store form is allowed and vice versa. */ +#define SLJIT_ATOMIC_TEST 0x10000 +/* The compiler must generate compare and swap instruction. + When this bit is set, calling sljit_emit_atomic_load() is optional. */ +#define SLJIT_ATOMIC_USE_CAS 0x20000 +/* The compiler must generate load-acquire and store-release instructions. + When this bit is set, the temp_reg for sljit_emit_atomic_store is not used. */ +#define SLJIT_ATOMIC_USE_LS 0x40000 /* The sljit_emit_atomic_load and sljit_emit_atomic_store operation pair can perform an atomic read-modify-write operation. First, an unsigned @@ -2121,23 +2246,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co sljit_emit_atomic_store. A thread can only perform a single atomic operation at a time. - Note: atomic operations are experimental, and not implemented - for all cpus. - The following conditions must be satisfied, or the operation is undefined: - the address provided in mem_reg must be divisible by the size of the value (only naturally aligned updates are supported) - - no memory writes are allowed between the load and store operations - regardless of its target address (currently read operations are - allowed, but this might change in the future) + - no memory operations are allowed between the load and store operations - the memory operation (op) and the base address (stored in mem_reg) passed to the load/store operations must be the same (the mem_reg can be a different register, only its value must be the same) - - an store must always follow a load for the same transaction. + - a store must always follow a load for the same transaction. - op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all - signed loads such as SLJIT_MOV32_S16 + op must be between SLJIT_MOV and SLJIT_MOV_P dst_reg is the register where the data will be loaded into mem_reg is the base address of the memory load (it cannot be SLJIT_SP or a virtual register on x86-32) @@ -2151,18 +2270,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler allows performing an atomic read-modify-write operation. See the description of sljit_emit_atomic_load. - op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all signed - loads such as SLJIT_MOV32_S16 + op must be between SLJIT_MOV and SLJIT_MOV_P src_reg is the register which value is stored into the memory mem_reg is the base address of the memory store (it cannot be SLJIT_SP or a virtual register on x86-32) - temp_reg is a not preserved scratch register, which must be - initialized with the value loaded into the dst_reg during the - corresponding sljit_emit_atomic_load operation, or the operation - is undefined - - Flags: ATOMIC_STORED is set if the operation is successful, - otherwise the memory remains unchanged. */ + temp_reg is a scratch register, which must be initialized with + the value loaded into the dst_reg during the corresponding + sljit_emit_atomic_load operation, or the operation is undefined. + The temp_reg register preserves its value, if the memory store + is successful. Otherwise, its value is undefined. + + Flags: ATOMIC_STORED + if ATOMIC_STORED flag is set, it represents that the memory + is updated with a new value. Otherwise the memory is unchanged. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src_reg, sljit_s32 mem_reg, @@ -2457,10 +2577,10 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct it is sometimes desired to free all unused memory regions, e.g. before the application terminates. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); -#endif +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ #ifdef __cplusplus } /* extern "C" */ -#endif +#endif /* __cplusplus */ #endif /* SLJIT_LIR_H_ */ diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c index a253c06f01008..327dc824efc6e 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c @@ -114,6 +114,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define CLZ 0xe16f0f10 #define CMN 0xe1600000 #define CMP 0xe1400000 +#define DMB_SY 0xf57ff05f #define EOR 0xe0200000 #define LDR 0xe5100000 #define LDR_POST 0xe4100000 @@ -180,6 +181,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define VST1_s 0xf4800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 +#define VTBL 0xf3b00800 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Arm v7 specific instructions. */ @@ -198,11 +200,28 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) fr -= SLJIT_F64_SECOND(0); - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) - || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches)) + || (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } +static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type) +{ + sljit_s32 vr_low = vr; + + if (compiler->scratches == -1) + return 0; + + if (SLJIT_SIMD_GET_REG_SIZE(type) == 4) { + vr += (vr & 0x1); + vr_low = vr - 1; + } + + return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches)) + || (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0) + || (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)); +} + #endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) @@ -364,7 +383,7 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ while (last_pc_patch < code_ptr) { /* Data transfer instruction with Rn == r15. */ - if ((*last_pc_patch & 0x0e0f0000) == 0x040f0000) { + if ((*last_pc_patch & 0x0e4f0000) == 0x040f0000) { diff = (sljit_uw)(const_pool - last_pc_patch); ind = (*last_pc_patch) & 0xfff; @@ -476,6 +495,14 @@ static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s3 static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code, sljit_sw executable_offset) { sljit_sw diff; + sljit_uw target_addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; + sljit_uw orig_addr = jump->addr; + SLJIT_UNUSED_ARG(executable_offset); + +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + jump->addr = jump_addr; +#endif if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; @@ -486,12 +513,17 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw #endif /* SLJIT_CONFIG_ARM_V6 */ if (jump->flags & JUMP_ADDR) - diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset); + target_addr = jump->u.target; else { SLJIT_ASSERT(jump->u.label != NULL); - diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)); + target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); + + if (jump->u.label->size > orig_addr) + jump_addr = (sljit_uw)(code + orig_addr); } + diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr + 8, executable_offset); + /* Branch to Thumb code has not been optimized yet. */ if (diff & 0x3) return 0; @@ -503,12 +535,9 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw jump->flags |= PATCH_B; return 1; } - } - else { - if (diff <= 0x01ffffff && diff >= -0x02000000) { - *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); - jump->flags |= PATCH_B; - } + } else if (diff <= 0x01ffffff && diff >= -0x02000000) { + *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); + jump->flags |= PATCH_B; } #else /* !SLJIT_CONFIG_ARM_V6 */ if (diff <= 0x01ffffff && diff >= -0x02000000) { @@ -714,16 +743,21 @@ static void set_const_value(sljit_uw addr, sljit_sw executable_offset, sljit_uw static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else + else { addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); + if (jump->u.label->size > jump->addr) + jump_addr = (sljit_uw)(code + jump->addr); + } + /* The pc+8 offset is represented by the 2 * SSIZE_OF(ins) below. */ - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if ((diff & 0x3) == 0 && diff <= (0x3fc + 2 * SSIZE_OF(ins)) && diff >= (-0x3fc + 2 * SSIZE_OF(ins))) { jump->flags |= PATCH_B; @@ -784,6 +818,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if (diff <= (0x01ffffff / SSIZE_OF(ins)) && diff >= (-0x02000000 / SSIZE_OF(ins))) total_size = 1 - 1; @@ -796,6 +834,11 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } + if (diff <= 0xff + 2 && diff >= -0xff + 2) total_size = 0; } @@ -917,7 +960,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump->addr = (sljit_uw)code_ptr; #else /* !SLJIT_CONFIG_ARM_V6 */ word_count += jump->flags >> JUMP_SIZE_SHIFT; - jump->addr = (sljit_uw)code_ptr; if (!detect_jump_type(jump, code_ptr, code, executable_offset)) { code_ptr[2] = code_ptr[0]; addr = ((code_ptr[0] & 0xf) << 12); @@ -1131,6 +1173,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + case SLJIT_HAS_MEMORY_BARRIER: +#endif /* SLJIT_CONFIG_ARM_V7 */ return 1; case SLJIT_HAS_CTZ: @@ -1225,9 +1270,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 sljit_s32 src2, sljit_sw src2w); SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_uw imm, offset; sljit_s32 i, tmp, size, word_arg_count; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); @@ -1240,11 +1287,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - imm = 0; + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; + imm = 0; tmp = SLJIT_S0 - saveds; for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) imm |= (sljit_uw)1 << reg_map[i]; @@ -1391,15 +1442,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); /* Doubles are saved, so alignment is unaffected. */ @@ -2364,6 +2421,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); } return SLJIT_SUCCESS; + case SLJIT_MEMORY_BARRIER: +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + return push_inst(compiler, DMB_SY); +#else /* !SLJIT_CONFIG_ARM_V7 */ + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_ARM_V7 */ case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2630,7 +2693,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) return freg_map[reg]; - if (type != SLJIT_SIMD_REG_128) + if (type == SLJIT_SIMD_REG_128) return freg_map[reg] & ~0x1; return -1; @@ -3105,9 +3168,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile if (type >= SLJIT_FAST_CALL) PTR_FAIL_IF(prepare_blx(compiler)); - jump->addr = compiler->size; PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(compiler, type), 0)); + jump->addr = compiler->size - 1; if (jump->flags & SLJIT_REWRITABLE_JUMP) compiler->patches++; @@ -3907,7 +3970,7 @@ static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) #define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3916,7 +3979,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3930,16 +3993,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (!(srcdst & SLJIT_MEM)) { if (reg_size == 4) srcdst = simd_get_quad_reg_index(srcdst); if (type & SLJIT_SIMD_STORE) - ins = VD(srcdst) | VN(freg) | VM(freg); + ins = VD(srcdst) | VN(vreg) | VM(vreg); else - ins = VD(freg) | VN(srcdst) | VM(srcdst); + ins = VD(vreg) | VN(srcdst) | VM(srcdst); if (reg_size == 4) ins |= (sljit_ins)1 << 6; @@ -3952,7 +4015,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (elem_size > 3) elem_size = 3; - ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD(freg) + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD(vreg) | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); SLJIT_ASSERT(reg_size >= alignment); @@ -4060,7 +4123,7 @@ static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4068,7 +4131,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins, imm; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4082,24 +4145,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (src == SLJIT_IMM && srcw == 0) - return push_inst(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD(freg)); + return push_inst(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD(vreg)); if (SLJIT_UNLIKELY(elem_size == 3)) { SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); - src = freg; - } else if (freg != src) - FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, vreg, src, srcw)); + src = vreg; + } else if (vreg != src) + FAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src))); - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); - if (freg != src) - return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); + if (vreg != src) + return push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src)); return SLJIT_SUCCESS; } @@ -4111,7 +4174,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 5; - return push_inst(compiler, VLD1_r | ins | VD(freg) | RN(src) | 0xf); + return push_inst(compiler, VLD1_r | ins | VD(vreg) | RN(src) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { @@ -4121,7 +4184,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst(compiler, VDUP_s | ins | VD(freg) | (sljit_ins)freg_map[src]); + return push_inst(compiler, VDUP_s | ins | VD(vreg) | (sljit_ins)freg_map[src]); } if (src == SLJIT_IMM) { @@ -4134,7 +4197,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) imm |= (sljit_ins)1 << 6; - return push_inst(compiler, VMOV_i | imm | VD(freg)); + return push_inst(compiler, VMOV_i | imm | VD(vreg)); } FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); @@ -4156,11 +4219,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 21; - return push_inst(compiler, VDUP | ins | VN(freg) | RD(src)); + return push_inst(compiler, VDUP | ins | VN(vreg) | RD(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4168,7 +4231,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -4182,7 +4245,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); @@ -4190,62 +4253,62 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { if (lane_index == 1) - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); - if (srcdst != freg) - FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(srcdst) | VM(srcdst))); + if (srcdst != vreg) + FAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(srcdst) | VM(srcdst))); - freg += SLJIT_QUAD_OTHER_HALF(freg); - return push_inst(compiler, VMOV_i | VD(freg)); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + return push_inst(compiler, VMOV_i | VD(vreg)); } - if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { - FAIL_IF(push_inst(compiler, VORR | ins | VD(TMP_FREG2) | VN(freg) | VM(freg))); + if (srcdst == vreg || (elem_size == 3 && srcdst == (vreg + SLJIT_QUAD_OTHER_HALF(vreg)))) { + FAIL_IF(push_inst(compiler, VORR | ins | VD(TMP_FREG2) | VN(vreg) | VM(vreg))); srcdst = TMP_FREG2; srcdstw = 0; } } - FAIL_IF(push_inst(compiler, VMOV_i | ins | VD(freg))); + FAIL_IF(push_inst(compiler, VMOV_i | ins | VD(vreg))); } if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { lane_index -= (0x8 >> elem_size); - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); } if (srcdst & SLJIT_MEM) { if (elem_size == 3) - return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, vreg, srcdst, srcdstw); FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); lane_index = lane_index << elem_size; ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); - return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD(freg) | RN(srcdst) | 0xf); + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD(vreg) | RN(srcdst) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3) { if (type & SLJIT_SIMD_STORE) - return push_inst(compiler, VORR | VD(srcdst) | VN(freg) | VM(freg)); - return push_inst(compiler, VMOV_F32 | SLJIT_32 | VD(freg) | VM(srcdst)); + return push_inst(compiler, VORR | VD(srcdst) | VN(vreg) | VM(vreg)); + return push_inst(compiler, VMOV_F32 | SLJIT_32 | VD(vreg) | VM(srcdst)); } if (type & SLJIT_SIMD_STORE) { - if (freg_ebit_map[freg] == 0) { + if (freg_ebit_map[vreg] == 0) { if (lane_index == 1) - freg = SLJIT_F64_SECOND(freg); + vreg = SLJIT_F64_SECOND(vreg); - return push_inst(compiler, VMOV_F32 | VD(srcdst) | VM(freg)); + return push_inst(compiler, VMOV_F32 | VD(srcdst) | VM(vreg)); } - FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1))); + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN(vreg) | RD(TMP_REG1))); return push_inst(compiler, VMOV | VN(srcdst) | RD(TMP_REG1)); } FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(srcdst) | RD(TMP_REG1))); - return push_inst(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1)); + return push_inst(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN(vreg) | RD(TMP_REG1)); } if (srcdst == SLJIT_IMM) { @@ -4273,11 +4336,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins |= (1 << 23); } - return push_inst(compiler, VMOV_s | ins | VN(freg) | RD(srcdst)); + return push_inst(compiler, VMOV_s | ins | VN(vreg) | RD(srcdst)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4285,7 +4348,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4297,7 +4360,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c return SLJIT_SUCCESS; if (reg_size == 4) { - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); src = simd_get_quad_reg_index(src); if (src_lane_index >= (0x8 >> elem_size)) { @@ -4307,13 +4370,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } if (elem_size == 3) { - if (freg != src) - FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); + if (vreg != src) + FAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src))); - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); - if (freg != src) - return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); + if (vreg != src) + return push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src)); return SLJIT_SUCCESS; } @@ -4322,11 +4385,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst(compiler, VDUP_s | ins | VD(freg) | VM(src)); + return push_inst(compiler, VDUP_s | ins | VD(vreg) | VM(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4335,7 +4398,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_s32 dst_reg; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4349,20 +4412,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (src & SLJIT_MEM) { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); if (reg_size == 4 && elem2_size - elem_size == 1) - FAIL_IF(push_inst(compiler, VLD1 | (0x7 << 8) | VD(freg) | RN(src) | 0xf)); + FAIL_IF(push_inst(compiler, VLD1 | (0x7 << 8) | VD(vreg) | RN(src) | 0xf)); else - FAIL_IF(push_inst(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD(freg) | RN(src) | 0xf)); - src = freg; + FAIL_IF(push_inst(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD(vreg) | RN(src) | 0xf)); + src = vreg; } else if (reg_size == 4) src = simd_get_quad_reg_index(src); if (!(type & SLJIT_SIMD_FLOAT)) { - dst_reg = (reg_size == 4) ? freg : TMP_FREG2; + dst_reg = (reg_size == 4) ? vreg : TMP_FREG2; do { FAIL_IF(push_inst(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 24)) @@ -4371,27 +4434,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } while (++elem_size < elem2_size); if (dst_reg == TMP_FREG2) - return push_inst(compiler, VORR | VD(freg) | VN(TMP_FREG2) | VM(TMP_FREG2)); + return push_inst(compiler, VORR | VD(vreg) | VN(TMP_FREG2) | VM(TMP_FREG2)); return SLJIT_SUCCESS; } /* No SIMD variant, must use VFP instead. */ SLJIT_ASSERT(reg_size == 4); - if (freg == src) { - freg += SLJIT_QUAD_OTHER_HALF(freg); - FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20)); - freg += SLJIT_QUAD_OTHER_HALF(freg); - return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src)); + if (vreg == src) { + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src) | 0x20)); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + return push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src)); } - FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src))); - freg += SLJIT_QUAD_OTHER_HALF(freg); - return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20); + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src))); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + return push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src) | 0x20); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4400,7 +4463,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4433,12 +4496,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } if (reg_size == 4) { - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); ins |= (sljit_ins)1 << 6; } SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); - FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG2) | VM(freg))); + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG2) | VM(vreg))); if (reg_size == 4 && elem_size > 0) FAIL_IF(push_inst(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD(TMP_FREG2) | VM(TMP_FREG2))); @@ -4468,14 +4531,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_ins ins = 0; + sljit_s32 alignment; + sljit_ins ins = 0, load_ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + ADJUST_LOCAL_OFFSET(src2, src2w); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4483,6 +4548,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) return SLJIT_ERR_UNSUPPORTED; + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = VAND; @@ -4493,19 +4561,51 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = VEOR; break; + case SLJIT_SIMD_OP2_SHUFFLE: + ins = VTBL; + break; } - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; + if (src2 & SLJIT_MEM) { + if (elem_size > 3) + elem_size = 3; + + load_ins = VLD1 | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); + alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + + SLJIT_ASSERT(reg_size >= alignment); + + if (alignment == 3) + load_ins |= 0x10; + else if (alignment >= 4) + load_ins |= 0x20; + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); + FAIL_IF(push_inst(compiler, load_ins | VD(TMP_FREG2) | RN(src2) | ((sljit_ins)elem_size) << 6 | 0xf)); + src2 = TMP_FREG2; + } if (reg_size == 4) { - dst_freg = simd_get_quad_reg_index(dst_freg); - src1_freg = simd_get_quad_reg_index(src1_freg); - src2_freg = simd_get_quad_reg_index(src2_freg); + dst_vreg = simd_get_quad_reg_index(dst_vreg); + src1_vreg = simd_get_quad_reg_index(src1_vreg); + src2 = simd_get_quad_reg_index(src2); + + if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) { + ins |= (sljit_ins)1 << 8; + + FAIL_IF(push_inst(compiler, ins | VD(dst_vreg != src1_vreg ? dst_vreg : TMP_FREG2) | VN(src1_vreg) | VM(src2))); + src2 += SLJIT_QUAD_OTHER_HALF(src2); + FAIL_IF(push_inst(compiler, ins | VD(dst_vreg + SLJIT_QUAD_OTHER_HALF(dst_vreg)) | VN(src1_vreg) | VM(src2))); + + if (dst_vreg == src1_vreg) + return push_inst(compiler, VORR | VD(dst_vreg) | VN(TMP_FREG2) | VM(TMP_FREG2)); + return SLJIT_SUCCESS; + } + ins |= (sljit_ins)1 << 6; } - return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); + return push_inst(compiler, ins | VD(dst_vreg) | VN(src1_vreg) | VM(src2)); } #undef FPU_LOAD @@ -4519,7 +4619,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + case SLJIT_MOV_S16: + case SLJIT_MOV_S32: + return SLJIT_ERR_UNSUPPORTED; + case SLJIT_MOV_U8: ins = LDREXB; break; @@ -4531,6 +4639,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler break; } + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + return push_inst(compiler, ins | RN(mem_reg) | RD(dst_reg)); } @@ -4547,7 +4658,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + case SLJIT_MOV_S16: + case SLJIT_MOV_S32: + return SLJIT_ERR_UNSUPPORTED; + case SLJIT_MOV_U8: ins = STREXB; break; @@ -4559,6 +4678,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, ins | RN(mem_reg) | RD(TMP_REG1) | RM(src_reg))); if (op & SLJIT_SET_ATOMIC_STORED) return push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(TMP_REG1)); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c index 5331ebdf42962..d80c9e546ee79 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c @@ -91,6 +91,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define CLZ 0xdac01000 #define CSEL 0x9a800000 #define CSINC 0x9a800400 +#define DMB_SY 0xd5033fbf #define DUP_e 0x0e000400 #define DUP_g 0x0e000c00 #define EOR 0xca000000 @@ -171,6 +172,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SUBI 0xd1000000 #define SUBS 0xeb000000 #define TBZ 0x36000000 +#define TBL_v 0x0e000000 #define UBFM 0xd3400000 #define UCVTF 0x9e630000 #define UDIV 0x9ac00800 @@ -208,7 +210,11 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i { sljit_sw diff; sljit_uw target_addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; + sljit_uw orig_addr = jump->addr; + SLJIT_UNUSED_ARG(executable_offset); + jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -216,10 +222,13 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; + target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); + + if (jump->u.label->size > orig_addr) + jump_addr = (sljit_uw)(code + orig_addr); } - diff = (sljit_sw)target_addr - (sljit_sw)code_ptr - executable_offset; + diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); @@ -271,16 +280,21 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT(jump->flags < ((sljit_uw)4 << JUMP_SIZE_SHIFT)); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else + else { addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + if (jump->u.label->size > jump->addr) + jump_addr = (sljit_uw)(code + jump->addr); + } + + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if (diff <= 0xfffff && diff >= -0x100000) { jump->flags |= PATCH_B; @@ -422,6 +436,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if ((jump->flags & IS_COND) && (diff + 1) <= (0xfffff / SSIZE_OF(ins)) && (diff + 1) >= (-0x100000 / SSIZE_OF(ins))) total_size = 0; @@ -439,6 +457,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if (diff <= (0xfffff / SSIZE_OF(ins)) && diff >= (-0x100000 / SSIZE_OF(ins))) total_size = 0; @@ -516,7 +538,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - jump->addr = (sljit_uw)code_ptr; code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); SLJIT_ASSERT((jump->flags & PATCH_COND) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { @@ -593,6 +614,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: return 1; default: @@ -1208,16 +1230,23 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 prev, fprev, saved_regs_size, i, tmp; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_ins offs; CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 2); saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1383,15 +1412,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 saved_regs_size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 2); saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1537,7 +1572,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile op = GET_OPCODE(op); switch (op) { case SLJIT_BREAKPOINT: - return push_inst(compiler, BRK); + return push_inst(compiler, BRK | (0xf000 << 5)); case SLJIT_NOP: return push_inst(compiler, NOP); case SLJIT_LMUL_UW: @@ -1554,6 +1589,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile case SLJIT_DIV_UW: case SLJIT_DIV_SW: return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); + case SLJIT_MEMORY_BARRIER: + return push_inst(compiler, DMB_SY); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2775,7 +2812,7 @@ static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, slj } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -2783,7 +2820,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -2798,9 +2835,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (!(srcdst & SLJIT_MEM)) { if (type & SLJIT_SIMD_STORE) - ins = VD(srcdst) | VN(freg) | VM(freg); + ins = VD(srcdst) | VN(vreg) | VM(vreg); else - ins = VD(freg) | VN(srcdst) | VM(srcdst); + ins = VD(vreg) | VN(srcdst) | VM(srcdst); if (reg_size == 4) ins |= (1 << 30); @@ -2818,7 +2855,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (reg_size == 4) ins |= (1 << 30); - return push_inst(compiler, ins | ((sljit_ins)elem_size << 10) | RN(srcdst) | VT(freg)); + return push_inst(compiler, ins | ((sljit_ins)elem_size << 10) | RN(srcdst) | VT(vreg)); } static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) @@ -2923,7 +2960,7 @@ static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -2931,7 +2968,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins, imm; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -2952,7 +2989,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 30; - return push_inst(compiler, LD1R | ins | RN(src) | VT(freg)); + return push_inst(compiler, LD1R | ins | RN(src) | VT(vreg)); } ins = (sljit_ins)1 << (16 + elem_size); @@ -2962,9 +2999,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) - return push_inst(compiler, MOVI | (ins & ((sljit_ins)1 << 30)) | VD(freg)); + return push_inst(compiler, MOVI | (ins & ((sljit_ins)1 << 30)) | VD(vreg)); - return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); + return push_inst(compiler, DUP_e | ins | VD(vreg) | VN(src)); } if (src == SLJIT_IMM) { @@ -2976,18 +3013,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (imm != ~(sljit_ins)0) { imm |= ins & ((sljit_ins)1 << 30); - return push_inst(compiler, MOVI | imm | VD(freg)); + return push_inst(compiler, MOVI | imm | VD(vreg)); } FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); src = TMP_REG2; } - return push_inst(compiler, DUP_g | ins | VD(freg) | RN(src)); + return push_inst(compiler, DUP_g | ins | VD(vreg) | RN(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -2995,7 +3032,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3011,13 +3048,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 30); - if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { - FAIL_IF(push_inst(compiler, ORR_v | ins | VD(TMP_FREG1) | VN(freg) | VM(freg))); + if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { + FAIL_IF(push_inst(compiler, ORR_v | ins | VD(TMP_FREG1) | VN(vreg) | VM(vreg))); srcdst = TMP_FREG1; srcdstw = 0; } - FAIL_IF(push_inst(compiler, MOVI | ins | VD(freg))); + FAIL_IF(push_inst(compiler, MOVI | ins | VD(vreg))); } if (srcdst & SLJIT_MEM) { @@ -3033,14 +3070,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile lane_index = lane_index << elem_size; ins |= (sljit_ins)(((lane_index & 0x8) << 27) | ((lane_index & 0x7) << 10)); - return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? ST1_s : LD1_s) | ins | RN(srcdst) | VT(freg)); + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? ST1_s : LD1_s) | ins | RN(srcdst) | VT(vreg)); } if (type & SLJIT_SIMD_FLOAT) { if (type & SLJIT_SIMD_STORE) - ins = INS_e | ((sljit_ins)1 << (16 + elem_size)) | ((sljit_ins)lane_index << (11 + elem_size)) | VD(srcdst) | VN(freg); + ins = INS_e | ((sljit_ins)1 << (16 + elem_size)) | ((sljit_ins)lane_index << (11 + elem_size)) | VD(srcdst) | VN(vreg); else - ins = INS_e | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)) | VD(freg) | VN(srcdst); + ins = INS_e | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)) | VD(vreg) | VN(srcdst); return push_inst(compiler, ins); } @@ -3054,7 +3091,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } if (type & SLJIT_SIMD_STORE) { - ins = RD(srcdst) | VN(freg); + ins = RD(srcdst) | VN(vreg); if ((type & SLJIT_SIMD_LANE_SIGNED) && (elem_size < 2 || (elem_size == 2 && !(type & SLJIT_32)))) { ins |= SMOV; @@ -3064,7 +3101,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } else ins |= UMOV; } else - ins = INS | VD(freg) | RN(srcdst); + ins = INS | VD(vreg) | RN(srcdst); if (elem_size == 3) ins |= (sljit_ins)1 << 30; @@ -3073,7 +3110,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3081,7 +3118,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3097,11 +3134,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 4) ins |= (sljit_ins)1 << 30; - return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); + return push_inst(compiler, DUP_e | ins | VD(vreg) | VN(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3109,7 +3146,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3126,28 +3163,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); if (reg_size == 4 && elem2_size - elem_size == 1) - FAIL_IF(push_inst(compiler, LD1 | ((sljit_ins)elem_size << 10) | RN(src) | VT(freg))); + FAIL_IF(push_inst(compiler, LD1 | ((sljit_ins)elem_size << 10) | RN(src) | VT(vreg))); else - FAIL_IF(push_inst(compiler, LD1_s | ((sljit_ins)0x2000 << (reg_size - elem2_size + elem_size)) | RN(src) | VT(freg))); - src = freg; + FAIL_IF(push_inst(compiler, LD1_s | ((sljit_ins)0x2000 << (reg_size - elem2_size + elem_size)) | RN(src) | VT(vreg))); + src = vreg; } if (type & SLJIT_SIMD_FLOAT) { SLJIT_ASSERT(reg_size == 4); - return push_inst(compiler, FCVTL | (1 << 22) | VD(freg) | VN(src)); + return push_inst(compiler, FCVTL | (1 << 22) | VD(vreg) | VN(src)); } do { FAIL_IF(push_inst(compiler, ((type & SLJIT_SIMD_EXTEND_SIGNED) ? SSHLL : USHLL) - | ((sljit_ins)1 << (19 + elem_size)) | VD(freg) | VN(src))); - src = freg; + | ((sljit_ins)1 << (19 + elem_size)) | VD(vreg) | VN(src))); + src = vreg; } while (++elem_size < elem2_size); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3156,7 +3193,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -3191,7 +3228,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c if (reg_size == 4) ins |= (1 << 30); - FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG1) | VN(freg))); + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG1) | VN(vreg))); if (reg_size == 4 && elem_size > 0) FAIL_IF(push_inst(compiler, XTN | ((sljit_ins)(elem_size - 1) << 22) | VD(TMP_FREG1) | VN(TMP_FREG1))); @@ -3224,14 +3261,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + ADJUST_LOCAL_OFFSET(src2, src2w); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3239,6 +3277,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) return SLJIT_ERR_UNSUPPORTED; + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = AND_v; @@ -3249,15 +3290,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = EOR_v; break; + case SLJIT_SIMD_OP2_SHUFFLE: + ins = TBL_v; + break; } - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; + if (src2 & SLJIT_MEM) { + if (elem_size > 3) + elem_size = 3; + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); + push_inst(compiler, LD1 | (reg_size == 4 ? (1 << 30) : 0) | ((sljit_ins)elem_size << 10) | RN(src2) | VT(TMP_FREG1)); + src2 = TMP_FREG1; + } if (reg_size == 4) ins |= (sljit_ins)1 << 30; - return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); + return push_inst(compiler, ins | VD(dst_vreg) | VN(src1_vreg) | VM(src2)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, @@ -3269,39 +3319,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); -#ifdef __ARM_FEATURE_ATOMICS - switch (GET_OPCODE(op)) { - case SLJIT_MOV32: - case SLJIT_MOV_U32: - ins = LDR ^ (1 << 30); - break; - case SLJIT_MOV_U16: - ins = LDRH; - break; - case SLJIT_MOV_U8: - ins = LDRB; - break; - default: - ins = LDR; - break; - } -#else /* !__ARM_FEATURE_ATOMICS */ +#ifndef __ARM_FEATURE_ATOMICS + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; +#endif /* ARM_FEATURE_ATOMICS */ + switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + case SLJIT_MOV_S16: + case SLJIT_MOV_S32: + return SLJIT_ERR_UNSUPPORTED; + case SLJIT_MOV32: case SLJIT_MOV_U32: - ins = LDXR ^ (1 << 30); +#ifdef __ARM_FEATURE_ATOMICS + if (!(op & SLJIT_ATOMIC_USE_LS)) + ins = LDR ^ (1 << 30); + else +#endif /* ARM_FEATURE_ATOMICS */ + ins = LDXR ^ (1 << 30); break; case SLJIT_MOV_U8: - ins = LDXRB; +#ifdef __ARM_FEATURE_ATOMICS + if (!(op & SLJIT_ATOMIC_USE_LS)) + ins = LDRB; + else +#endif /* ARM_FEATURE_ATOMICS */ + ins = LDXRB; break; case SLJIT_MOV_U16: - ins = LDXRH; +#ifdef __ARM_FEATURE_ATOMICS + if (!(op & SLJIT_ATOMIC_USE_LS)) + ins = LDRH; + else +#endif /* ARM_FEATURE_ATOMICS */ + ins = LDXRH; break; default: - ins = LDXR; +#ifdef __ARM_FEATURE_ATOMICS + if (!(op & SLJIT_ATOMIC_USE_LS)) + ins = LDR; + else +#endif /* ARM_FEATURE_ATOMICS */ + ins = LDXR; break; } -#endif /* ARM_FEATURE_ATOMICS */ + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + return push_inst(compiler, ins | RN(mem_reg) | RT(dst_reg)); } @@ -3311,55 +3377,65 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler sljit_s32 temp_reg) { sljit_ins ins; - sljit_s32 tmp = temp_reg; sljit_ins cmp = 0; - sljit_ins inv_bits = W_OP; CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); #ifdef __ARM_FEATURE_ATOMICS - if (op & SLJIT_SET_ATOMIC_STORED) - cmp = (SUBS ^ W_OP) | RD(TMP_ZERO); + if (!(op & SLJIT_ATOMIC_USE_LS)) { + if (op & SLJIT_SET_ATOMIC_STORED) + cmp = (SUBS ^ W_OP) | RD(TMP_ZERO); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + case SLJIT_MOV_S16: + case SLJIT_MOV_S32: + return SLJIT_ERR_UNSUPPORTED; + + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = CAS ^ (1 << 30); + break; + case SLJIT_MOV_U16: + ins = CASH; + break; + case SLJIT_MOV_U8: + ins = CASB; + break; + default: + ins = CAS; + if (cmp) + cmp ^= W_OP; + break; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; - switch (GET_OPCODE(op)) { - case SLJIT_MOV32: - case SLJIT_MOV_U32: - ins = CAS ^ (1 << 30); - break; - case SLJIT_MOV_U16: - ins = CASH; - break; - case SLJIT_MOV_U8: - ins = CASB; - break; - default: - ins = CAS; - inv_bits = 0; if (cmp) - cmp ^= W_OP; - break; - } + FAIL_IF(push_inst(compiler, ((MOV ^ W_OP) ^ (cmp & W_OP)) | RM(temp_reg) | RD(TMP_REG2))); - if (cmp) { - FAIL_IF(push_inst(compiler, (MOV ^ inv_bits) | RM(temp_reg) | RD(TMP_REG1))); - tmp = TMP_REG1; - } - FAIL_IF(push_inst(compiler, ins | RM(tmp) | RN(mem_reg) | RD(src_reg))); - if (!cmp) - return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, ins | RM(temp_reg) | RN(mem_reg) | RD(src_reg))); + if (!cmp) + return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, cmp | RM(tmp) | RN(temp_reg))); - FAIL_IF(push_inst(compiler, (CSET ^ inv_bits) | RD(tmp))); - return push_inst(compiler, cmp | RM(tmp) | RN(TMP_ZERO)); + return push_inst(compiler, cmp | RM(TMP_REG2) | RN(temp_reg)); + } #else /* !__ARM_FEATURE_ATOMICS */ - SLJIT_UNUSED_ARG(tmp); - SLJIT_UNUSED_ARG(inv_bits); + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; +#endif /* __ARM_FEATURE_ATOMICS */ if (op & SLJIT_SET_ATOMIC_STORED) cmp = (SUBI ^ W_OP) | (1 << 29); switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + case SLJIT_MOV_S16: + case SLJIT_MOV_S32: + return SLJIT_ERR_UNSUPPORTED; + case SLJIT_MOV32: case SLJIT_MOV_U32: ins = STXR ^ (1 << 30); @@ -3375,9 +3451,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } - FAIL_IF(push_inst(compiler, ins | RM(TMP_REG1) | RN(mem_reg) | RT(src_reg))); - return cmp ? push_inst(compiler, cmp | RD(TMP_ZERO) | RN(TMP_REG1)) : SLJIT_SUCCESS; -#endif /* __ARM_FEATURE_ATOMICS */ + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, ins | RM(TMP_REG2) | RN(mem_reg) | RT(src_reg))); + if (!cmp) + return SLJIT_SUCCESS; + return push_inst(compiler, cmp | RD(TMP_ZERO) | RN(TMP_REG2)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c index 799954a85996f..d8058ab6ea4b6 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c @@ -138,6 +138,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define CMPI_W 0xf1b00f00 #define CMP_X 0x4500 #define CMP_W 0xebb00f00 +#define DMB_SY 0xf3bf8f5f #define EORI 0xf0800000 #define EORS 0x4040 #define EOR_W 0xea800000 @@ -253,6 +254,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define VST1_s 0xf9800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 +#define VTBL 0xffb00800 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -264,11 +266,28 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) fr -= SLJIT_F64_SECOND(0); - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) - || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches)) + || (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } +static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type) +{ + sljit_s32 vr_low = vr; + + if (compiler->scratches == -1) + return 0; + + if (SLJIT_SIMD_GET_REG_SIZE(type) == 4) { + vr += (vr & 0x1); + vr_low = vr - 1; + } + + return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches)) + || (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0) + || (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)); +} + #endif /* SLJIT_ARGUMENT_CHECKS */ static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst) @@ -320,7 +339,12 @@ static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm) static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset) { sljit_sw diff; + sljit_uw target_addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; + sljit_uw orig_addr = jump->addr; + SLJIT_UNUSED_ARG(executable_offset); + jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -328,12 +352,17 @@ static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u /* Branch to ARM code is not optimized yet. */ if (!(jump->u.target & 0x1)) goto exit; - diff = (sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset; + target_addr = jump->u.target; } else { SLJIT_ASSERT(jump->u.label != NULL); - diff = (sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2); + target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); + + if (jump->u.label->size > orig_addr) + jump_addr = (sljit_uw)(code + orig_addr); } + diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr + 4, executable_offset); + if (jump->flags & IS_COND) { SLJIT_ASSERT(!(jump->flags & IS_BL)); /* Size of the prefix IT instruction. */ @@ -380,16 +409,21 @@ static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset) { sljit_uw addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else + else { addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); + if (jump->u.label->size > jump->addr) + jump_addr = (sljit_uw)(code + jump->addr); + } + /* The pc+4 offset is represented by the 2 * SSIZE_OF(sljit_u16) below. */ - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); /* Note: ADR with imm8 does not set the last bit (Thumb2 flag). */ @@ -517,6 +551,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if (jump->flags & IS_COND) { diff++; @@ -540,6 +578,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if (diff <= (0xffd / SSIZE_OF(u16)) && diff >= (-0xfff / SSIZE_OF(u16))) total_size = 1; @@ -612,7 +654,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { half_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - jump->addr = (sljit_uw)code_ptr; code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); SLJIT_ASSERT((sljit_uw)code_ptr - jump->addr < ((jump->flags >> JUMP_SIZE_SHIFT) + ((jump->flags & 0xf0) <= PATCH_TYPE2)) * sizeof(sljit_u16)); @@ -694,6 +735,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: return 1; default: @@ -1367,9 +1409,11 @@ static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 size, i, tmp, word_arg_count; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_uw offset; @@ -1383,8 +1427,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; tmp = SLJIT_S0 - saveds; for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) @@ -1577,15 +1626,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); /* Doubles are saved, so alignment is unaffected. */ @@ -1904,6 +1959,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile } return SLJIT_SUCCESS; #endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */ + case SLJIT_MEMORY_BARRIER: + return push_inst32(compiler, DMB_SY); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2204,7 +2261,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) return freg_map[reg]; - if (type != SLJIT_SIMD_REG_128) + if (type == SLJIT_SIMD_REG_128) return freg_map[reg] & ~0x1; return -1; @@ -3582,7 +3639,7 @@ static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) #define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3591,7 +3648,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3605,16 +3662,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (!(srcdst & SLJIT_MEM)) { if (reg_size == 4) srcdst = simd_get_quad_reg_index(srcdst); if (type & SLJIT_SIMD_STORE) - ins = VD4(srcdst) | VN4(freg) | VM4(freg); + ins = VD4(srcdst) | VN4(vreg) | VM4(vreg); else - ins = VD4(freg) | VN4(srcdst) | VM4(srcdst); + ins = VD4(vreg) | VN4(srcdst) | VM4(srcdst); if (reg_size == 4) ins |= (sljit_ins)1 << 6; @@ -3627,7 +3684,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (elem_size > 3) elem_size = 3; - ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD4(freg) + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD4(vreg) | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); SLJIT_ASSERT(reg_size >= alignment); @@ -3735,7 +3792,7 @@ static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3743,7 +3800,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins, imm; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3757,24 +3814,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (src == SLJIT_IMM && srcw == 0) - return push_inst32(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD4(freg)); + return push_inst32(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD4(vreg)); if (SLJIT_UNLIKELY(elem_size == 3)) { SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); - src = freg; - } else if (freg != src) - FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, vreg, src, srcw)); + src = vreg; + } else if (vreg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src))); - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); - if (freg != src) - return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); + if (vreg != src) + return push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src)); return SLJIT_SUCCESS; } @@ -3786,7 +3843,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= 1 << 5; - return push_inst32(compiler, VLD1_r | ins | VD4(freg) | RN4(src) | 0xf); + return push_inst32(compiler, VLD1_r | ins | VD4(vreg) | RN4(src) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { @@ -3796,7 +3853,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst32(compiler, VDUP_s | ins | VD4(freg) | (sljit_ins)freg_map[src]); + return push_inst32(compiler, VDUP_s | ins | VD4(vreg) | (sljit_ins)freg_map[src]); } if (src == SLJIT_IMM) { @@ -3809,7 +3866,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) imm |= (sljit_ins)1 << 6; - return push_inst32(compiler, VMOV_i | imm | VD4(freg)); + return push_inst32(compiler, VMOV_i | imm | VD4(vreg)); } FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); @@ -3831,11 +3888,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 21; - return push_inst32(compiler, VDUP | ins | VN4(freg) | RT4(src)); + return push_inst32(compiler, VDUP | ins | VN4(vreg) | RT4(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3843,7 +3900,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3857,7 +3914,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); @@ -3865,62 +3922,62 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { if (lane_index == 1) - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); - if (srcdst != freg) - FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(srcdst) | VM4(srcdst))); + if (srcdst != vreg) + FAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(srcdst) | VM4(srcdst))); - freg += SLJIT_QUAD_OTHER_HALF(freg); - return push_inst32(compiler, VMOV_i | VD4(freg)); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + return push_inst32(compiler, VMOV_i | VD4(vreg)); } - if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { - FAIL_IF(push_inst32(compiler, VORR | ins | VD4(TMP_FREG2) | VN4(freg) | VM4(freg))); + if (srcdst == vreg || (elem_size == 3 && srcdst == (vreg + SLJIT_QUAD_OTHER_HALF(vreg)))) { + FAIL_IF(push_inst32(compiler, VORR | ins | VD4(TMP_FREG2) | VN4(vreg) | VM4(vreg))); srcdst = TMP_FREG2; srcdstw = 0; } } - FAIL_IF(push_inst32(compiler, VMOV_i | ins | VD4(freg))); + FAIL_IF(push_inst32(compiler, VMOV_i | ins | VD4(vreg))); } if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { lane_index -= (0x8 >> elem_size); - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); } if (srcdst & SLJIT_MEM) { if (elem_size == 3) - return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, vreg, srcdst, srcdstw); FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); lane_index = lane_index << elem_size; ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); - return push_inst32(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD4(freg) | RN4(srcdst) | 0xf); + return push_inst32(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD4(vreg) | RN4(srcdst) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3) { if (type & SLJIT_SIMD_STORE) - return push_inst32(compiler, VORR | VD4(srcdst) | VN4(freg) | VM4(freg)); - return push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(freg) | VM4(srcdst)); + return push_inst32(compiler, VORR | VD4(srcdst) | VN4(vreg) | VM4(vreg)); + return push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(vreg) | VM4(srcdst)); } if (type & SLJIT_SIMD_STORE) { - if (freg_ebit_map[freg] == 0) { + if (freg_ebit_map[vreg] == 0) { if (lane_index == 1) - freg = SLJIT_F64_SECOND(freg); + vreg = SLJIT_F64_SECOND(vreg); - return push_inst32(compiler, VMOV_F32 | VD4(srcdst) | VM4(freg)); + return push_inst32(compiler, VMOV_F32 | VD4(srcdst) | VM4(vreg)); } - FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1))); + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN4(vreg) | RT4(TMP_REG1))); return push_inst32(compiler, VMOV | VN4(srcdst) | RT4(TMP_REG1)); } FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(srcdst) | RT4(TMP_REG1))); - return push_inst32(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1)); + return push_inst32(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN4(vreg) | RT4(TMP_REG1)); } if (srcdst == SLJIT_IMM) { @@ -3948,11 +4005,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins |= (1 << 23); } - return push_inst32(compiler, VMOV_s | ins | VN4(freg) | RT4(srcdst)); + return push_inst32(compiler, VMOV_s | ins | VN4(vreg) | RT4(srcdst)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3960,7 +4017,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3972,7 +4029,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c return SLJIT_SUCCESS; if (reg_size == 4) { - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); src = simd_get_quad_reg_index(src); if (src_lane_index >= (0x8 >> elem_size)) { @@ -3982,13 +4039,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } if (elem_size == 3) { - if (freg != src) - FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); + if (vreg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src))); - freg += SLJIT_QUAD_OTHER_HALF(freg); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); - if (freg != src) - return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); + if (vreg != src) + return push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src)); return SLJIT_SUCCESS; } @@ -3997,11 +4054,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst32(compiler, VDUP_s | ins | VD4(freg) | VM4(src)); + return push_inst32(compiler, VDUP_s | ins | VD4(vreg) | VM4(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4010,7 +4067,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_s32 dst_reg; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4024,20 +4081,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (reg_size == 4) - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); if (src & SLJIT_MEM) { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); if (reg_size == 4 && elem2_size - elem_size == 1) - FAIL_IF(push_inst32(compiler, VLD1 | (0x7 << 8) | VD4(freg) | RN4(src) | 0xf)); + FAIL_IF(push_inst32(compiler, VLD1 | (0x7 << 8) | VD4(vreg) | RN4(src) | 0xf)); else - FAIL_IF(push_inst32(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD4(freg) | RN4(src) | 0xf)); - src = freg; + FAIL_IF(push_inst32(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD4(vreg) | RN4(src) | 0xf)); + src = vreg; } else if (reg_size == 4) src = simd_get_quad_reg_index(src); if (!(type & SLJIT_SIMD_FLOAT)) { - dst_reg = (reg_size == 4) ? freg : TMP_FREG2; + dst_reg = (reg_size == 4) ? vreg : TMP_FREG2; do { FAIL_IF(push_inst32(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 28)) @@ -4046,27 +4103,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } while (++elem_size < elem2_size); if (dst_reg == TMP_FREG2) - return push_inst32(compiler, VORR | VD4(freg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); + return push_inst32(compiler, VORR | VD4(vreg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); return SLJIT_SUCCESS; } /* No SIMD variant, must use VFP instead. */ SLJIT_ASSERT(reg_size == 4); - if (freg == src) { - freg += SLJIT_QUAD_OTHER_HALF(freg); - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20)); - freg += SLJIT_QUAD_OTHER_HALF(freg); - return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src)); + if (vreg == src) { + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src) | 0x20)); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src)); } - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src))); - freg += SLJIT_QUAD_OTHER_HALF(freg); - return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src))); + vreg += SLJIT_QUAD_OTHER_HALF(vreg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src) | 0x20); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4075,7 +4132,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4108,12 +4165,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } if (reg_size == 4) { - freg = simd_get_quad_reg_index(freg); + vreg = simd_get_quad_reg_index(vreg); ins |= (sljit_ins)1 << 6; } SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); - FAIL_IF(push_inst32(compiler, ins | VD4(TMP_FREG2) | VM4(freg))); + FAIL_IF(push_inst32(compiler, ins | VD4(TMP_FREG2) | VM4(vreg))); if (reg_size == 4 && elem_size > 0) FAIL_IF(push_inst32(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); @@ -4143,14 +4200,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_ins ins = 0; + sljit_s32 alignment; + sljit_ins ins = 0, load_ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + ADJUST_LOCAL_OFFSET(src2, src2w); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4158,6 +4217,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) return SLJIT_ERR_UNSUPPORTED; + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = VAND; @@ -4168,19 +4230,51 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = VEOR; break; + case SLJIT_SIMD_OP2_SHUFFLE: + ins = VTBL; + break; } - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; + if (src2 & SLJIT_MEM) { + if (elem_size > 3) + elem_size = 3; + + load_ins = VLD1 | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); + alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + + SLJIT_ASSERT(reg_size >= alignment); + + if (alignment == 3) + load_ins |= 0x10; + else if (alignment >= 4) + load_ins |= 0x20; + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); + FAIL_IF(push_inst32(compiler, load_ins | VD4(TMP_FREG2) | RN4(src2) | ((sljit_ins)elem_size) << 6 | 0xf)); + src2 = TMP_FREG2; + } if (reg_size == 4) { - dst_freg = simd_get_quad_reg_index(dst_freg); - src1_freg = simd_get_quad_reg_index(src1_freg); - src2_freg = simd_get_quad_reg_index(src2_freg); + dst_vreg = simd_get_quad_reg_index(dst_vreg); + src1_vreg = simd_get_quad_reg_index(src1_vreg); + src2 = simd_get_quad_reg_index(src2); + + if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) { + ins |= (sljit_ins)1 << 8; + + FAIL_IF(push_inst32(compiler, ins | VD4(dst_vreg != src1_vreg ? dst_vreg : TMP_FREG2) | VN4(src1_vreg) | VM4(src2))); + src2 += SLJIT_QUAD_OTHER_HALF(src2); + FAIL_IF(push_inst32(compiler, ins | VD4(dst_vreg + SLJIT_QUAD_OTHER_HALF(dst_vreg)) | VN4(src1_vreg) | VM4(src2))); + + if (dst_vreg == src1_vreg) + return push_inst32(compiler, VORR | VD4(dst_vreg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); + return SLJIT_SUCCESS; + } + ins |= (sljit_ins)1 << 6; } - return push_inst32(compiler, ins | VD4(dst_freg) | VN4(src1_freg) | VM4(src2_freg)); + return push_inst32(compiler, ins | VD4(dst_vreg) | VN4(src1_vreg) | VM4(src2)); } #undef FPU_LOAD @@ -4194,7 +4288,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + case SLJIT_MOV_S16: + case SLJIT_MOV_S32: + return SLJIT_ERR_UNSUPPORTED; + case SLJIT_MOV_U8: ins = LDREXB; break; @@ -4206,6 +4308,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler break; } + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + return push_inst32(compiler, ins | RN4(mem_reg) | RT4(dst_reg)); } @@ -4222,7 +4327,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + case SLJIT_MOV_S16: + case SLJIT_MOV_S32: + return SLJIT_ERR_UNSUPPORTED; + case SLJIT_MOV_U8: ins = STREXB | RM4(TMP_REG1); break; @@ -4234,6 +4347,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + FAIL_IF(push_inst32(compiler, ins | RN4(mem_reg) | RT4(src_reg))); if (op & SLJIT_SET_ATOMIC_STORED) return push_inst32(compiler, CMPI_W | RN4(TMP_REG1)); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c index 2e1d742aee74a..73868ca186a43 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c @@ -250,6 +250,9 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes #define AMCAS_W OPC_3R(0x70B2) #define AMCAS_D OPC_3R(0x70B3) +/* Memory barrier instructions */ +#define DBAR OPC_3R(0x70e4) + /* Other instructions */ #define BREAK OPC_3R(0x54) #define DBGCALL OPC_3R(0x55) @@ -348,6 +351,7 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes #define VREPLGR2VR OPC_2R(0x1ca7c0) #define VREPLVE OPC_3R(0xe244) #define VREPLVEI OPC_2R(0x1cbde0) +#define VSHUF_B OPC_4R(0xd5) #define XVPERMI OPC_2RI8(0x1dfa) #define I12_MAX (0x7ff) @@ -386,6 +390,8 @@ static sljit_u32 hwcap_feature_list = 0; #define GET_CFG2 0 #define GET_HWCAP 1 +#define LOONGARCH_SUPPORT_AMCAS (LOONGARCH_CFG2_LAMCAS & get_cpu_features(GET_CFG2)) + static SLJIT_INLINE sljit_u32 get_cpu_features(sljit_u32 feature_type) { if (cfg2_feature_list == 0) @@ -405,14 +411,15 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; - sljit_ins *inst; - - inst = (sljit_ins *)jump->addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; + sljit_uw orig_addr = jump->addr; + SLJIT_UNUSED_ARG(executable_offset); + jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -420,20 +427,23 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; + target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); + + if (jump->u.label->size > orig_addr) + jump_addr = (sljit_uw)(code + orig_addr); } - diff = (sljit_sw)target_addr - (sljit_sw)inst - executable_offset; + diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); if (diff >= BRANCH16_MIN && diff <= BRANCH16_MAX) { - inst--; - inst[0] = (inst[0] & 0xfc0003ff) ^ 0x4000000; + code_ptr--; + code_ptr[0] = (code_ptr[0] & 0xfc0003ff) ^ 0x4000000; jump->flags |= PATCH_B; - jump->addr = (sljit_uw)inst; - return inst; + jump->addr = (sljit_uw)code_ptr; + return code_ptr; } diff -= SSIZE_OF(ins); @@ -441,60 +451,65 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i if (diff >= JUMP_MIN && diff <= JUMP_MAX) { if (jump->flags & IS_COND) { - inst[-1] |= (sljit_ins)IMM_I16(2); + code_ptr[-1] |= (sljit_ins)IMM_I16(2); } jump->flags |= PATCH_J; - return inst; + return code_ptr; } if (diff >= S32_MIN && diff <= S32_MAX) { if (jump->flags & IS_COND) - inst[-1] |= (sljit_ins)IMM_I16(3); + code_ptr[-1] |= (sljit_ins)IMM_I16(3); jump->flags |= PATCH_REL32; - inst[1] = inst[0]; - return inst + 1; + code_ptr[1] = code_ptr[0]; + return code_ptr + 1; } if (target_addr <= (sljit_uw)S32_MAX) { if (jump->flags & IS_COND) - inst[-1] |= (sljit_ins)IMM_I16(3); + code_ptr[-1] |= (sljit_ins)IMM_I16(3); jump->flags |= PATCH_ABS32; - inst[1] = inst[0]; - return inst + 1; + code_ptr[1] = code_ptr[0]; + return code_ptr + 1; } if (target_addr <= S52_MAX) { if (jump->flags & IS_COND) - inst[-1] |= (sljit_ins)IMM_I16(4); + code_ptr[-1] |= (sljit_ins)IMM_I16(4); jump->flags |= PATCH_ABS52; - inst[2] = inst[0]; - return inst + 2; + code_ptr[2] = code_ptr[0]; + return code_ptr + 2; } exit: if (jump->flags & IS_COND) - inst[-1] |= (sljit_ins)IMM_I16(5); - inst[3] = inst[0]; - return inst + 3; + code_ptr[-1] |= (sljit_ins)IMM_I16(5); + code_ptr[3] = code_ptr[0]; + return code_ptr + 3; } static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT)); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else + else { addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + if (jump->u.label->size > jump->addr) + jump_addr = (sljit_uw)(code + jump->addr); + } + + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if (diff >= S32_MIN && diff <= S32_MAX) { SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT)); @@ -617,6 +632,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH16_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH16_MIN / SSIZE_OF(ins))) total_size = 0; @@ -635,6 +654,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { /* Real size minus 1. Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins))) total_size = 1; @@ -710,8 +733,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - jump->addr = (sljit_uw)code_ptr; - code_ptr = detect_jump_type(jump, code, executable_offset); + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { word_count += jump->flags >> JUMP_SIZE_SHIFT; @@ -804,9 +826,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_SIMD: return (LOONGARCH_HWCAP_LSX & get_cpu_features(GET_HWCAP)); - case SLJIT_HAS_ATOMIC: - return (LOONGARCH_CFG2_LAMCAS & get_cpu_features(GET_CFG2)); - case SLJIT_HAS_CLZ: case SLJIT_HAS_CTZ: case SLJIT_HAS_REV: @@ -814,6 +833,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_PREFETCH: case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: return 1; default: @@ -889,16 +910,22 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw); SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 i, tmp, offset; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -973,13 +1000,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #undef STACK_MAX_DISTANCE SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; + CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1884,6 +1918,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, ((op & SLJIT_32)? DIV_WU: DIV_DU) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1)); case SLJIT_DIV_SW: return push_inst(compiler, INST(DIV, op) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1)); + case SLJIT_MEMORY_BARRIER: + return push_inst(compiler, DBAR); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2644,10 +2680,8 @@ static sljit_ins get_jump_instruction(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: - case SLJIT_ATOMIC_NOT_STORED: return BNE | RJ(EQUAL_FLAG) | RD(TMP_ZERO); case SLJIT_NOT_EQUAL: - case SLJIT_ATOMIC_STORED: return BEQ | RJ(EQUAL_FLAG) | RD(TMP_ZERO); case SLJIT_LESS: case SLJIT_GREATER: @@ -2655,6 +2689,7 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: case SLJIT_CARRY: + case SLJIT_ATOMIC_STORED: return BEQ | RJ(OTHER_FLAG) | RD(TMP_ZERO); case SLJIT_GREATER_EQUAL: case SLJIT_LESS_EQUAL: @@ -2662,6 +2697,7 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: case SLJIT_NOT_CARRY: + case SLJIT_ATOMIC_NOT_STORED: return BNE | RJ(OTHER_FLAG) | RD(TMP_ZERO); case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: @@ -2933,7 +2969,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co break; case SLJIT_ATOMIC_STORED: case SLJIT_ATOMIC_NOT_STORED: - FAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RJ(EQUAL_FLAG) | IMM_I12(1))); + FAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RJ(OTHER_FLAG) | IMM_I12(1))); src_r = dst_r; invert ^= 0x1; break; @@ -3162,14 +3198,14 @@ static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, slj } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3184,9 +3220,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (!(srcdst & SLJIT_MEM)) { if (type & SLJIT_SIMD_STORE) - ins = FRD(srcdst) | FRJ(freg) | FRK(freg); + ins = FRD(srcdst) | FRJ(vreg) | FRK(vreg); else - ins = FRD(freg) | FRJ(srcdst) | FRK(srcdst); + ins = FRD(vreg) | FRJ(srcdst) | FRK(srcdst); if (reg_size == 5) ins |= VOR_V | (sljit_ins)1 << 26; @@ -3202,15 +3238,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co ins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD; if (FAST_IS_REG(srcdst) && srcdst >= 0 && (srcdstw >= I12_MIN && srcdstw <= I12_MAX)) - return push_inst(compiler, ins | FRD(freg) | RJ((sljit_u8)srcdst) | IMM_I12(srcdstw)); + return push_inst(compiler, ins | FRD(vreg) | RJ((sljit_u8)srcdst) | IMM_I12(srcdstw)); else { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); - return push_inst(compiler, ins | FRD(freg) | RJ(srcdst) | IMM_I12(0)); + return push_inst(compiler, ins | FRD(vreg) | RJ(srcdst) | IMM_I12(0)); } } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3218,7 +3254,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3237,7 +3273,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 5) ins = (sljit_ins)1 << 25; - return push_inst(compiler, VLDREPL | ins | FRD(freg) | RJ(src) | (sljit_ins)1 << (23 - elem_size)); + return push_inst(compiler, VLDREPL | ins | FRD(vreg) | RJ(src) | (sljit_ins)1 << (23 - elem_size)); } if (reg_size == 5) @@ -3245,13 +3281,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) - return push_inst(compiler, VREPLGR2VR | ins | FRD(freg) | RJ(TMP_ZERO) | (sljit_ins)elem_size << 10); + return push_inst(compiler, VREPLGR2VR | ins | FRD(vreg) | RJ(TMP_ZERO) | (sljit_ins)elem_size << 10); - FAIL_IF(push_inst(compiler, VREPLVE | ins | FRD(freg) | FRJ(src) | RK(TMP_ZERO) | (sljit_ins)elem_size << 15)); + FAIL_IF(push_inst(compiler, VREPLVE | ins | FRD(vreg) | FRJ(src) | RK(TMP_ZERO) | (sljit_ins)elem_size << 15)); if (reg_size == 5) { ins = (sljit_ins)(0x44 << 10); - return push_inst(compiler, XVPERMI | ins | FRD(freg) | FRJ(freg)); + return push_inst(compiler, XVPERMI | ins | FRD(vreg) | FRJ(vreg)); } return SLJIT_SUCCESS; @@ -3264,11 +3300,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil src = TMP_REG2; } - return push_inst(compiler, ins | FRD(freg) | RJ(src)); + return push_inst(compiler, ins | FRD(vreg) | RJ(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3276,7 +3312,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3298,13 +3334,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 5) ? ((sljit_ins)1 << 26) : 0; - if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { - FAIL_IF(push_inst(compiler, VOR_V | ins | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); + if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { + FAIL_IF(push_inst(compiler, VOR_V | ins | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); srcdst = TMP_FREG1; srcdstw = 0; } - FAIL_IF(push_inst(compiler, VXOR_V | ins | FRD(freg) | FRJ(freg) | FRK(freg))); + FAIL_IF(push_inst(compiler, VXOR_V | ins | FRD(vreg) | FRJ(vreg) | FRK(vreg))); } if (srcdst & SLJIT_MEM) { @@ -3315,7 +3351,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_STORE) { ins |= (sljit_ins)lane_index << 18 | (sljit_ins)(1 << (23 - elem_size)); - return push_inst(compiler, VSTELM | ins | FRD(freg) | RJ(srcdst)); + return push_inst(compiler, VSTELM | ins | FRD(vreg) | RJ(srcdst)); } else { emit_op_mem(compiler, (elem_size == 3 ? WORD_DATA : (elem_size == 2 ? INT_DATA : (elem_size == 1 ? HALF_DATA : BYTE_DATA))) | LOAD_DATA, TMP_REG1, srcdst | SLJIT_MEM, 0); srcdst = TMP_REG1; @@ -3323,20 +3359,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (reg_size == 5) { if (elem_size < 2) { - FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); + FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); if (lane_index >= (2 << (3 - elem_size))) { - FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1))); + FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1))); FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size))))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(2)); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(2)); } else { - FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(18)); + FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index))); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(18)); } } else ins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26; } - return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index)); + return push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index)); } } @@ -3344,11 +3380,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins = (reg_size == 5) ? (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26 : (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10; if (type & SLJIT_SIMD_STORE) { - FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(freg) | IMM_V(lane_index))); + FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(vreg) | IMM_V(lane_index))); return push_inst(compiler, VINSGR2VR | ins | FRD(srcdst) | RJ(TMP_REG1) | IMM_V(0)); } else { FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(srcdst) | IMM_V(0))); - return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(TMP_REG1) | IMM_V(lane_index)); + return push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(TMP_REG1) | IMM_V(lane_index)); } } @@ -3373,8 +3409,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile else ins |= VPICKVE2GR_U; - FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); - FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1))); + FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); + FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1))); return push_inst(compiler, ins | RD(srcdst) | FRJ(TMP_FREG1) | IMM_V(lane_index % (2 << (3 - elem_size)))); } } else { @@ -3383,33 +3419,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } } - return push_inst(compiler, ins | RD(srcdst) | FRJ(freg) | IMM_V(lane_index)); + return push_inst(compiler, ins | RD(srcdst) | FRJ(vreg) | IMM_V(lane_index)); } else { ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10; if (reg_size == 5) { if (elem_size < 2) { - FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); + FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); if (lane_index >= (2 << (3 - elem_size))) { - FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1))); + FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1))); FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size))))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(2)); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(2)); } else { - FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(18)); + FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index))); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(18)); } } else ins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26; } - return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index)); + return push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index)); } return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3417,7 +3453,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); if (reg_size != 5 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3431,18 +3467,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10; if (reg_size == 5) { - FAIL_IF(push_inst(compiler, VREPLVEI | (sljit_ins)1 << 26 | ins | FRD(freg) | FRJ(src) | IMM_V(src_lane_index % (2 << (3 - elem_size))))); + FAIL_IF(push_inst(compiler, VREPLVEI | (sljit_ins)1 << 26 | ins | FRD(vreg) | FRJ(src) | IMM_V(src_lane_index % (2 << (3 - elem_size))))); ins = (src_lane_index < (2 << (3 - elem_size))) ? (sljit_ins)(0x44 << 10) : (sljit_ins)(0xee << 10); - return push_inst(compiler, XVPERMI | ins | FRD(freg) | FRJ(freg)); + return push_inst(compiler, XVPERMI | ins | FRD(vreg) | FRJ(vreg)); } - return push_inst(compiler, VREPLVEI | ins | FRD(freg) | FRJ(src) | IMM_V(src_lane_index)); + return push_inst(compiler, VREPLVEI | ins | FRD(vreg) | FRJ(src) | IMM_V(src_lane_index)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3451,7 +3487,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3471,12 +3507,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler ins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD; if (FAST_IS_REG(src) && src >= 0 && (srcw >= I12_MIN && srcw <= I12_MAX)) - FAIL_IF(push_inst(compiler, ins | FRD(freg) | RJ(src) | IMM_I12(srcw))); + FAIL_IF(push_inst(compiler, ins | FRD(vreg) | RJ(src) | IMM_I12(srcw))); else { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); - FAIL_IF(push_inst(compiler, ins | FRD(freg) | RJ(src) | IMM_I12(0))); + FAIL_IF(push_inst(compiler, ins | FRD(vreg) | RJ(src) | IMM_I12(0))); } - src = freg; + src = vreg; } if (type & SLJIT_SIMD_FLOAT) { @@ -3489,7 +3525,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler FAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16))); } - return push_inst(compiler, VFCVTL_D_S | ins | FRD(freg) | FRJ(src)); + return push_inst(compiler, VFCVTL_D_S | ins | FRD(vreg) | FRJ(src)); } ins = (type & SLJIT_SIMD_EXTEND_SIGNED) ? VSLLWIL : (VSLLWIL | (sljit_ins)1 << 18); @@ -3501,15 +3537,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler if (reg_size == 5) FAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16))); - FAIL_IF(push_inst(compiler, ins | ((sljit_ins)1 << (13 + elem_size)) | FRD(freg) | FRJ(src))); - src = freg; + FAIL_IF(push_inst(compiler, ins | ((sljit_ins)1 << (13 + elem_size)) | FRD(vreg) | FRJ(src))); + src = vreg; } while (++elem_size < elem2_size); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3518,7 +3554,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -3539,7 +3575,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c if (reg_size == 5) ins = (sljit_ins)1 << 26; - FAIL_IF(push_inst(compiler, VMSKLTZ | ins | (sljit_ins)(elem_size << 10) | FRD(TMP_FREG1) | FRJ(freg))); + FAIL_IF(push_inst(compiler, VMSKLTZ | ins | (sljit_ins)(elem_size << 10) | FRD(TMP_FREG1) | FRJ(vreg))); FAIL_IF(push_inst(compiler, VPICKVE2GR_U | (sljit_ins)(0x3c << 10) | RD(dst_r) | FRJ(TMP_FREG1))); @@ -3556,14 +3592,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + ADJUST_LOCAL_OFFSET(src2, src2w); if (reg_size != 5 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3577,6 +3614,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if (type & SLJIT_SIMD_TEST) return SLJIT_SUCCESS; + if (src2 & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); + FAIL_IF(push_inst(compiler, (reg_size == 4 ? VLD : XVLD) | FRD(TMP_FREG1) | RJ(src2) | IMM_I12(0))); + src2 = TMP_FREG1; + } + switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = VAND_V; @@ -3587,12 +3630,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = VXOR_V; break; + case SLJIT_SIMD_OP2_SHUFFLE: + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + return push_inst(compiler, VSHUF_B | FRD(dst_vreg) | FRJ(src1_vreg) | FRK(src1_vreg) | FRA(src2)); } if (reg_size == 5) ins |= (sljit_ins)1 << 26; - return push_inst(compiler, ins | FRD(dst_freg) | FRJ(src1_freg) | FRK(src2_freg)); + return push_inst(compiler, ins | FRD(dst_vreg) | FRJ(src1_vreg) | FRK(src2)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, @@ -3605,14 +3653,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + if ((op & SLJIT_ATOMIC_USE_LS) || !LOONGARCH_SUPPORT_AMCAS) { + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + ins = LL_D; + break; + case SLJIT_MOV_S32: + case SLJIT_MOV32: + ins = LL_W; + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | RD(dst_reg) | RJ(mem_reg)); + } + switch(GET_OPCODE(op)) { + case SLJIT_MOV_S8: + ins = LD_B; + break; case SLJIT_MOV_U8: ins = LD_BU; break; + case SLJIT_MOV_S16: + ins = LD_H; + break; case SLJIT_MOV_U16: ins = LD_HU; break; case SLJIT_MOV32: + case SLJIT_MOV_S32: ins = LD_W; break; case SLJIT_MOV_U32: @@ -3623,6 +3702,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler break; } + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + return push_inst(compiler, ins | RD(dst_reg) | RJ(mem_reg) | IMM_I12(0)); } @@ -3639,16 +3721,48 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + if ((op & SLJIT_ATOMIC_USE_LS) || !LOONGARCH_SUPPORT_AMCAS) { + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: + ins = SC_D; + break; + case SLJIT_MOV_S32: + case SLJIT_MOV32: + ins = SC_W; + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, ADD_D | RD(OTHER_FLAG) | RJ(src_reg) | RK(TMP_ZERO))); + return push_inst(compiler, ins | RD(OTHER_FLAG) | RJ(mem_reg)); + } + switch (GET_OPCODE(op)) { + case SLJIT_MOV_S8: + ins = AMCAS_B; + break; case SLJIT_MOV_U8: ins = AMCAS_B; unsign = BSTRPICK_D | (7 << 16); break; + case SLJIT_MOV_S16: + ins = AMCAS_H; + break; case SLJIT_MOV_U16: ins = AMCAS_H; unsign = BSTRPICK_D | (15 << 16); break; case SLJIT_MOV32: + case SLJIT_MOV_S32: ins = AMCAS_W; break; case SLJIT_MOV_U32: @@ -3660,9 +3774,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + if (op & SLJIT_SET_ATOMIC_STORED) { - FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RJ(temp_reg) | RK(TMP_ZERO))); - tmp = TMP_REG1; + FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG3) | RJ(temp_reg) | RK(TMP_ZERO))); + tmp = TMP_REG3; } FAIL_IF(push_inst(compiler, ins | RD(tmp) | RJ(mem_reg) | RK(src_reg))); if (!(op & SLJIT_SET_ATOMIC_STORED)) @@ -3671,8 +3788,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler if (unsign) FAIL_IF(push_inst(compiler, unsign | RD(tmp) | RJ(tmp))); - FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(tmp) | RK(temp_reg))); - return push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RJ(EQUAL_FLAG) | IMM_I12(1)); + FAIL_IF(push_inst(compiler, XOR | RD(OTHER_FLAG) | RJ(tmp) | RK(temp_reg))); + return push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RJ(OTHER_FLAG) | IMM_I12(1)); } static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c index 88eb30b7f163b..1b951fe18348e 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c @@ -249,6 +249,8 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define LDL (HI(26)) #define LDR (HI(27)) #define LDC1 (HI(53)) +#define LL (HI(48)) +#define LLD (HI(52)) #define LUI (HI(15)) #define LW (HI(35)) #define LWL (HI(34)) @@ -288,6 +290,8 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define ROTR (HI(0) | (1 << 21) | LO(2)) #define ROTRV (HI(0) | (1 << 6) | LO(6)) #endif /* SLJIT_MIPS_REV >= 2 */ +#define SC (HI(56)) +#define SCD (HI(60)) #define SD (HI(63)) #define SDL (HI(44)) #define SDR (HI(45)) @@ -308,6 +312,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define SWL (HI(42)) #define SWR (HI(46)) #define SWC1 (HI(57)) +#define SYNC (HI(0) | LO(15)) #define TRUNC_W_S (HI(17) | FMT_S | LO(13)) #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define WSBH (HI(31) | (2 << 6) | LO(32)) @@ -381,11 +386,21 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) fr -= SLJIT_F64_SECOND(0); - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) - || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches)) + || (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } +static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(vr); + SLJIT_UNUSED_ARG(type); + + /* SIMD is not supported. */ + return 0; +} + #endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_ARGUMENT_CHECKS */ static void get_cpu_features(void) @@ -857,6 +872,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_CMOV: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: return 1; case SLJIT_HAS_CTZ: @@ -928,17 +945,22 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit #endif SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); sljit_ins base; sljit_s32 i, tmp, offset; sljit_s32 arg_count, word_arg_count, float_arg_count; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -1138,12 +1160,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); + CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -2462,6 +2490,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); #endif /* SLJIT_MIPS_REV >= 6 */ + case SLJIT_MEMORY_BARRIER: +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) + return push_inst(compiler, SYNC, UNMOVABLE_INS); +#else /* SLJIT_MIPS_REV < 1 */ + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_MIPS_REV >= 1 */ case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -3312,6 +3346,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: case SLJIT_CARRY: + case SLJIT_ATOMIC_STORED: BR_Z(OTHER_FLAG); break; case SLJIT_GREATER_EQUAL: @@ -3320,6 +3355,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: case SLJIT_NOT_CARRY: + case SLJIT_ATOMIC_NOT_STORED: BR_NZ(OTHER_FLAG); break; case SLJIT_F_NOT_EQUAL: @@ -4209,6 +4245,80 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil #undef TO_ARGW_HI +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + ins = LLD; + break; +#endif /* SLJIT_CONFIG_MIPS_64 */ + case SLJIT_MOV_S32: + case SLJIT_MOV32: + ins = LL; + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | T(dst_reg) | S(mem_reg), DR(dst_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins ins; + + /* temp_reg == mem_reg is undefined so use another temp register */ + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + ins = SCD; + break; +#endif /* SLJIT_CONFIG_RISCV_64 */ + case SLJIT_MOV_S32: + case SLJIT_MOV32: + op |= SLJIT_32; + ins = SC; + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src_reg) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG)); + return push_inst(compiler, ins | TA(OTHER_FLAG) | S(mem_reg), OTHER_FLAG); +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c b/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c index 1f17d90423eb6..3d2268e896bff 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c @@ -187,10 +187,12 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define LD (HI(58) | 0) #define LFD (HI(50)) #define LFS (HI(48)) +#define LDARX (HI(31) | LO(84)) #if defined(_ARCH_PWR7) && _ARCH_PWR7 #define LDBRX (HI(31) | LO(532)) #endif /* POWER7 */ #define LHBRX (HI(31) | LO(790)) +#define LWARX (HI(31) | LO(20)) #define LWBRX (HI(31) | LO(534)) #define LWZ (HI(32)) #define MFCR (HI(31) | LO(19)) @@ -231,6 +233,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #if defined(_ARCH_PWR7) && _ARCH_PWR7 #define STDBRX (HI(31) | LO(660)) #endif /* POWER7 */ +#define STDCX (HI(31) | LO(214)) #define STDU (HI(62) | 1) #define STDUX (HI(31) | LO(181)) #define STFD (HI(54)) @@ -239,12 +242,14 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define STHBRX (HI(31) | LO(918)) #define STW (HI(36)) #define STWBRX (HI(31) | LO(662)) +#define STWCX (HI(31) | LO(150)) #define STWU (HI(37)) #define STWUX (HI(31) | LO(183)) #define SUBF (HI(31) | LO(40)) #define SUBFC (HI(31) | LO(8)) #define SUBFE (HI(31) | LO(136)) #define SUBFIC (HI(8)) +#define SYNC (HI(31) | LO(598)) #define XOR (HI(31) | LO(316)) #define XORI (HI(26)) #define XORIS (HI(27)) @@ -314,7 +319,11 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i { sljit_sw diff; sljit_uw target_addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; + sljit_uw orig_addr = jump->addr; + SLJIT_UNUSED_ARG(executable_offset); + jump->addr = jump_addr; #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) goto exit; @@ -328,6 +337,9 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i else { SLJIT_ASSERT(jump->u.label != NULL); target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; + + if (jump->u.label->size > orig_addr) + jump_addr = (sljit_uw)(code + orig_addr); } #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -335,7 +347,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i goto keep_address; #endif - diff = (sljit_sw)target_addr - (sljit_sw)code_ptr - executable_offset; + diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if (jump->flags & IS_COND) { if (diff <= 0x7fff && diff >= -0x8000) { @@ -547,6 +559,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if (jump->flags & IS_COND) { if (diff <= (0x7fff / SSIZE_OF(ins)) && diff >= (-0x8000 / SSIZE_OF(ins))) @@ -592,6 +608,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + sljit_uw jump_addr; +#endif SLJIT_NEXT_DEFINE_TYPES; sljit_sw executable_offset; @@ -648,9 +667,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count += jump->flags >> JUMP_SIZE_SHIFT; - jump->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + jump_addr = (sljit_uw)code_ptr; +#endif code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); - SLJIT_ASSERT(((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); + SLJIT_ASSERT(((sljit_uw)code_ptr - jump_addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { jump->addr = (sljit_uw)code_ptr; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -748,6 +769,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_ROT: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: return 1; case SLJIT_HAS_CTZ: @@ -845,9 +868,11 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flag #define STACK_MAX_DISTANCE (0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); sljit_s32 i, tmp, base, offset; sljit_s32 word_arg_count = 0; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); @@ -856,9 +881,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 0) + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -962,13 +989,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); + CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 0) + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1399,6 +1431,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #else return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); #endif + case SLJIT_MEMORY_BARRIER: + return push_inst(compiler, SYNC); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2422,6 +2456,7 @@ static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type /* fallthrough */ case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: return (12 << 21) | (2 << 16); case SLJIT_CARRY: @@ -2430,6 +2465,7 @@ static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type /* fallthrough */ case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: return (4 << 21) | (2 << 16); case SLJIT_LESS: @@ -2686,10 +2722,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co break; case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: bit = 2; break; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: bit = 2; invert = 1; break; @@ -3106,6 +3144,78 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + ins = LDARX; + break; +#endif /* SLJIT_CONFIG_RISCV_64 */ + case SLJIT_MOV_U32: + case SLJIT_MOV32: + ins = LWARX; + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | D(dst_reg) | B(mem_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins ins; + + /* temp_reg == mem_reg is undefined so use another temp register */ + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + ins = STDCX | 0x1; + break; +#endif /* SLJIT_CONFIG_RISCV_64 */ + case SLJIT_MOV_U32: + case SLJIT_MOV32: + ins = STWCX | 0x1; + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | D(src_reg) | B(mem_reg)); +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c index d86100a80ceff..d3ba46dba8b31 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c @@ -50,6 +50,9 @@ typedef sljit_u32 sljit_ins; #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) +#define TMP_VREG1 (SLJIT_NUMBER_OF_VECTOR_REGISTERS + 1) +#define TMP_VREG2 (SLJIT_NUMBER_OF_VECTOR_REGISTERS + 2) + static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { 0, 10, 11, 12, 13, 14, 15, 16, 17, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 2, 6, 1, 7, 5, 28 }; @@ -58,6 +61,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { 0, 10, 11, 12, 13, 14, 15, 16, 17, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 0, 1, }; +static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + /* --------------------------------------------------------------------- */ /* Instrucion forms */ /* --------------------------------------------------------------------- */ @@ -68,6 +75,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define FRD(rd) ((sljit_ins)freg_map[rd] << 7) #define FRS1(rs1) ((sljit_ins)freg_map[rs1] << 15) #define FRS2(rs2) ((sljit_ins)freg_map[rs2] << 20) +#define VRD(rd) ((sljit_ins)vreg_map[rd] << 7) +#define VRS1(rs1) ((sljit_ins)vreg_map[rs1] << 15) +#define VRS2(rs2) ((sljit_ins)vreg_map[rs2] << 20) #define IMM_I(imm) ((sljit_ins)(imm) << 20) #define IMM_S(imm) ((((sljit_ins)(imm) & 0xfe0) << 20) | (((sljit_ins)(imm) & 0x1f) << 7)) @@ -77,6 +87,15 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define F12(f) ((sljit_ins)(f) << 20) #define F7(f) ((sljit_ins)(f) << 25) +/* Vector instruction types. */ +#define OPFVF (F3(0x5) | OPC(0x57)) +#define OPFVV (F3(0x1) | OPC(0x57)) +#define OPIVI (F3(0x3) | OPC(0x57)) +#define OPIVV (F3(0x0) | OPC(0x57)) +#define OPIVX (F3(0x4) | OPC(0x57)) +#define OPMVV (F3(0x2) | OPC(0x57)) +#define OPMVX (F3(0x6) | OPC(0x57)) + #define ADD (F7(0x0) | F3(0x0) | OPC(0x33)) #define ADDI (F3(0x0) | OPC(0x13)) #define AND (F7(0x0) | F3(0x7) | OPC(0x33)) @@ -88,11 +107,16 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define BGE (F3(0x5) | OPC(0x63)) #define BLTU (F3(0x6) | OPC(0x63)) #define BGEU (F3(0x7) | OPC(0x63)) +#if defined __riscv_zbb +#define CLZ (F7(0x30) | F3(0x1) | OPC(0x13)) +#define CTZ (F7(0x30) | F12(0x1) | F3(0x1) | OPC(0x13)) +#endif /* __riscv_zbb */ #define DIV (F7(0x1) | F3(0x4) | OPC(0x33)) #define DIVU (F7(0x1) | F3(0x5) | OPC(0x33)) #define EBREAK (F12(0x1) | F3(0x0) | OPC(0x73)) #define FADD_S (F7(0x0) | F3(0x7) | OPC(0x53)) #define FDIV_S (F7(0xc) | F3(0x7) | OPC(0x53)) +#define FENCE (F3(0x0) | OPC(0xf)) #define FEQ_S (F7(0x50) | F3(0x2) | OPC(0x53)) #define FLD (F3(0x3) | OPC(0x7)) #define FLE_S (F7(0x50) | F3(0x0) | OPC(0x53)) @@ -116,6 +140,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define LD (F3(0x3) | OPC(0x3)) #define LUI (OPC(0x37)) #define LW (F3(0x2) | OPC(0x3)) +#define LR (F7(0x8) | OPC(0x2f)) #define MUL (F7(0x1) | F3(0x0) | OPC(0x33)) #define MULH (F7(0x1) | F3(0x1) | OPC(0x33)) #define MULHU (F7(0x1) | F3(0x3) | OPC(0x33)) @@ -123,21 +148,73 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define ORI (F3(0x6) | OPC(0x13)) #define REM (F7(0x1) | F3(0x6) | OPC(0x33)) #define REMU (F7(0x1) | F3(0x7) | OPC(0x33)) +#if defined __riscv_zbb +#if defined SLJIT_CONFIG_RISCV_32 +#define REV8 (F12(0x698) | F3(0x5) | OPC(0x13)) +#elif defined SLJIT_CONFIG_RISCV_64 +#define REV8 (F12(0x6b8) | F3(0x5) | OPC(0x13)) +#endif /* SLJIT_CONFIG_RISCV_32 */ +#define ROL (F7(0x30) | F3(0x1) | OPC(0x33)) +#define ROR (F7(0x30) | F3(0x5) | OPC(0x33)) +#define RORI (F7(0x30) | F3(0x5) | OPC(0x13)) +#endif /* __riscv_zbb */ +#define SC (F7(0xc) | OPC(0x2f)) #define SD (F3(0x3) | OPC(0x23)) +#if defined __riscv_zbb +#define SEXTB (F7(0x30) | F12(0x4) | F3(0x1) | OPC(0x13)) +#define SEXTH (F7(0x30) | F12(0x5) | F3(0x1) | OPC(0x13)) +#endif /* __riscv_zbb */ +#if defined __riscv_zba +#define SH1ADD (F7(0x10) | F3(0x2) | OPC(0x33)) +#define SH2ADD (F7(0x10) | F3(0x4) | OPC(0x33)) +#define SH3ADD (F7(0x10) | F3(0x6) | OPC(0x33)) +#endif /* __riscv_zba */ #define SLL (F7(0x0) | F3(0x1) | OPC(0x33)) -#define SLLI (IMM_I(0x0) | F3(0x1) | OPC(0x13)) +#define SLLI (F3(0x1) | OPC(0x13)) #define SLT (F7(0x0) | F3(0x2) | OPC(0x33)) #define SLTI (F3(0x2) | OPC(0x13)) #define SLTU (F7(0x0) | F3(0x3) | OPC(0x33)) #define SLTUI (F3(0x3) | OPC(0x13)) #define SRL (F7(0x0) | F3(0x5) | OPC(0x33)) -#define SRLI (IMM_I(0x0) | F3(0x5) | OPC(0x13)) +#define SRLI (F3(0x5) | OPC(0x13)) #define SRA (F7(0x20) | F3(0x5) | OPC(0x33)) -#define SRAI (IMM_I(0x400) | F3(0x5) | OPC(0x13)) +#define SRAI (F7(0x20) | F3(0x5) | OPC(0x13)) #define SUB (F7(0x20) | F3(0x0) | OPC(0x33)) #define SW (F3(0x2) | OPC(0x23)) +#define VAND_VV (F7(0x13) | OPIVV) +#define VFMV_FS (F7(0x21) | OPFVV) +#define VFMV_SF (F7(0x21) | OPFVF) +#define VFMV_VF (F7(0x2f) | OPFVF) +#define VFWCVT_FFV (F7(0x25) | (0xc << 15) | OPFVV) +#define VL (F7(0x1) | OPC(0x7)) +#define VMSLE_VI (F7(0x3b) | OPIVI) +#define VMV_SX (F7(0x21) | OPMVX) +#define VMV_VI (F7(0x2f) | OPIVI) +#define VMV_VV (F7(0x2f) | OPIVV) +#define VMV_VX (F7(0x2f) | OPIVX) +#define VMV_XS (F7(0x21) | OPMVV) +#define VOR_VV (F7(0x15) | OPIVV) +#define VSETIVLI (F7(0x60) | F3(0x7) | OPC(0x57)) +#define VS (F7(0x1) | OPC(0x27)) +#define VSLIDEDOWN_VX (F7(0x1f) | OPIVX) +#define VSLIDEDOWN_VI (F7(0x1f) | OPIVI) +#define VSLIDEUP_VX (F7(0x1d) | OPIVX) +#define VSLIDEUP_VI (F7(0x1d) | OPIVI) +#define VRGATHER_VI (F7(0x19) | OPIVI) +#define VRGATHER_VV (F7(0x19) | OPIVV) +#define VXOR_VV (F7(0x17) | OPIVV) +#define VZEXT_VF2 (F7(0x25) | (0x6 << 15) | OPMVV) +#define VZEXT_VF4 (F7(0x25) | (0x4 << 15) | OPMVV) +#define VZEXT_VF8 (F7(0x25) | (0x2 << 15) | OPMVV) #define XOR (F7(0x0) | F3(0x4) | OPC(0x33)) #define XORI (F3(0x4) | OPC(0x13)) +#if defined __riscv_zbb +#if defined SLJIT_CONFIG_RISCV_32 +#define ZEXTH (F7(0x4) | F3(0x4) | OPC(0x33)) +#elif defined SLJIT_CONFIG_RISCV_64 +#define ZEXTH (F7(0x4) | F3(0x4) | OPC(0x3B)) +#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif /* __riscv_zbb */ #define SIMM_MAX (0x7ff) #define SIMM_MIN (-0x800) @@ -151,7 +228,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define S32_MIN (-0x80000000l) #define S44_MAX (0x7fffffff7ffl) #define S52_MAX (0x7ffffffffffffl) -#endif +#endif /* SLJIT_CONFIG_RISCV_64 */ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { @@ -167,14 +244,15 @@ static sljit_s32 push_imm_s_inst(struct sljit_compiler *compiler, sljit_ins ins, return push_inst(compiler, ins | IMM_S(imm)); } -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; - sljit_ins *inst; - - inst = (sljit_ins *)jump->addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; + sljit_uw orig_addr = jump->addr; + SLJIT_UNUSED_ARG(executable_offset); + jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -182,20 +260,23 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; + target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); + + if (jump->u.label->size > orig_addr) + jump_addr = (sljit_uw)(code + orig_addr); } - diff = (sljit_sw)target_addr - (sljit_sw)inst - executable_offset; + diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); if (diff >= BRANCH_MIN && diff <= BRANCH_MAX) { - inst--; - inst[0] = (inst[0] & 0x1fff07f) ^ 0x1000; + code_ptr--; + code_ptr[0] = (code_ptr[0] & 0x1fff07f) ^ 0x1000; jump->flags |= PATCH_B; - jump->addr = (sljit_uw)inst; - return inst; + jump->addr = (sljit_uw)code_ptr; + return code_ptr; } diff -= SSIZE_OF(ins); @@ -204,62 +285,62 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i if (diff >= JUMP_MIN && diff <= JUMP_MAX) { if (jump->flags & IS_COND) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - inst[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; -#else - inst[-1] -= (sljit_ins)(5 * sizeof(sljit_ins)) << 7; -#endif + code_ptr[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; +#else /* !SLJIT_CONFIG_RISCV_32 */ + code_ptr[-1] -= (sljit_ins)(5 * sizeof(sljit_ins)) << 7; +#endif /* SLJIT_CONFIG_RISCV_32 */ } jump->flags |= PATCH_J; - return inst; + return code_ptr; } #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) if (diff >= S32_MIN && diff <= S32_MAX) { if (jump->flags & IS_COND) - inst[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; + code_ptr[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_REL32; - inst[1] = inst[0]; - return inst + 1; + code_ptr[1] = code_ptr[0]; + return code_ptr + 1; } if (target_addr <= (sljit_uw)S32_MAX) { if (jump->flags & IS_COND) - inst[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; + code_ptr[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_ABS32; - inst[1] = inst[0]; - return inst + 1; + code_ptr[1] = code_ptr[0]; + return code_ptr + 1; } if (target_addr <= S44_MAX) { if (jump->flags & IS_COND) - inst[-1] -= (sljit_ins)(2 * sizeof(sljit_ins)) << 7; + code_ptr[-1] -= (sljit_ins)(2 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_ABS44; - inst[3] = inst[0]; - return inst + 3; + code_ptr[3] = code_ptr[0]; + return code_ptr + 3; } if (target_addr <= S52_MAX) { if (jump->flags & IS_COND) - inst[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; + code_ptr[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_ABS52; - inst[4] = inst[0]; - return inst + 4; + code_ptr[4] = code_ptr[0]; + return code_ptr + 4; } -#endif +#endif /* SLJIT_CONFIG_RISCV_64 */ exit: #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - inst[1] = inst[0]; - return inst + 1; -#else - inst[5] = inst[0]; - return inst + 5; -#endif + code_ptr[1] = code_ptr[0]; + return code_ptr + 1; +#else /* !SLJIT_CONFIG_RISCV_32 */ + code_ptr[5] = code_ptr[0]; + return code_ptr + 5; +#endif /* SLJIT_CONFIG_RISCV_32 */ } #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) @@ -267,16 +348,21 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; + sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT)); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else + else { addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + if (jump->u.label->size > jump->addr) + jump_addr = (sljit_uw)(code + jump->addr); + } + + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); if (diff >= S32_MIN && diff <= S32_MAX) { SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT)); @@ -316,7 +402,7 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : TMP_REG1; #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) sljit_sw high; -#endif +#endif /* SLJIT_CONFIG_RISCV_64 */ SLJIT_UNUSED_ARG(executable_offset); #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) @@ -337,7 +423,7 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr); return; } -#endif +#endif /* SLJIT_CONFIG_RISCV_64 */ if ((addr & 0x800) != 0) addr += 0x1000; @@ -453,6 +539,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH_MIN / SSIZE_OF(ins))) total_size = 0; @@ -474,6 +564,10 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { /* Real size minus 1. Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins))) total_size = 1; @@ -552,8 +646,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - jump->addr = (sljit_uw)code_ptr; - code_ptr = detect_jump_type(jump, code, executable_offset); + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) @@ -642,7 +735,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) return (SLJIT_IS_FPU_AVAILABLE) != 0; #elif defined(__riscv_float_abi_soft) return 0; -#else +#else /* !SLJIT_IS_FPU_AVAILABLE && !__riscv_float_abi_soft */ return 1; #endif /* SLJIT_IS_FPU_AVAILABLE */ case SLJIT_HAS_ZERO_REGISTER: @@ -650,7 +743,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) case SLJIT_HAS_COPY_F64: #endif /* !SLJIT_CONFIG_RISCV_64 */ + case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: +#ifdef __riscv_vector + case SLJIT_HAS_SIMD: +#endif /* __riscv_vector */ + return 1; +#ifdef __riscv_zbb + case SLJIT_HAS_CLZ: + case SLJIT_HAS_CTZ: + case SLJIT_HAS_REV: + case SLJIT_HAS_ROT: return 1; +#endif /* __riscv_zbb */ default: return 0; } @@ -708,32 +813,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define STACK_STORE SW #define STACK_LOAD LW -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ #define STACK_STORE SD #define STACK_LOAD LD -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #include "sljitNativeRISCV_32.c" -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ #include "sljitNativeRISCV_64.c" -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ #define STACK_MAX_DISTANCE (-SIMM_MIN) static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw); SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); sljit_s32 i, tmp, offset; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1); #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { @@ -741,9 +850,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi local_size += SSIZE_OF(sw); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; compiler->local_size = local_size; @@ -778,7 +887,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi /* This alignment is valid because offset is not used after storing FPU regs. */ if ((offset & SSIZE_OF(sw)) != 0) offset -= SSIZE_OF(sw); -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ tmp = SLJIT_FS0 - fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { @@ -821,13 +930,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #undef STACK_MAX_DISTANCE SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); + sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); + CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { @@ -835,9 +949,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp local_size += SSIZE_OF(sw); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; return SLJIT_SUCCESS; @@ -883,7 +997,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit /* This alignment is valid because offset is not used after storing FPU regs. */ if ((offset & SSIZE_OF(sw)) != 0) offset -= SSIZE_OF(sw); -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ tmp = SLJIT_FS0 - compiler->fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { @@ -939,9 +1053,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define ARCH_32_64(a, b) a -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ #define ARCH_32_64(a, b) b -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ static const sljit_ins data_transfer_insts[16 + 4] = { /* u w s */ ARCH_32_64(F3(0x2) | OPC(0x23) /* sw */, F3(0x3) | OPC(0x23) /* sd */), @@ -1034,6 +1148,9 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl sljit_s32 base = arg & REG_MASK; sljit_s32 tmp_r = (flags & MEM_USE_TMP2) ? TMP_REG2 : TMP_REG1; sljit_sw offset, argw_hi; +#if defined __riscv_zba + sljit_ins ins = ADD; +#endif /* __riscv_zba */ SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -1044,6 +1161,20 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { argw &= 0x3; +#if defined __riscv_zba + switch (argw) { + case 1: + ins = SH1ADD; + break; + case 2: + ins = SH2ADD; + break; + case 3: + ins = SH3ADD; + break; + } + FAIL_IF(push_inst(compiler, ins | RD(tmp_r) | RS1(OFFS_REG(arg)) | RS2(base))); +#else /* !__riscv_zba */ /* Using the cache. */ if (argw == compiler->cache_argw) { if (arg == compiler->cache_arg) @@ -1075,6 +1206,8 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl } else FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(!argw ? OFFS_REG(arg) : TMP_REG3))); +#endif /* __riscv_zba */ + return push_mem_inst(compiler, flags, reg, tmp_r, 0); } @@ -1161,7 +1294,7 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji #define WORD_32 0x08 #define IMM_EXTEND(v) (IMM_I((op & SLJIT_32) ? (v) : (32 + (v)))) #endif /* SLJIT_CONFIG_RISCV_32 */ - +#ifndef __riscv_zbb static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) { sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ); @@ -1264,6 +1397,7 @@ static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | WORD | RD(dst) | RS1(dst) | IMM_I(word_size - 16))); return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); } +#endif /* !__riscv_zbb */ #define EMIT_LOGICAL(op_imm, op_reg) \ if (flags & SRC2_IMM) { \ @@ -1309,6 +1443,9 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; case SLJIT_MOV_S8: +#if defined __riscv_zbb + return push_inst(compiler, SEXTB | RD(dst) | RS1(src2)); +#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(24))); @@ -1316,8 +1453,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } SLJIT_ASSERT(dst == src2); return SLJIT_SUCCESS; +#endif /* __riscv_zbb */ case SLJIT_MOV_U16: +#if defined __riscv_zbb + return push_inst(compiler, ZEXTH | RD(dst) | RS1(src2)); +#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16))); @@ -1325,8 +1466,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } SLJIT_ASSERT(dst == src2); return SLJIT_SUCCESS; +#endif /* __riscv_zbb */ case SLJIT_MOV_S16: +#if defined __riscv_zbb + return push_inst(compiler, SEXTH | RD(dst) | RS1(src2)); +#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16))); @@ -1334,6 +1479,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } SLJIT_ASSERT(dst == src2); return SLJIT_SUCCESS; +#endif /* !__riscv_zbb */ #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) case SLJIT_MOV_U32: @@ -1354,24 +1500,59 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl #endif /* SLJIT_CONFIG_RISCV_64 */ case SLJIT_CLZ: +#if defined __riscv_zbb + return push_inst(compiler, CLZ | WORD | RD(dst) | RS1(src2)); +#endif /* __riscv_zbb */ case SLJIT_CTZ: +#if defined __riscv_zbb + return push_inst(compiler, CTZ | WORD | RD(dst) | RS1(src2)); +#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); return emit_clz_ctz(compiler, op, dst, src2); +#endif /* __riscv_zbb */ case SLJIT_REV: +#if defined __riscv_zbb + SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); + FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2))); +#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64 + if (op & SLJIT_32) + return push_inst(compiler, SRAI | RD(dst) | RS1(dst) | IMM_I(32)); + return SLJIT_SUCCESS; +#else /* !SLJIT_CONFIG_RISCV_64 */ + return SLJIT_SUCCESS; +#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif /* __riscv_zbb */ case SLJIT_REV_S32: -#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) +#if ((defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || defined __riscv_zbb) case SLJIT_REV_U32: -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif /* SLJIT_CONFIG_RISCV_32 || __riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); +#if defined __riscv_zbb + FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2))); +#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64 + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U32 ? SRLI : SRAI )| RD(dst) | RS1(dst) | IMM_I(32)); +#else /* !SLJIT_CONFIG_RISCV_64 */ + return SLJIT_SUCCESS; +#endif /* SLJIT_CONFIG_RISCV_64 */ +#else /* !__riscv_zbb */ return emit_rev(compiler, op, dst, src2); - +#endif /* __riscv_zbb */ case SLJIT_REV_U16: case SLJIT_REV_S16: SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); +#if defined __riscv_zbb + FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2))); +#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64 + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI )| RD(dst) | RS1(dst) | IMM_I(48)); +#else /* !SLJIT_CONFIG_RISCV_64 */ + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | RD(dst) | RS1(dst) | IMM_I(16)); +#endif /* SLJIT_CONFIG_RISCV_64 */ +#else /* !__riscv_zbb */ return emit_rev16(compiler, op, dst, src2); +#endif /* __riscv_zbb */ -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) +#if ((defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) && !defined __riscv_zbb) case SLJIT_REV_U32: SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1); FAIL_IF(emit_rev(compiler, op, dst, src2)); @@ -1379,8 +1560,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(32))); return push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32)); -#endif /* SLJIT_CONFIG_RISCV_32 */ - +#endif /* SLJIT_CONFIG_RISCV_64 && !__riscv_zbb */ case SLJIT_ADD: /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; @@ -1668,7 +1848,16 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_ROTR: if (flags & SRC2_IMM) { SLJIT_ASSERT(src2 != 0); - +#if defined __riscv_zbb + if (GET_OPCODE(op) == SLJIT_ROTL) { +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + src2 = ((op & SLJIT_32) ? 32 : 64) - src2; +#else /* !SLJIT_CONFIG_RISCV_64 */ + src2 = 32 - src2; +#endif /* SLJIT_CONFIG_RISCV_64 */ + } + return push_inst(compiler, RORI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)); +#else /* !__riscv_zbb */ op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLI : SRLI; FAIL_IF(push_inst(compiler, op_imm | WORD | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2))); @@ -1680,8 +1869,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLI : SLLI; FAIL_IF(push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)); +#endif /* !__riscv_zbb */ } +#if defined __riscv_zbb + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_ROTL ? ROL : ROR) | WORD | RD(dst) | RS1(src1) | RS2(src2)); +#else /* !__riscv_zbb */ if (src2 == TMP_ZERO) { if (dst != src1) return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(0)); @@ -1694,7 +1887,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl op_reg = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL; FAIL_IF(push_inst(compiler, op_reg | WORD | RD(dst) | RS1(src1) | RS2(EQUAL_FLAG))); return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)); - +#endif /* !riscv_zbb */ default: SLJIT_UNREACHABLE(); return SLJIT_SUCCESS; @@ -1881,6 +2074,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, DIVU | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)); case SLJIT_DIV_SW: return push_inst(compiler, DIV | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)); + case SLJIT_MEMORY_BARRIER: + return push_inst(compiler, FENCE | 0x0ff00000); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -1903,7 +2098,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) if (op & SLJIT_32) flags = INT_DATA | SIGNED_DATA; -#endif +#endif /* SLJIT_CONFIG_RISCV_64 */ switch (GET_OPCODE(op)) { case SLJIT_MOV: @@ -1911,7 +2106,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_U32: case SLJIT_MOV_S32: case SLJIT_MOV32: -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, srcw); @@ -1923,7 +2118,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile /* Logical operators have no W variant, so sign extended input is necessary for them. */ case SLJIT_MOV32: return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw); -#endif +#endif /* SLJIT_CONFIG_RISCV_64 */ case SLJIT_MOV_U8: return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); @@ -1976,7 +2171,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (src2 == SLJIT_IMM) src2w = (sljit_s32)src2w; } -#endif +#endif /* SLJIT_CONFIG_RISCV_64 */ switch (GET_OPCODE(op)) { case SLJIT_ADD: @@ -2204,10 +2399,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_GP_REGISTER) return reg_map[reg]; - if (type != SLJIT_FLOAT_REGISTER) - return -1; + if (type == SLJIT_FLOAT_REGISTER) + return freg_map[reg]; - return freg_map[reg]; + return vreg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -2234,9 +2429,9 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) # define flags (sljit_u32)0 -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21; -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; if (src & SLJIT_MEM) { @@ -2250,15 +2445,15 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (dst & SLJIT_MEM) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) return emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ return emit_op_mem2(compiler, flags ? WORD_DATA : INT_DATA, TMP_REG2, dst, dstw, 0, 0); -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) # undef flags -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ } static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, @@ -2556,9 +2751,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define BRANCH_LENGTH ((sljit_ins)(3 * sizeof(sljit_ins)) << 7) -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ #define BRANCH_LENGTH ((sljit_ins)(7 * sizeof(sljit_ins)) << 7) -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ static sljit_ins get_jump_instruction(sljit_s32 type) { @@ -2573,6 +2768,7 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: case SLJIT_CARRY: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: case SLJIT_ORDERED_NOT_EQUAL: @@ -2591,6 +2787,7 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: case SLJIT_NOT_CARRY: + case SLJIT_ATOMIC_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: case SLJIT_UNORDERED_OR_EQUAL: @@ -2687,7 +2884,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler } if (src2 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, flags, src2_tmp_reg, src2, src2w, 0, 0)); + PTR_FAIL_IF(emit_op_mem2(compiler, flags | (src1 == TMP_REG1 ? MEM_USE_TMP2 : 0), src2_tmp_reg, src2, src2w, 0, 0)); src2 = src2_tmp_reg; } @@ -2825,9 +3022,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 saved_op = op; #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) sljit_s32 mem_type = WORD_DATA; -#else +#else /* !SLJIT_CONFIG_RISCV_32 */ sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; -#endif +#endif /* SLJIT_CONFIG_RISCV_32 */ CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type)); @@ -2862,6 +3059,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co src_r = dst_r; invert ^= 0x1; break; + case SLJIT_ATOMIC_STORED: + case SLJIT_ATOMIC_NOT_STORED: + invert ^= 0x1; + break; } } else { invert = 0; @@ -3066,6 +3267,561 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile #undef TO_ARGW_HI +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + ins = LR | (3 << 12); + break; +#endif /* SLJIT_CONFIG_RISCV_64 */ + case SLJIT_MOV_S32: + case SLJIT_MOV32: + ins = LR | (2 << 12); + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | RD(dst_reg) | RS1(mem_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins ins; + + /* temp_reg == mem_reg is undefined so use another temp register */ + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + if (op & SLJIT_ATOMIC_USE_CAS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_P: +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + ins = SC | (3 << 12); + break; +#endif /* SLJIT_CONFIG_RISCV_64 */ + case SLJIT_MOV_S32: + case SLJIT_MOV32: + ins = SC | (2 << 12); + break; + + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | RD(OTHER_FLAG) | RS1(mem_reg) | RS2(src_reg)); +} + +/* + SEW = Selected element width + LMUL = Vector register group multiplier + + VLMUL values (in binary): + 100 : reserved + 101 : 1/8 + 110 : 1/4 + 111 : 1/2 + 000 : 1 + 001 : 2 + 010 : 4 + 011 : 8 +*/ + +static SLJIT_INLINE sljit_s32 sljit_emit_vsetivli(struct sljit_compiler *compiler, sljit_s32 type, sljit_ins vlmul) +{ + sljit_ins elem_size = (sljit_ins)SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins avl = (sljit_ins)1 << (SLJIT_SIMD_GET_REG_SIZE(type) - elem_size); + + return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | (elem_size << 23) | (vlmul << 20) | (avl << 15)); +} + +static SLJIT_INLINE sljit_s32 sljit_emit_vsetivli_size(struct sljit_compiler *compiler, sljit_s32 reg_size, sljit_s32 elem_size) +{ + sljit_ins avl = (sljit_ins)1 << (reg_size - elem_size); + return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (avl << 15)); +} + +static sljit_s32 sljit_emit_vmem(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 elem_size, sljit_s32 mem, sljit_sw memw) +{ + sljit_s32 base = mem & REG_MASK; + + if (elem_size > 0) + ins |= (1 << 14) | ((sljit_ins)elem_size << 12); + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + memw &= 0x3; + + if (SLJIT_UNLIKELY(memw)) { + FAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG1) | RS1(OFFS_REG(mem)) | IMM_I(memw))); + } + + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(base) | RS2(!memw ? OFFS_REG(mem) : TMP_REG1))); + return push_inst(compiler, ins | RS1(TMP_REG1)); + } + + if (memw == 0) + return push_inst(compiler, ins | RS1(base)); + + if (memw <= SIMM_MAX && memw >= SIMM_MIN) { + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(base) | IMM_I(memw))); + return push_inst(compiler, ins | RS1(TMP_REG1)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, memw, TMP_REG3)); + + if (base != 0) + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(base))); + + return push_inst(compiler, ins | RS1(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 vreg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (elem_size > 3) + elem_size = 3; + + FAIL_IF(sljit_emit_vsetivli_size(compiler, reg_size, elem_size)); + + if (srcdst & SLJIT_MEM) { + ins = (type & SLJIT_SIMD_STORE) ? VS : VL; + return sljit_emit_vmem(compiler, ins | VRD(vreg), elem_size, srcdst, srcdstw); + } + + if (type & SLJIT_SIMD_STORE) + ins = VRD(srcdst) | VRS1(vreg); + else + ins = VRD(vreg) | VRS1(srcdst); + + return push_inst(compiler, VMV_VV | ins); +} + +static sljit_s32 sljit_simd_get_mem_flags(sljit_s32 elem_size) +{ + switch (elem_size) { + case 0: + return BYTE_DATA; + case 1: + return HALF_DATA; +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + case 2: + return INT_DATA; +#endif /* SLJIT_CONFIG_RISCV_64 */ + default: + return WORD_DATA; + } +} + +static sljit_sw sljit_simd_get_imm(sljit_s32 elem_size, sljit_sw imm) +{ + switch (elem_size) { + case 0: + return (sljit_s8)imm; + case 1: + return (sljit_s16)imm; +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + case 2: + return (sljit_s32)imm; +#endif /* SLJIT_CONFIG_RISCV_64 */ + default: + return imm; + } +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 vreg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 flags; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) + return SLJIT_ERR_UNSUPPORTED; +#else /* !SLJIT_CONFIG_RISCV_32 */ + if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_RISCV_32 */ + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) + return push_inst(compiler, VMV_VI | VRD(vreg) | ((sljit_ins)(srcw & 0x1f) << 15)); + + if (src & SLJIT_MEM) { + flags = (elem_size == 2) ? SINGLE_DATA : DOUBLE_DATA; + FAIL_IF(emit_op_mem(compiler, flags | LOAD_DATA, TMP_FREG1, src, srcw)); + src = TMP_FREG1; + } + + return push_inst(compiler, VFMV_VF | VRD(vreg) | FRS1(src)); + } + + if (src == SLJIT_IMM) { + srcw = sljit_simd_get_imm(elem_size, srcw); + + if (srcw >= -0x10 && srcw <= 0xf) + return push_inst(compiler, VMV_VI | VRD(vreg) | ((sljit_ins)(srcw & 0x1f) << 15)); + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw, TMP_REG3)); + src = TMP_REG1; + } else if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, sljit_simd_get_mem_flags(elem_size) | LOAD_DATA, TMP_REG1, src, srcw)); + src = TMP_REG1; + } + + return push_inst(compiler, VMV_VX | VRD(vreg) | RS1(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 flags; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) + return SLJIT_ERR_UNSUPPORTED; +#else /* !SLJIT_CONFIG_RISCV_32 */ + if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_RISCV_32 */ + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (type & SLJIT_SIMD_STORE) { + FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (1 << 15))); + + if (lane_index > 0) { + FAIL_IF(push_inst(compiler, VSLIDEDOWN_VI | VRD(TMP_VREG1) | ((sljit_ins)lane_index << 15) | VRS2(vreg))); + vreg = TMP_VREG1; + } + + if (srcdst & SLJIT_MEM) + return sljit_emit_vmem(compiler, VS | VRD(vreg), elem_size, srcdst, srcdstw); + + if (type & SLJIT_SIMD_FLOAT) + return push_inst(compiler, VFMV_FS | FRD(srcdst) | VRS2(vreg)); + + FAIL_IF(push_inst(compiler, VMV_XS | RD(srcdst) | VRS2(vreg))); + +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + if ((type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 2) + return SLJIT_SUCCESS; +#else /* !SLJIT_CONFIG_RISCV_32 */ + if ((type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3 || (elem_size == 2 && (type & SLJIT_32))) + return SLJIT_SUCCESS; +#endif /* SLJIT_CONFIG_RISCV_32 */ + + if (elem_size == 0) + return push_inst(compiler, ANDI | RD(srcdst) | RS1(srcdst) | IMM_I(0xff)); + +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + flags = 16; +#else /* !SLJIT_CONFIG_RISCV_32 */ + flags = (elem_size == 1) ? 48 : 32; +#endif /* SLJIT_CONFIG_RISCV_32 */ + + FAIL_IF(push_inst(compiler, SLLI | RD(srcdst) | RS1(srcdst) | IMM_I(flags))); + return push_inst(compiler, SRLI | RD(srcdst) | RS1(srcdst) | IMM_I(flags)); + } + + if (type & SLJIT_SIMD_LANE_ZERO) { + FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); + FAIL_IF(push_inst(compiler, VMV_VI | VRD(vreg))); + } + + if (srcdst & SLJIT_MEM) { + FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (1 << 15))); + FAIL_IF(sljit_emit_vmem(compiler, VL | VRD(lane_index > 0 ? TMP_VREG1 : vreg), elem_size, srcdst, srcdstw)); + + if (lane_index == 0) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | ((sljit_ins)(lane_index + 1) << 15))); + return push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1)); + } + + if (!(type & SLJIT_SIMD_LANE_ZERO) || lane_index > 0) + FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | ((sljit_ins)(lane_index + 1) << 15))); + + if (type & SLJIT_SIMD_FLOAT) { + FAIL_IF(push_inst(compiler, VFMV_SF | VRD(lane_index > 0 ? TMP_VREG1 : vreg) | FRS1(srcdst))); + + if (lane_index == 0) + return SLJIT_SUCCESS; + + return push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1)); + } + + if (srcdst == SLJIT_IMM) { + srcdstw = sljit_simd_get_imm(elem_size, srcdstw); + FAIL_IF(load_immediate(compiler, TMP_REG1, srcdstw, TMP_REG3)); + srcdst = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, VMV_SX | VRD(lane_index > 0 ? TMP_VREG1 : vreg) | RS1(srcdst))); + + if (lane_index == 0) + return SLJIT_SUCCESS; + + return push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 vreg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); + + FAIL_IF(push_inst(compiler, VRGATHER_VI | VRD(vreg != src ? vreg : TMP_VREG1) | ((sljit_ins)src_lane_index << 15) | VRS2(src))); + if (vreg == src) + return push_inst(compiler, VMV_VV | VRD(vreg) | VRS1(TMP_VREG1)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 vreg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) + return SLJIT_ERR_UNSUPPORTED; +#else /* !SLJIT_CONFIG_RISCV_32 */ + if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_RISCV_32 */ + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if ((src & SLJIT_MEM) || vreg == src) { + ins = (sljit_ins)1 << (reg_size - elem2_size); + FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (ins << 15))); + + if (src & SLJIT_MEM) + FAIL_IF(sljit_emit_vmem(compiler, VL | VRD(TMP_VREG1), elem_size, src, srcw)); + else + FAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG1) | VRS1(src))); + + src = TMP_VREG1; + } + + if (type & SLJIT_SIMD_FLOAT) { + FAIL_IF(sljit_emit_vsetivli(compiler, type, 0x7)); + return push_inst(compiler, VFWCVT_FFV | VRD(vreg) | VRS2(src)); + } + + ins = (sljit_ins)1 << (reg_size - elem2_size); + FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem2_size << 23) | (ins << 15))); + + switch (elem2_size - elem_size) { + case 1: + ins = VZEXT_VF2; + break; + case 2: + ins = VZEXT_VF4; + break; + default: + ins = VZEXT_VF8; + break; + } + + if (type & SLJIT_SIMD_EXTEND_SIGNED) + ins |= 1 << 15; + + return push_inst(compiler, ins | VRD(vreg) | VRS2(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 vreg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) + return SLJIT_ERR_UNSUPPORTED; + + FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); + FAIL_IF(push_inst(compiler, VMV_VI | VRD(TMP_VREG1) | (0x0 << 15))); + FAIL_IF(push_inst(compiler, VMSLE_VI | VRD(TMP_VREG1) | (0x0 << 15) | VRS2(vreg))); + + FAIL_IF(sljit_emit_vsetivli_size(compiler, 2, 2)); + FAIL_IF(push_inst(compiler, VMV_XS | RD(dst_r) | VRS2(TMP_VREG1))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, (type & SLJIT_32) ? INT_DATA : WORD_DATA, dst_r, dst, dstw); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + + ADJUST_LOCAL_OFFSET(src2, src2w); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = VAND_VV; + break; + case SLJIT_SIMD_OP2_OR: + ins = VOR_VV; + break; + case SLJIT_SIMD_OP2_XOR: + ins = VXOR_VV; + break; + case SLJIT_SIMD_OP2_SHUFFLE: + ins = VRGATHER_VV; + elem_size = 0; + break; + } + + if (elem_size > 3) + elem_size = 3; + + FAIL_IF(sljit_emit_vsetivli_size(compiler, reg_size, elem_size)); + + if (src2 & SLJIT_MEM) { + FAIL_IF(sljit_emit_vmem(compiler, VL | VRD(TMP_VREG1), elem_size, src2, src2w)); + src2 = TMP_VREG1; + } + + if (SLJIT_SIMD_GET_OPCODE(type) != SLJIT_SIMD_OP2_SHUFFLE) + return push_inst(compiler, ins | VRD(dst_vreg) | VRS1(src1_vreg) | VRS2(src2)); + + if (dst_vreg == src2) { + FAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG1) | VRS1(src2))); + src2 = TMP_VREG1; + } + + if (dst_vreg == src1_vreg) { + FAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG2) | VRS1(src1_vreg))); + src1_vreg = TMP_VREG2; + } + + return push_inst(compiler, ins | VRD(dst_vreg) | VRS1(src2) | VRS2(src1_vreg)); +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c b/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c index 99e846350fdd6..7ce9f9fcdcc58 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c @@ -1638,6 +1638,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F64: case SLJIT_HAS_SIMD: case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: return 1; case SLJIT_HAS_CTZ: @@ -1660,19 +1661,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_s32 offset, i, tmp; CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); /* Saved registers are stored in callee allocated save area. */ SLJIT_ASSERT(gpr(SLJIT_FIRST_SAVED_REG) == r6 && gpr(SLJIT_S0) == r13); + scratches = ENTER_GET_REGS(scratches); + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; + offset = 2 * SSIZE_OF(sw); if (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) { if (saved_arg_count == 0) { @@ -1756,12 +1764,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); compiler->local_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf; return SLJIT_SUCCESS; @@ -1923,7 +1931,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return SLJIT_SUCCESS; case SLJIT_DIV_S32: case SLJIT_DIVMOD_S32: - FAIL_IF(push_inst(compiler, lhi(tmp0, 0))); + FAIL_IF(push_inst(compiler, 0xeb00000000dc /* srak */ | R36A(tmp0) | R32A(arg0) | (31 << 16))); FAIL_IF(push_inst(compiler, lr(tmp1, arg0))); FAIL_IF(push_inst(compiler, dr(tmp0, arg1))); FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */ @@ -1950,6 +1958,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */ return SLJIT_SUCCESS; + case SLJIT_MEMORY_BARRIER: + return push_inst(compiler, 0x0700 /* bcr */ | (0xe << 4) | 0); case SLJIT_ENDBR: return SLJIT_SUCCESS; case SLJIT_SKIP_FRAMES_BEFORE_RETURN: @@ -2475,14 +2485,9 @@ static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op, ins = (op & SLJIT_32) ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */; return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); } - } - else { - if ((op & SLJIT_32) || is_u32(src2w)) { - ins = (op & SLJIT_32) ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */; - return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); - } - if (is_s16(src2w)) - return emit_rie_d(compiler, 0xec00000000db /* alghsik */, (sljit_s32)tmp0, src1, src1w, src2w); + } else if ((op & SLJIT_32) || is_u32(src2w)) { + ins = (op & SLJIT_32) ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */; + return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); } } else if (src2 & SLJIT_MEM) { @@ -3182,7 +3187,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_GP_REGISTER) return (sljit_s32)gpr(reg); - if (type != SLJIT_FLOAT_REGISTER) + if (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128) return -1; return (sljit_s32)freg_map[reg]; @@ -3934,7 +3939,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3944,7 +3949,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3959,15 +3964,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (!(srcdst & SLJIT_MEM)) { if (type & SLJIT_SIMD_STORE) - ins = F36(srcdst) | F32(freg); + ins = F36(srcdst) | F32(vreg); else - ins = F36(freg) | F32(srcdst); + ins = F36(vreg) | F32(srcdst); return push_inst(compiler, 0xe70000000056 /* vlr */ | ins); } FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); - ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + ins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); if (alignment >= 4) ins |= 4 << 12; @@ -3978,7 +3983,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3988,7 +3993,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_sw sign_ext; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4003,15 +4008,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (src & SLJIT_MEM) { FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); - return push_inst(compiler, 0xe70000000005 /* vlrep */ | F36(freg) + return push_inst(compiler, 0xe70000000005 /* vlrep */ | F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset) | ((sljit_ins)elem_size << 12)); } if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) - return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg)); + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg)); - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) | ((sljit_ins)elem_size << 12)); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(src) | ((sljit_ins)elem_size << 12)); } if (src == SLJIT_IMM) { @@ -4043,10 +4048,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (sign_ext != 0x10000) { if (sign_ext == 0 || sign_ext == -1) - return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg) + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg) | (sign_ext == 0 ? 0 : ((sljit_ins)0xffff << 16))); - return push_inst(compiler, 0xe70000000045 /* vrepi */ | F36(freg) + return push_inst(compiler, 0xe70000000045 /* vrepi */ | F36(vreg) | ((sljit_ins)srcw << 16) | ((sljit_ins)elem_size << 12)); } @@ -4055,12 +4060,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil } else reg = gpr(src); - FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ((sljit_ins)elem_size << 12))); - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(freg) | ((sljit_ins)elem_size << 12)); + FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(reg) | ((sljit_ins)elem_size << 12))); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(vreg) | ((sljit_ins)elem_size << 12)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4070,7 +4075,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -4085,20 +4090,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (srcdst & SLJIT_MEM) { FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); - ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + ins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); } if (type & SLJIT_SIMD_LANE_ZERO) { if ((srcdst & SLJIT_MEM) && lane_index == ((1 << (3 - elem_size)) - 1)) return push_inst(compiler, 0xe70000000004 /* vllez */ | ins | ((sljit_ins)elem_size << 12)); - if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { - FAIL_IF(push_inst(compiler, 0xe70000000056 /* vlr */ | F36(TMP_FREG1) | F32(freg))); + if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { + FAIL_IF(push_inst(compiler, 0xe70000000056 /* vlr */ | F36(TMP_FREG1) | F32(vreg))); srcdst = TMP_FREG1; srcdstw = 0; } - FAIL_IF(push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg))); + FAIL_IF(push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg))); } if (srcdst & SLJIT_MEM) { @@ -4126,19 +4131,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_FLOAT) { if (type & SLJIT_SIMD_STORE) - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(srcdst) | F32(freg) | ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12)); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(srcdst) | F32(vreg) | ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12)); if (elem_size == 3) { if (lane_index == 0) - ins = F32(srcdst) | F28(freg) | (1 << 12); + ins = F32(srcdst) | F28(vreg) | (1 << 12); else - ins = F32(freg) | F28(srcdst); + ins = F32(vreg) | F28(srcdst); - return push_inst(compiler, 0xe70000000084 /* vpdi */ | F36(freg) | ins); + return push_inst(compiler, 0xe70000000084 /* vpdi */ | F36(vreg) | ins); } FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(tmp0) | F32(srcdst) | ((sljit_ins)2 << 12))); - return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(tmp0) | ((sljit_ins)lane_index << 16) | ((sljit_ins)2 << 12)); + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(tmp0) | ((sljit_ins)lane_index << 16) | ((sljit_ins)2 << 12)); } if (srcdst == SLJIT_IMM) { @@ -4167,7 +4172,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } if (ins != 0) - return push_inst(compiler, ins | F36(freg) | ((sljit_ins)srcdstw << 16) | ((sljit_ins)lane_index << 12)); + return push_inst(compiler, ins | F36(vreg) | ((sljit_ins)srcdstw << 16) | ((sljit_ins)lane_index << 12)); push_load_imm_inst(compiler, tmp0, srcdstw); reg = tmp0; @@ -4177,9 +4182,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins = ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12); if (!(type & SLJIT_SIMD_STORE)) - return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ins); + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(reg) | ins); - FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(reg) | F32(freg) | ins)); + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(reg) | F32(vreg) | ins)); if (!(type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3) return SLJIT_SUCCESS; @@ -4200,14 +4205,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); if (reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4218,12 +4223,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (type & SLJIT_SIMD_TEST) return SLJIT_SUCCESS; - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(src) | ((sljit_ins)src_lane_index << 16) | ((sljit_ins)elem_size << 12)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4233,7 +4238,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4248,7 +4253,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler if (src & SLJIT_MEM) { FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); - ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + ins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); switch (elem2_size - elem_size) { case 1: @@ -4263,27 +4268,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } FAIL_IF(push_inst(compiler, ins)); - src = freg; + src = vreg; } if (type & SLJIT_SIMD_FLOAT) { - FAIL_IF(push_inst(compiler, 0xe700000000d5 /* vuplh */ | F36(freg) | F32(src) | (2 << 12))); - FAIL_IF(push_inst(compiler, 0xe70000000030 /* vesl */ | F36(freg) | F32(freg) | (32 << 16) | (3 << 12))); - return push_inst(compiler, 0xe700000000c4 /* vfll */ | F36(freg) | F32(freg) | (2 << 12)); + FAIL_IF(push_inst(compiler, 0xe700000000d5 /* vuplh */ | F36(vreg) | F32(src) | (2 << 12))); + FAIL_IF(push_inst(compiler, 0xe70000000030 /* vesl */ | F36(vreg) | F32(vreg) | (32 << 16) | (3 << 12))); + return push_inst(compiler, 0xe700000000c4 /* vfll */ | F36(vreg) | F32(vreg) | (2 << 12)); } - ins = ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0xe700000000d7 /* vuph */ : 0xe700000000d5 /* vuplh */) | F36(freg); + ins = ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0xe700000000d7 /* vuph */ : 0xe700000000d5 /* vuplh */) | F36(vreg); do { FAIL_IF(push_inst(compiler, ins | F32(src) | ((sljit_ins)elem_size << 12))); - src = freg; + src = vreg; } while (++elem_size < elem2_size); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4291,7 +4296,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_gpr dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4324,7 +4329,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c if (elem_size != 0) FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(TMP_FREG1) | R32A(tmp0) | (1 << 16) | (3 << 12))); - FAIL_IF(push_inst(compiler, 0xe70000000085 /* vbperm */ | F36(TMP_FREG1) | F32(freg) | F28(TMP_FREG1))); + FAIL_IF(push_inst(compiler, 0xe70000000085 /* vbperm */ | F36(TMP_FREG1) | F32(vreg) | F28(TMP_FREG1))); dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(dst_r) | F32(TMP_FREG1) @@ -4337,14 +4342,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_ins ins = 0; + sljit_s32 alignment; + struct addr addr; + sljit_ins ins = 0, load_ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + ADJUST_LOCAL_OFFSET(src2, src2w); if (reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4365,12 +4373,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = 0xe7000000006d /* vx */; break; + case SLJIT_SIMD_OP2_SHUFFLE: + ins = 0xe7000000008c /* vperm */; + break; } - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; + if (src2 & SLJIT_MEM) { + FAIL_IF(make_addr_bx(compiler, &addr, src2, src2w, tmp1)); + load_ins = 0xe70000000006 /* vl */ | F36(TMP_FREG1) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + + if (alignment >= 4) + load_ins |= 4 << 12; + else if (alignment == 3) + load_ins |= 3 << 12; + + FAIL_IF(push_inst(compiler, load_ins)); + src2 = TMP_FREG1; + } + + if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) + return push_inst(compiler, ins | F36(dst_vreg) | F32(src1_vreg) | F28(src1_vreg) | F12(src2)); - return push_inst(compiler, ins | F36(dst_freg) | F32(src1_freg) | F28(src2_freg)); + return push_inst(compiler, ins | F36(dst_vreg) | F32(src1_vreg) | F28(src2)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, @@ -4380,8 +4405,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); + if (op & SLJIT_ATOMIC_USE_LS) + return SLJIT_ERR_UNSUPPORTED; + + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + case SLJIT_MOV: + case SLJIT_MOV_P: + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_op1(compiler, op & ~SLJIT_ATOMIC_USE_CAS, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); + default: + return SLJIT_ERR_UNSUPPORTED; + } } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, @@ -4389,44 +4428,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler sljit_s32 mem_reg, sljit_s32 temp_reg) { - sljit_ins mask; + sljit_ins ins; sljit_gpr tmp_r = gpr(temp_reg); sljit_gpr mem_r = gpr(mem_reg); CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + if (op & SLJIT_ATOMIC_USE_LS) + return SLJIT_ERR_UNSUPPORTED; + switch (GET_OPCODE(op)) { case SLJIT_MOV32: case SLJIT_MOV_U32: - return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp_r) | R16A(gpr(src_reg)) | R12A(mem_r)); - case SLJIT_MOV_U8: - mask = 0xff; + ins = 0xba000000 /* cs */ | R20A(tmp_r) | R16A(gpr(src_reg)) | R12A(mem_r); break; - case SLJIT_MOV_U16: - mask = 0xffff; + case SLJIT_MOV: + case SLJIT_MOV_P: + ins = 0xeb0000000030 /* csg */ | R36A(tmp_r) | R32A(gpr(src_reg)) | R28A(mem_r); break; default: - return push_inst(compiler, 0xeb0000000030 /* csg */ | R36A(tmp_r) | R32A(gpr(src_reg)) | R28A(mem_r)); + return SLJIT_ERR_UNSUPPORTED; } - /* tmp0 = (src_reg ^ tmp_r) & mask */ - FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | mask)); - FAIL_IF(push_inst(compiler, 0xb9e70000 /* xgrk */ | R4A(tmp0) | R0A(gpr(src_reg)) | R12A(tmp_r))); - FAIL_IF(push_inst(compiler, 0xa7090000 /* lghi */ | R20A(tmp_r) | 0xfffc)); - FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp0) | R0A(tmp1))); - - /* tmp0 = tmp0 << (((mem_r ^ 0x3) & 0x3) << 3) */ - FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | (sljit_ins)((mask == 0xff) ? 0x18 : 0x10))); - FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp_r) | R0A(mem_r))); - FAIL_IF(push_inst(compiler, 0xec0000000057 /* rxsbg */ | R36A(tmp1) | R32A(mem_r) | (59 << 24) | (60 << 16) | (3 << 8))); - FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp0) | R32A(tmp0) | R28A(tmp1))); - - /* Already computed: tmp_r = mem_r & ~0x3 */ + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, 0x58000000 /* l */ | R20A(tmp1) | R12A(tmp_r))); - FAIL_IF(push_inst(compiler, 0x1700 /* x */ | R4A(tmp0) | R0A(tmp1))); - return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp1) | R16A(tmp0) | R12A(tmp_r)); + return push_inst(compiler, ins); } /* --------------------------------------------------------------------- */ diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c index 59ea04a5c81b1..217a1498abe18 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c @@ -311,8 +311,8 @@ static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_pt #define ENTER_TMP_TO_S 0x00002 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { sljit_s32 word_arg_count, saved_arg_count, float_arg_count; sljit_s32 size, args_size, types, status; @@ -323,8 +323,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); /* Emit ENDBR32 at function entry if needed. */ FAIL_IF(emit_endbranch(compiler)); @@ -536,14 +538,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { sljit_s32 args_size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); arg_types >>= SLJIT_ARG_SHIFT; args_size = 0; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c index 1ab79293c7efc..e4d3db828fa09 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c @@ -454,14 +454,16 @@ typedef struct { #endif /* _WIN64 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { sljit_uw size; sljit_s32 word_arg_count = 0; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_s32 saved_regs_size, tmp, i; #ifdef _WIN64 + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 saved_float_regs_size; sljit_s32 saved_float_regs_offset = 0; sljit_s32 float_arg_count = 0; @@ -469,8 +471,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi sljit_u8 *inst; CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); +#ifdef _WIN64 + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; +#endif /* _WIN64 */ if (options & SLJIT_ENTER_REG_ARG) arg_types = 0; @@ -630,19 +639,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, + sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) { sljit_s32 saved_regs_size; #ifdef _WIN64 + sljit_s32 fscratches; + sljit_s32 fsaveds; sljit_s32 saved_float_regs_size; #endif /* _WIN64 */ CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); - set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + + scratches = ENTER_GET_REGS(scratches); #ifdef _WIN64 + saveds = ENTER_GET_REGS(saveds); + fscratches = compiler->fscratches; + fsaveds = compiler->fsaveds; + local_size += SLJIT_LOCALS_OFFSET; saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c index ecb7e9be3b0e0..9f599d5fb0899 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c @@ -239,6 +239,7 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { #define MOVDDUP_x_xm 0x12 #define MOVDQA_x_xm 0x6f #define MOVDQA_xm_x 0x7f +#define MOVDQU_x_xm 0x6f #define MOVHLPS_x_x 0x12 #define MOVHPD_m_x 0x17 #define MOVHPD_x_m 0x16 @@ -398,6 +399,13 @@ static sljit_u32 cpu_feature_list = 0; #include #elif defined(_MSC_VER) && _MSC_VER >= 1400 #include +#elif defined(__INTEL_COMPILER) +#include +#endif + +#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__INTEL_COMPILER) \ + || (defined(__INTEL_LLVM_COMPILER) && defined(__XSAVE__)) +#include #endif /******************************************************/ @@ -425,49 +433,20 @@ static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value) static void execute_cpu_id(sljit_u32 info[4]) { -#if defined(_MSC_VER) && _MSC_VER >= 1400 +#if (defined(_MSC_VER) && _MSC_VER >= 1400) \ + || (defined(__INTEL_COMPILER) && __INTEL_COMPILER == 2021 && __INTEL_COMPILER_UPDATE >= 7) __cpuidex((int*)info, (int)info[0], (int)info[2]); -#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__TINYC__) +#elif (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900) - /* AT&T syntax. */ - __asm__ ( -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - "movl %0, %%esi\n" - "movl (%%esi), %%eax\n" - "movl 8(%%esi), %%ecx\n" - "pushl %%ebx\n" - "cpuid\n" - "movl %%eax, (%%esi)\n" - "movl %%ebx, 4(%%esi)\n" - "popl %%ebx\n" - "movl %%ecx, 8(%%esi)\n" - "movl %%edx, 12(%%esi)\n" -#else /* !SLJIT_CONFIG_X86_32 */ - "movq %0, %%rsi\n" - "movl (%%rsi), %%eax\n" - "movl 8(%%rsi), %%ecx\n" - "cpuid\n" - "movl %%eax, (%%rsi)\n" - "movl %%ebx, 4(%%rsi)\n" - "movl %%ecx, 8(%%rsi)\n" - "movl %%edx, 12(%%rsi)\n" -#endif /* SLJIT_CONFIG_X86_32 */ - : - : "r" (info) -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "memory", "eax", "ecx", "edx", "esi" -#else /* !SLJIT_CONFIG_X86_32 */ - : "memory", "rax", "rbx", "rcx", "rdx", "rsi" -#endif /* SLJIT_CONFIG_X86_32 */ - ); + __get_cpuid_count(info[0], info[2], info, info + 1, info + 2, info + 3); -#else /* _MSC_VER < 1400 */ +#elif (defined(_MSC_VER) || defined(__INTEL_COMPILER)) \ + && (defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32) /* Intel syntax. */ __asm { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) mov esi, info mov eax, [esi] mov ecx, [esi + 8] @@ -476,30 +455,48 @@ static void execute_cpu_id(sljit_u32 info[4]) mov [esi + 4], ebx mov [esi + 8], ecx mov [esi + 12], edx -#else /* !SLJIT_CONFIG_X86_32 */ - mov rsi, info - mov eax, [rsi] - mov ecx, [rsi + 8] - cpuid - mov [rsi], eax - mov [rsi + 4], ebx - mov [rsi + 8], ecx - mov [rsi + 12], edx -#endif /* SLJIT_CONFIG_X86_32 */ } -#endif /* _MSC_VER && _MSC_VER >= 1400 */ +#else + + __asm__ __volatile__ ( + "cpuid\n" + : "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3]) + : "0" (info[0]), "2" (info[2]) + ); + +#endif } static sljit_u32 execute_get_xcr0_low(void) { sljit_u32 xcr0; -#if defined(_MSC_VER) && _MSC_VER >= 1400 +#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__INTEL_COMPILER) \ + || (defined(__INTEL_LLVM_COMPILER) && defined(__XSAVE__)) xcr0 = (sljit_u32)_xgetbv(0); -#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__TINYC__) +#elif defined(__TINYC__) + + __asm__ ( + "xorl %%ecx, %%ecx\n" + ".byte 0x0f\n" + ".byte 0x01\n" + ".byte 0xd0\n" + : "=a" (xcr0) + : +#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 + : "ecx", "edx" +#else /* !SLJIT_CONFIG_X86_32 */ + : "rcx", "rdx" +#endif /* SLJIT_CONFIG_X86_32 */ + ); + +#elif (defined(__INTEL_LLVM_COMPILER) && __INTEL_LLVM_COMPILER < 20220100) \ + || (defined(__clang__) && __clang_major__ < 14) \ + || (defined(__GNUC__) && __GNUC__ < 3) \ + || defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* AT&T syntax. */ __asm__ ( @@ -507,23 +504,37 @@ static sljit_u32 execute_get_xcr0_low(void) "xgetbv\n" : "=a" (xcr0) : -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 : "ecx", "edx" #else /* !SLJIT_CONFIG_X86_32 */ : "rcx", "rdx" #endif /* SLJIT_CONFIG_X86_32 */ ); -#else /* _MSC_VER < 1400 */ +#elif defined(_MSC_VER) /* Intel syntax. */ __asm { - mov ecx, 0 + xor ecx, ecx xgetbv mov xcr0, eax } -#endif /* _MSC_VER && _MSC_VER >= 1400 */ +#else + + __asm__ ( + "xor{l %%ecx, %%ecx | ecx, ecx}\n" + "xgetbv\n" + : "=a" (xcr0) + : +#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 + : "ecx", "edx" +#else /* !SLJIT_CONFIG_X86_32 */ + : "rcx", "rdx" +#endif /* SLJIT_CONFIG_X86_32 */ + ); + +#endif return xcr0; } @@ -549,6 +560,10 @@ static void get_cpu_features(void) if (max_id >= 1) { info[0] = 1; +#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 + /* Winchip 2 and Cyrix MII bugs */ + info[1] = info[2] = 0; +#endif execute_cpu_id(info); if (info[2] & 0x80000) @@ -565,11 +580,17 @@ static void get_cpu_features(void) feature_list |= CPU_FEATURE_CMOV; } - info[0] = 0x80000001; + info[0] = 0x80000000; execute_cpu_id(info); + max_id = info[0]; + + if (max_id >= 0x80000001) { + info[0] = 0x80000001; + execute_cpu_id(info); - if (info[2] & 0x20) - feature_list |= CPU_FEATURE_LZCNT; + if (info[2] & 0x20) + feature_list |= CPU_FEATURE_LZCNT; + } if ((feature_list & CPU_FEATURE_OSXSAVE) && (execute_get_xcr0_low() & 0x4) == 0) feature_list &= ~(sljit_u32)(CPU_FEATURE_AVX | CPU_FEATURE_AVX2); @@ -659,18 +680,23 @@ static sljit_u8* detect_near_jump_type(struct sljit_jump *jump, sljit_u8 *code_p sljit_uw type = jump->flags >> TYPE_SHIFT; sljit_s32 short_jump; sljit_uw label_addr; + sljit_uw jump_addr; - if (jump->flags & JUMP_ADDR) - label_addr = jump->u.target - (sljit_uw)executable_offset; - else + jump_addr = (sljit_uw)code_ptr; + if (!(jump->flags & JUMP_ADDR)) { label_addr = (sljit_uw)(code + jump->u.label->size); + if (jump->u.label->size > jump->addr) + jump_addr = (sljit_uw)(code + jump->addr); + } else + label_addr = jump->u.target - (sljit_uw)executable_offset; + #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((sljit_sw)(label_addr - (sljit_uw)(code_ptr + 6)) > HALFWORD_MAX || (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 5)) < HALFWORD_MIN) + if ((sljit_sw)(label_addr - (jump_addr + 6)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump_addr + 5)) < HALFWORD_MIN) return detect_far_jump_type(jump, code_ptr); #endif /* SLJIT_CONFIG_X86_64 */ - short_jump = (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 2)) >= -0x80 && (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 2)) <= 0x7f; + short_jump = (sljit_sw)(label_addr - (jump_addr + 2)) >= -0x80 && (sljit_sw)(label_addr - (jump_addr + 2)) <= 0x7f; if (type == SLJIT_JUMP) { if (short_jump) @@ -792,6 +818,7 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (next_min_addr != next_jump_addr) continue; + jump->addr -= size_reduce; if (!(jump->flags & JUMP_MOV_ADDR)) { #if (defined SLJIT_DEBUG && SLJIT_DEBUG) size_reduce_max = size_reduce + (((jump->flags >> TYPE_SHIFT) < SLJIT_JUMP) ? CJUMP_MAX_SIZE : JUMP_MAX_SIZE); @@ -805,7 +832,11 @@ static void reduce_code_size(struct sljit_compiler *compiler) #endif /* SLJIT_CONFIG_X86_64 */ } else { /* Unit size: instruction. */ - diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - size_reduce); + diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; + if (jump->u.label->size > jump->addr) { + SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); + diff -= (sljit_sw)size_reduce; + } type = jump->flags >> TYPE_SHIFT; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -845,7 +876,7 @@ static void reduce_code_size(struct sljit_compiler *compiler) #endif /* SLJIT_DEBUG */ if (!(jump->flags & JUMP_ADDR)) { - diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - size_reduce - 3); + diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - 3); if (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN) size_reduce += 3; @@ -1017,6 +1048,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: + case SLJIT_HAS_MEMORY_BARRIER: return 1; #if !(defined SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE @@ -1476,6 +1508,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); #endif break; + case SLJIT_MEMORY_BARRIER: + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + inst[0] = GROUP_0F; + inst[1] = 0xae; + inst[2] = 0xf0; + return SLJIT_SUCCESS; case SLJIT_ENDBR: return emit_endbranch(compiler); case SLJIT_SKIP_FRAMES_BEFORE_RETURN: @@ -3466,6 +3506,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_u8 cond_set; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) sljit_s32 reg; + sljit_uw size; #endif /* !SLJIT_CONFIG_X86_64 */ /* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */ sljit_s32 dst_save = dst; @@ -3482,35 +3523,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst)) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3); + size = 3 + 2; + if (reg_map[TMP_REG1] >= 4) + size += 1 + 1; + else if (reg_map[dst] >= 4) + size++; + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); - INC_SIZE(4 + 3); + INC_SIZE(size); /* Set low register to conditional flag. */ - inst[0] = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; - inst[1] = GROUP_0F; - inst[2] = cond_set; - inst[3] = MOD_REG | reg_lmap[TMP_REG1]; - inst[4] = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); - inst[5] = OR_rm8_r8; - inst[6] = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); + if (reg_map[TMP_REG1] >= 4) + *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; + + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = MOD_REG | reg_lmap[TMP_REG1]; + inst += 3; + + if (reg_map[TMP_REG1] >= 4 || reg_map[dst] >= 4) + *inst++ = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); + + inst[0] = OR_rm8_r8; + inst[1] = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); return SLJIT_SUCCESS; } reg = (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG1; - inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4); + size = 3 + (reg_map[reg] >= 4) + 4; + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); - INC_SIZE(4 + 4); + INC_SIZE(size); /* Set low register to conditional flag. */ - inst[0] = (reg_map[reg] <= 7) ? REX : REX_B; - inst[1] = GROUP_0F; - inst[2] = cond_set; - inst[3] = MOD_REG | reg_lmap[reg]; - inst[4] = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + + if (reg_map[reg] >= 4) + *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; + + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = MOD_REG | reg_lmap[reg]; + + inst[3] = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); /* The movzx instruction does not affect flags. */ - inst[5] = GROUP_0F; - inst[6] = MOVZX_r_rm8; - inst[7] = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); + inst[4] = GROUP_0F; + inst[5] = MOVZX_r_rm8; + inst[6] = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); if (reg != TMP_REG1) return SLJIT_SUCCESS; @@ -3617,7 +3675,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3626,7 +3684,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_uw op; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3670,13 +3728,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co return SLJIT_SUCCESS; if ((op & VEX_256) || ((cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX))) - return emit_vex_instruction(compiler, op, freg, 0, srcdst, srcdstw); + return emit_vex_instruction(compiler, op, vreg, 0, srcdst, srcdstw); - return emit_groupf(compiler, op, freg, srcdst, srcdstw); + return emit_groupf(compiler, op, vreg, srcdst, srcdstw); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3687,7 +3745,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_uw op; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3753,48 +3811,48 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (elem_size >= 3) compiler->mode32 = 0; #endif /* SLJIT_CONFIG_X86_64 */ - FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw)); + FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; #endif /* SLJIT_CONFIG_X86_64 */ - src = freg; + src = vreg; srcw = 0; } if (reg_size == 5) op |= VEX_256; - return emit_vex_instruction(compiler, op, freg, 0, src, srcw); + return emit_vex_instruction(compiler, op, vreg, 0, src, srcw); } } if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) { if (use_vex) - return emit_vex_instruction(compiler, XORPD_x_xm | (reg_size == 5 ? VEX_256 : 0) | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); + return emit_vex_instruction(compiler, XORPD_x_xm | (reg_size == 5 ? VEX_256 : 0) | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0); - return emit_groupf(compiler, XORPD_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2, freg, freg, 0); + return emit_groupf(compiler, XORPD_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2, vreg, vreg, 0); } SLJIT_ASSERT(reg_size == 4); if (use_vex) { if (elem_size == 3) - return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, src, srcw); + return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, src, srcw); SLJIT_ASSERT(!(src & SLJIT_MEM)); - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, vreg, src, src, 0)); return emit_byte(compiler, 0); } - if (elem_size == 2 && freg != src) { - FAIL_IF(emit_sse2_load(compiler, 1, freg, src, srcw)); - src = freg; + if (elem_size == 2 && vreg != src) { + FAIL_IF(emit_sse2_load(compiler, 1, vreg, src, srcw)); + src = vreg; srcw = 0; } op = (elem_size == 2 ? SHUFPS_x_xm : MOVDDUP_x_xm) | (elem_size == 2 ? 0 : EX86_PREF_F2) | EX86_SSE2; - FAIL_IF(emit_groupf(compiler, op, freg, src, srcw)); + FAIL_IF(emit_groupf(compiler, op, vreg, src, srcw)); if (elem_size == 2) return emit_byte(compiler, 0); @@ -3820,9 +3878,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (srcw == 0 || srcw == -1) { if (use_vex) - return emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); + return emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0); - return emit_groupf(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | EX86_PREF_66 | EX86_SSE2, freg, freg, 0); + return emit_groupf(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0); } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -3864,11 +3922,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (use_vex) { if (opcode != MOVD_x_rm) { op = (opcode == 0x3a) ? (PINSRB_x_rm_i8 | VEX_OP_0F3A) : opcode; - FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1 | VEX_SSE2_OPV, freg, freg, src, srcw)); + FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1 | VEX_SSE2_OPV, vreg, vreg, src, srcw)); } else - FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw)); + FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw)); } else { - inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw); + inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw); FAIL_IF(!inst); inst[0] = GROUP_0F; inst[1] = opcode; @@ -3879,13 +3937,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil } } - if (use_vex && elem_size >= 2) { + if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && elem_size >= 2) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) op = VPBROADCASTD_x_xm; #else /* !SLJIT_CONFIG_X86_32 */ op = (elem_size == 3) ? VPBROADCASTQ_x_xm : VPBROADCASTD_x_xm; #endif /* SLJIT_CONFIG_X86_32 */ - return emit_vex_instruction(compiler, op | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + return emit_vex_instruction(compiler, op | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0); } SLJIT_ASSERT(reg_size == 4); @@ -3897,37 +3955,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil case 0: if (use_vex) { FAIL_IF(emit_vex_instruction(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0)); - return emit_vex_instruction(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, TMP_FREG, 0); + return emit_vex_instruction(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, TMP_FREG, 0); } FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); - return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, TMP_FREG, 0); case 1: if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, vreg, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, freg, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, vreg, 0)); FAIL_IF(emit_byte(compiler, 0)); /* fallthrough */ default: if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, vreg, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0)); return emit_byte(compiler, 0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) case 3: compiler->mode32 = 1; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, vreg, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0)); return emit_byte(compiler, 0x44); #endif /* SLJIT_CONFIG_X86_64 */ } } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 vreg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3936,7 +3994,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_u8 *inst; sljit_u8 opcode = 0; sljit_uw op; - sljit_s32 freg_orig = freg; + sljit_s32 vreg_orig = vreg; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) sljit_s32 srcdst_is_ereg = 0; sljit_s32 srcdst_orig = 0; @@ -3944,7 +4002,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile #endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -4004,29 +4062,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (elem_size == 2) { if (use_vex) - return emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); - return emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, srcdst, srcdstw); + return emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, vreg, srcdst, srcdstw); } } else if (srcdst & SLJIT_MEM) { SLJIT_ASSERT(elem_size == 2 || elem_size == 3); if (use_vex) - return emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, 0, srcdst, srcdstw); - return emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, vreg, 0, srcdst, srcdstw); + return emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, vreg, srcdst, srcdstw); } else if (elem_size == 3) { if (use_vex) - return emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, 0, srcdst, 0); - return emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, srcdst, 0); + return emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, vreg, 0, srcdst, 0); + return emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, vreg, srcdst, 0); } else if (use_vex) { FAIL_IF(emit_vex_instruction(compiler, XORPD_x_xm | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0)); - return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F3 | EX86_SSE2 | VEX_SSE2_OPV, freg, TMP_FREG, srcdst, 0); + return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F3 | EX86_SSE2 | VEX_SSE2_OPV, vreg, TMP_FREG, srcdst, 0); } } if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { - freg = TMP_FREG; + vreg = TMP_FREG; lane_index -= (1 << (4 - elem_size)); - } else if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + } else if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { if (use_vex) FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, srcdst, srcdstw)); else @@ -4039,14 +4097,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile | ((type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm) | EX86_SSE2; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, op | (reg_size == 5 ? VEX_256 : 0) | VEX_SSE2_OPV, freg, freg, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, op | (reg_size == 5 ? VEX_256 : 0) | VEX_SSE2_OPV, vreg, vreg, vreg, 0)); else - FAIL_IF(emit_groupf(compiler, op, freg, freg, 0)); + FAIL_IF(emit_groupf(compiler, op, vreg, vreg, 0)); } else if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { - FAIL_IF(emit_vex_instruction(compiler, ((type & SLJIT_SIMD_FLOAT) ? VEXTRACTF128_x_ym : VEXTRACTI128_x_ym) | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, ((type & SLJIT_SIMD_FLOAT) ? VEXTRACTF128_x_ym : VEXTRACTI128_x_ym) | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, TMP_FREG, 0)); FAIL_IF(emit_byte(compiler, 1)); - freg = TMP_FREG; + vreg = TMP_FREG; lane_index -= (1 << (4 - elem_size)); } @@ -4059,55 +4117,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile op = lane_index == 0 ? MOVLPD_x_m : MOVHPD_x_m; /* VEX prefix clears upper bits of the target register. */ - if (use_vex && ((type & SLJIT_SIMD_STORE) || reg_size == 4 || freg == TMP_FREG)) + if (use_vex && ((type & SLJIT_SIMD_STORE) || reg_size == 4 || vreg == TMP_FREG)) FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2 - | ((type & SLJIT_SIMD_STORE) ? 0 : VEX_SSE2_OPV), freg, (type & SLJIT_SIMD_STORE) ? 0 : freg, srcdst, srcdstw)); + | ((type & SLJIT_SIMD_STORE) ? 0 : VEX_SSE2_OPV), vreg, (type & SLJIT_SIMD_STORE) ? 0 : vreg, srcdst, srcdstw)); else - FAIL_IF(emit_groupf(compiler, op | EX86_PREF_66 | EX86_SSE2, freg, srcdst, srcdstw)); + FAIL_IF(emit_groupf(compiler, op | EX86_PREF_66 | EX86_SSE2, vreg, srcdst, srcdstw)); - /* In case of store, freg is not TMP_FREG. */ + /* In case of store, vreg is not TMP_FREG. */ } else if (type & SLJIT_SIMD_STORE) { if (lane_index == 1) { if (use_vex) - return emit_vex_instruction(compiler, MOVHLPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, freg, 0); - return emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, freg, 0); + return emit_vex_instruction(compiler, MOVHLPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, vreg, 0); + return emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, vreg, 0); } if (use_vex) - return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, freg, 0); - return emit_sse2_load(compiler, 0, srcdst, freg, 0); - } else if (use_vex && (reg_size == 4 || freg == TMP_FREG)) { + return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, vreg, 0); + return emit_sse2_load(compiler, 0, srcdst, vreg, 0); + } else if (use_vex && (reg_size == 4 || vreg == TMP_FREG)) { if (lane_index == 1) - FAIL_IF(emit_vex_instruction(compiler, MOVLHPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, srcdst, 0)); + FAIL_IF(emit_vex_instruction(compiler, MOVLHPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, srcdst, 0)); else - FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, srcdst, 0)); + FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, srcdst, 0)); } else { if (lane_index == 1) - FAIL_IF(emit_groupf(compiler, MOVLHPS_x_x | EX86_SSE2, freg, srcdst, 0)); + FAIL_IF(emit_groupf(compiler, MOVLHPS_x_x | EX86_SSE2, vreg, srcdst, 0)); else - FAIL_IF(emit_sse2_load(compiler, 0, freg, srcdst, 0)); + FAIL_IF(emit_sse2_load(compiler, 0, vreg, srcdst, 0)); } } else if (type & SLJIT_SIMD_STORE) { if (lane_index == 0) { if (use_vex) - return emit_vex_instruction(compiler, ((srcdst & SLJIT_MEM) ? MOVSD_xm_x : MOVSD_x_xm) | EX86_PREF_F3 | EX86_SSE2 - | ((srcdst & SLJIT_MEM) ? 0 : VEX_SSE2_OPV), freg, ((srcdst & SLJIT_MEM) ? 0 : freg), srcdst, srcdstw); - return emit_sse2_store(compiler, 1, srcdst, srcdstw, freg); + return emit_vex_instruction(compiler, MOVSD_xm_x | EX86_PREF_F3 | EX86_SSE2 | ((srcdst & SLJIT_MEM) ? 0 : VEX_SSE2_OPV), + vreg, ((srcdst & SLJIT_MEM) ? 0 : srcdst), srcdst, srcdstw); + return emit_sse2_store(compiler, 1, srcdst, srcdstw, vreg); } if (srcdst & SLJIT_MEM) { if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, srcdst, srcdstw)); + FAIL_IF(emit_vex_instruction(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, srcdst, srcdstw)); else - FAIL_IF(emit_groupf_ext(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); + FAIL_IF(emit_groupf_ext(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, srcdst, srcdstw)); return emit_byte(compiler, U8(lane_index)); } if (use_vex) { - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, srcdst, freg, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, srcdst, vreg, vreg, 0)); return emit_byte(compiler, U8(lane_index)); } - if (srcdst == freg) + if (srcdst == vreg) op = SHUFPS_x_xm | EX86_SSE2; else { switch (lane_index) { @@ -4124,7 +4182,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } } - FAIL_IF(emit_groupf(compiler, op, srcdst, freg, 0)); + FAIL_IF(emit_groupf(compiler, op, srcdst, vreg, 0)); op &= 0xff; if (op == SHUFPS_x_xm || op == PSHUFD_x_xm) @@ -4133,23 +4191,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile return SLJIT_SUCCESS; } else { if (lane_index != 0 || (srcdst & SLJIT_MEM)) { - FAIL_IF(emit_groupf_ext(compiler, INSERTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); + FAIL_IF(emit_groupf_ext(compiler, INSERTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, srcdst, srcdstw)); FAIL_IF(emit_byte(compiler, U8(lane_index << 4))); } else - FAIL_IF(emit_sse2_store(compiler, 1, freg, 0, srcdst)); + FAIL_IF(emit_sse2_store(compiler, 1, vreg, 0, srcdst)); } - if (freg != TMP_FREG || (type & SLJIT_SIMD_STORE)) + if (vreg != TMP_FREG || (type & SLJIT_SIMD_STORE)) return SLJIT_SUCCESS; SLJIT_ASSERT(reg_size == 5); if (type & SLJIT_SIMD_LANE_ZERO) { - FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg_orig, 0, TMP_FREG, 0)); return emit_byte(compiler, 0x4e); } - FAIL_IF(emit_vex_instruction(compiler, VINSERTF128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VINSERTF128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, vreg_orig, vreg_orig, TMP_FREG, 0)); return emit_byte(compiler, 1); } @@ -4186,9 +4244,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (use_vex && (type & SLJIT_SIMD_STORE)) { op = opcode | ((op == 3) ? VEX_OP_0F3A : 0); - FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | VEX_AUTO_W | EX86_SSE2_OP1 | VEX_SSE2_OPV, freg, 0, srcdst, srcdstw)); + FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | VEX_AUTO_W | EX86_SSE2_OP1 | VEX_SSE2_OPV, vreg, 0, srcdst, srcdstw)); } else { - inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); + inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, srcdst, srcdstw); FAIL_IF(!inst); inst[0] = GROUP_0F; @@ -4202,15 +4260,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile FAIL_IF(emit_byte(compiler, U8(lane_index))); if (!(type & SLJIT_SIMD_LANE_SIGNED) || (srcdst & SLJIT_MEM)) { - if (freg == TMP_FREG && !(type & SLJIT_SIMD_STORE)) { + if (vreg == TMP_FREG && !(type & SLJIT_SIMD_STORE)) { SLJIT_ASSERT(reg_size == 5); if (type & SLJIT_SIMD_LANE_ZERO) { - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg_orig, 0, TMP_FREG, 0)); return emit_byte(compiler, 0x4e); } - FAIL_IF(emit_vex_instruction(compiler, VINSERTI128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VINSERTI128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, vreg_orig, vreg_orig, TMP_FREG, 0)); return emit_byte(compiler, 1); } @@ -4262,7 +4320,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4277,7 +4335,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c #endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -4301,9 +4359,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 5) { if (src_lane_index == 0) - return emit_vex_instruction(compiler, VBROADCASTSD_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + return emit_vex_instruction(compiler, VBROADCASTSD_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0); - FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); byte = U8(byte | (byte << 2)); return emit_byte(compiler, U8(byte | (byte << 4))); @@ -4311,8 +4369,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (src_lane_index == 0) { if (use_vex) - return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, src, 0); - return emit_groupf(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, src, 0); + return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, src, 0); + return emit_groupf(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, src, 0); } /* Changes it to SHUFPD_x_xm. */ @@ -4326,9 +4384,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c SLJIT_ASSERT(elem_size == 2); if (src_lane_index == 0) - return emit_vex_instruction(compiler, VBROADCASTSS_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + return emit_vex_instruction(compiler, VBROADCASTSS_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0); - FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); byte = 0x44; if (src_lane_index >= 4) { @@ -4337,15 +4395,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } FAIL_IF(emit_byte(compiler, byte)); - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | VEX_256 | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | VEX_256 | pref | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0)); byte = U8(src_lane_index); } else if (use_vex) { - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, vreg, src, src, 0)); } else { - if (freg != src) - FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | pref | EX86_SSE2, freg, src, 0)); + if (vreg != src) + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | pref | EX86_SSE2, vreg, src, 0)); - FAIL_IF(emit_groupf(compiler, SHUFPS_x_xm | pref | EX86_SSE2, freg, freg, 0)); + FAIL_IF(emit_groupf(compiler, SHUFPS_x_xm | pref | EX86_SSE2, vreg, vreg, 0)); } if (elem_size == 2) { @@ -4362,13 +4420,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (elem_size == 0) { if (reg_size == 5 && src_lane_index >= 16) { - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); FAIL_IF(emit_byte(compiler, src_lane_index >= 24 ? 0xff : 0xaa)); src_lane_index &= 0x7; - src = freg; + src = vreg; } - if (src_lane_index != 0 || (freg != src && (!(cpu_feature_list & CPU_FEATURE_AVX2) || !use_vex))) { + if (src_lane_index != 0 || (vreg != src && (!(cpu_feature_list & CPU_FEATURE_AVX2) || !use_vex))) { pref = 0; if ((src_lane_index & 0x3) == 0) { @@ -4379,33 +4437,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c byte = U8(src_lane_index >> 1); } else { if (!use_vex) { - if (freg != src) - FAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); + if (vreg != src) + FAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, src, 0)); - FAIL_IF(emit_groupf(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2, opcode3, freg, 0)); + FAIL_IF(emit_groupf(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2, opcode3, vreg, 0)); } else - FAIL_IF(emit_vex_instruction(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2 | VEX_SSE2_OPV, opcode3, freg, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2 | VEX_SSE2_OPV, opcode3, vreg, src, 0)); FAIL_IF(emit_byte(compiler, U8(src_lane_index))); } if (pref != 0) { if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, 0, src, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, src, 0)); FAIL_IF(emit_byte(compiler, byte)); } - src = freg; + src = vreg; } if (use_vex && (cpu_feature_list & CPU_FEATURE_AVX2)) - return emit_vex_instruction(compiler, VPBROADCASTB_x_xm | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + return emit_vex_instruction(compiler, VPBROADCASTB_x_xm | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0); SLJIT_ASSERT(reg_size == 4); FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); - return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, TMP_FREG, 0); } if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && src_lane_index == 0 && elem_size <= 3) { @@ -4424,7 +4482,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 5) pref |= VEX_256; - return emit_vex_instruction(compiler, pref, freg, 0, src, 0); + return emit_vex_instruction(compiler, pref, vreg, 0, src, 0); } if (reg_size == 5) { @@ -4443,22 +4501,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c pref = 0; break; default: - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); return emit_byte(compiler, U8(src_lane_index == 0 ? 0x44 : 0xee)); } if (pref != 0) { - FAIL_IF(emit_vex_instruction(compiler, pref, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, pref, vreg, 0, src, 0)); byte = U8(byte | (byte << 2)); FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); if (src_lane_index == 0) - return emit_vex_instruction(compiler, VPBROADCASTQ_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + return emit_vex_instruction(compiler, VPBROADCASTQ_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0); - src = freg; + src = vreg; } - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); byte = U8(src_lane_index); byte = U8(byte | (byte << 2)); return emit_byte(compiler, U8(byte | (byte << 4))); @@ -4471,16 +4529,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c pref = (src_lane_index & 2) == 0 ? EX86_PREF_F2 : EX86_PREF_F3; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, 0, src, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, src, 0)); byte = U8(byte | (byte << 2)); FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && pref == EX86_PREF_F2) - return emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + return emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0); - src = freg; + src = vreg; /* fallthrough */ case 2: byte = U8(src_lane_index); @@ -4493,14 +4551,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, src, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, src, 0)); return emit_byte(compiler, U8(byte | (byte << 4))); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4510,7 +4568,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_u8 opcode; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4533,8 +4591,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (use_vex) - return emit_vex_instruction(compiler, CVTPS2PD_x_xm | ((reg_size == 5) ? VEX_256 : 0) | EX86_SSE2, freg, 0, src, srcw); - return emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, freg, src, srcw); + return emit_vex_instruction(compiler, CVTPS2PD_x_xm | ((reg_size == 5) ? VEX_256 : 0) | EX86_SSE2, vreg, 0, src, srcw); + return emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, vreg, src, srcw); } switch (elem_size) { @@ -4570,12 +4628,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (use_vex) - return emit_vex_instruction(compiler, opcode | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, srcw); - return emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, src, srcw); + return emit_vex_instruction(compiler, opcode | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, srcw); + return emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, src, srcw); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 freg, + sljit_s32 vreg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4586,7 +4644,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_u8 *inst; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4607,10 +4665,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c switch (elem_size) { case 1: if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, freg, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, vreg, vreg, 0)); else - FAIL_IF(emit_groupf(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, freg, 0)); - freg = TMP_FREG; + FAIL_IF(emit_groupf(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, vreg, 0)); + vreg = TMP_FREG; break; case 2: op = EX86_SSE2_OP2; @@ -4621,9 +4679,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c op |= (elem_size < 2) ? PMOVMSKB_r_x : MOVMSKPS_r_x; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, vreg, 0)); else - FAIL_IF(emit_groupf(compiler, op, dst_r, freg, 0)); + FAIL_IF(emit_groupf(compiler, op, dst_r, vreg, 0)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = type & SLJIT_32; @@ -4650,9 +4708,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; if (elem_size == 1) { - FAIL_IF(emit_vex_instruction(compiler, VEXTRACTI128_x_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VEXTRACTI128_x_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, TMP_FREG, 0)); FAIL_IF(emit_byte(compiler, 1)); - FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, freg, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, vreg, TMP_FREG, 0)); FAIL_IF(emit_groupf(compiler, PMOVMSKB_r_x | EX86_PREF_66 | EX86_SSE2_OP2, dst_r, TMP_FREG, 0)); } else { op = MOVMSKPS_r_x | VEX_256 | EX86_SSE2_OP2; @@ -4662,7 +4720,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c else if (elem_size == 3) op |= EX86_PREF_66; - FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, freg, 0)); + FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, vreg, 0)); } if (dst_r == TMP_REG1) { @@ -4676,7 +4734,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } static sljit_s32 emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src_freg) + sljit_s32 dst_vreg, sljit_s32 src_vreg) { sljit_uw op = ((type & SLJIT_SIMD_FLOAT) ? MOVAPS_x_xm : MOVDQA_x_xm) | EX86_SSE2; @@ -4685,18 +4743,21 @@ static sljit_s32 emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, if (!(type & SLJIT_SIMD_FLOAT) || SLJIT_SIMD_GET_ELEM_SIZE(type) == 3) op |= EX86_PREF_66; - return emit_groupf(compiler, op, dst_freg, src_freg, 0); + return emit_groupf(compiler, op, dst_vreg, src_vreg, 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) + sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX); sljit_uw op = 0; + sljit_uw mov_op = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + ADJUST_LOCAL_OFFSET(src2, src2w); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -4730,27 +4791,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) op |= EX86_PREF_66; break; + + case SLJIT_SIMD_OP2_SHUFFLE: + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + op = PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38; + break; } if (type & SLJIT_SIMD_TEST) return SLJIT_SUCCESS; - if (reg_size == 5 || ((cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX))) { + if ((src2 & SLJIT_MEM) && SLJIT_SIMD_GET_ELEM2_SIZE(type) < reg_size) { + mov_op = ((type & SLJIT_SIMD_FLOAT) ? (MOVUPS_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0)) : (MOVDQU_x_xm | EX86_PREF_F3)) | EX86_SSE2; + if (use_vex) + FAIL_IF(emit_vex_instruction(compiler, mov_op, TMP_FREG, 0, src2, src2w)); + else + FAIL_IF(emit_groupf(compiler, mov_op, TMP_FREG, src2, src2w)); + + src2 = TMP_FREG; + src2w = 0; + } + + if (reg_size == 5 || use_vex) { if (reg_size == 5) op |= VEX_256; - return emit_vex_instruction(compiler, op | EX86_SSE2 | VEX_SSE2_OPV, dst_freg, src1_freg, src2_freg, 0); + return emit_vex_instruction(compiler, op | EX86_SSE2 | VEX_SSE2_OPV, dst_vreg, src1_vreg, src2, src2w); } - if (dst_freg != src1_freg) { - if (dst_freg == src2_freg) - src2_freg = src1_freg; - else - FAIL_IF(emit_simd_mov(compiler, type, dst_freg, src1_freg)); + if (dst_vreg != src1_vreg) { + if (dst_vreg == src2) { + if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) { + FAIL_IF(emit_simd_mov(compiler, type, TMP_FREG, src2)); + FAIL_IF(emit_simd_mov(compiler, type, dst_vreg, src1_vreg)); + src2 = TMP_FREG; + src2w = 0; + } else + src2 = src1_vreg; + } else + FAIL_IF(emit_simd_mov(compiler, type, dst_vreg, src1_vreg)); } - FAIL_IF(emit_groupf(compiler, op | EX86_SSE2, dst_freg, src2_freg, 0)); - return SLJIT_SUCCESS; + if (op & (VEX_OP_0F38 | VEX_OP_0F3A)) + return emit_groupf_ext(compiler, op | EX86_SSE2, dst_vreg, src2, src2w); + return emit_groupf(compiler, op | EX86_SSE2, dst_vreg, src2, src2w); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, @@ -4760,8 +4846,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + if ((op & SLJIT_ATOMIC_USE_LS) || GET_OPCODE(op) == SLJIT_MOV_S8 || GET_OPCODE(op) == SLJIT_MOV_S16 || GET_OPCODE(op) == SLJIT_MOV_S32) + return SLJIT_ERR_UNSUPPORTED; + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); + return sljit_emit_op1(compiler, op & ~SLJIT_ATOMIC_USE_CAS, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, @@ -4770,8 +4862,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler sljit_s32 temp_reg) { sljit_uw pref; - sljit_s32 free_reg = TMP_REG1; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_s32 saved_reg = TMP_REG1; + sljit_s32 swap_tmp = 0; sljit_sw srcw = 0; sljit_sw tempw = 0; #endif /* SLJIT_CONFIG_X86_32 */ @@ -4784,18 +4877,43 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler SLJIT_ASSERT(FAST_IS_REG(src_reg) || src_reg == SLJIT_MEM1(SLJIT_SP)); SLJIT_ASSERT(FAST_IS_REG(temp_reg) || temp_reg == SLJIT_MEM1(SLJIT_SP)); + if ((op & SLJIT_ATOMIC_USE_LS) || GET_OPCODE(op) == SLJIT_MOV_S8 || GET_OPCODE(op) == SLJIT_MOV_S16 || GET_OPCODE(op) == SLJIT_MOV_S32) + return SLJIT_ERR_UNSUPPORTED; + + if (op & SLJIT_ATOMIC_TEST) + return SLJIT_SUCCESS; + op = GET_OPCODE(op); + #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (temp_reg == SLJIT_TMP_DEST_REG) { + FAIL_IF(emit_byte(compiler, XCHG_EAX_r | reg_map[TMP_REG1])); + + if (src_reg == SLJIT_R0) + src_reg = TMP_REG1; + if (mem_reg == SLJIT_R0) + mem_reg = TMP_REG1; + + temp_reg = SLJIT_R0; + swap_tmp = 1; + } + + /* Src is virtual register or its low byte is not accessible. */ if ((src_reg & SLJIT_MEM) || (op == SLJIT_MOV_U8 && reg_map[src_reg] >= 4)) { - /* Src is virtual register or its low byte is not accessible. */ - SLJIT_ASSERT(src_reg != SLJIT_R1); - free_reg = src_reg; + SLJIT_ASSERT(src_reg != SLJIT_R1 && temp_reg != SLJIT_TMP_DEST_REG); + + if (swap_tmp) { + saved_reg = (mem_reg != SLJIT_R1) ? SLJIT_R1 : SLJIT_R2; + + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, saved_reg, 0); + EMIT_MOV(compiler, saved_reg, 0, src_reg, srcw); + } else + EMIT_MOV(compiler, TMP_REG1, 0, src_reg, srcw); - EMIT_MOV(compiler, TMP_REG1, 0, src_reg, srcw); - src_reg = TMP_REG1; + src_reg = saved_reg; if (mem_reg == src_reg) - mem_reg = TMP_REG1; + mem_reg = saved_reg; } #endif /* SLJIT_CONFIG_X86_32 */ @@ -4803,29 +4921,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; - EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_R0, 0); EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, 0); if (src_reg == SLJIT_R0) - src_reg = free_reg; + src_reg = TMP_REG2; if (mem_reg == SLJIT_R0) - mem_reg = free_reg; + mem_reg = TMP_REG2; #else /* !SLJIT_CONFIG_X86_64 */ - if (src_reg == TMP_REG1 && mem_reg == SLJIT_R0 && (free_reg & SLJIT_MEM)) { - EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R1, 0); - EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_R0, 0); - EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + SLJIT_ASSERT(!swap_tmp); - mem_reg = SLJIT_R1; - free_reg = SLJIT_R1; + if (src_reg == TMP_REG1) { + if (mem_reg == SLJIT_R0) { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R1, 0); + EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + + mem_reg = SLJIT_R1; + saved_reg = SLJIT_R1; + } else { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + saved_reg = SLJIT_R0; + } } else { - EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R0, 0); EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); if (src_reg == SLJIT_R0) - src_reg = free_reg; + src_reg = TMP_REG1; if (mem_reg == SLJIT_R0) - mem_reg = free_reg; + mem_reg = TMP_REG1; } #endif /* SLJIT_CONFIG_X86_64 */ } @@ -4847,14 +4973,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler FAIL_IF(emit_groupf(compiler, (op == SLJIT_MOV_U8 ? CMPXCHG_rm8_r : CMPXCHG_rm_r) | pref, src_reg, SLJIT_MEM1(mem_reg), 0)); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (swap_tmp) { + SLJIT_ASSERT(temp_reg == SLJIT_R0); + FAIL_IF(emit_byte(compiler, XCHG_EAX_r | reg_map[TMP_REG1])); + + if (saved_reg != TMP_REG1) + return emit_mov(compiler, saved_reg, 0, SLJIT_MEM1(SLJIT_SP), 0); + return SLJIT_SUCCESS; + } +#endif /* SLJIT_CONFIG_X86_32 */ + if (temp_reg != SLJIT_R0) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; - return emit_mov(compiler, SLJIT_R0, 0, TMP_REG1, 0); + return emit_mov(compiler, SLJIT_R0, 0, TMP_REG2, 0); #else /* !SLJIT_CONFIG_X86_64 */ - EMIT_MOV(compiler, SLJIT_R0, 0, free_reg, 0); - if (free_reg != TMP_REG1) - return emit_mov(compiler, free_reg, 0, (free_reg == SLJIT_R1) ? SLJIT_MEM1(SLJIT_SP) : TMP_REG1, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, (saved_reg == SLJIT_R0) ? SLJIT_MEM1(SLJIT_SP) : saved_reg, 0); + if (saved_reg == SLJIT_R1) + return emit_mov(compiler, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_SP), 0); #endif /* SLJIT_CONFIG_X86_64 */ } return SLJIT_SUCCESS; diff --git a/ext/pcre/tests/bug75457.phpt b/ext/pcre/tests/bug75457.phpt index ee5ab162f8a6c..87dc12a1ad056 100644 --- a/ext/pcre/tests/bug75457.phpt +++ b/ext/pcre/tests/bug75457.phpt @@ -6,5 +6,5 @@ $pattern = "/(((?(?C)0?=))(?!()0|.(?0)0)())/"; var_dump(preg_match($pattern, "hello")); ?> --EXPECTF-- -Warning: preg_match(): Compilation failed: assertion expected after (?( or (?(?C) at offset 8 in %sbug75457.php on line %d +Warning: preg_match(): Compilation failed: %r(atomic|)%r assertion expected after (?( or (?(?C) at offset 8 in %sbug75457.php on line %d bool(false)