Merge "Upgrade to pcre2 version 10.31."
diff --git a/Android.bp b/Android.bp
index 9b9b272..292e962 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7,8 +7,10 @@
     libpcre2_dist_prefix + "/src/pcre2_compile.c",
     libpcre2_dist_prefix + "/src/pcre2_config.c",
     libpcre2_dist_prefix + "/src/pcre2_context.c",
+    libpcre2_dist_prefix + "/src/pcre2_convert.c",
     libpcre2_dist_prefix + "/src/pcre2_dfa_match.c",
     libpcre2_dist_prefix + "/src/pcre2_error.c",
+    libpcre2_dist_prefix + "/src/pcre2_extuni.c",
     libpcre2_dist_prefix + "/src/pcre2_find_bracket.c",
     libpcre2_dist_prefix + "/src/pcre2_maketables.c",
     libpcre2_dist_prefix + "/src/pcre2_match.c",
diff --git a/README.version b/README.version
index 6ed9971..9311180 100644
--- a/README.version
+++ b/README.version
@@ -1,2 +1,2 @@
-URL: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-10.22.tar.gz
-Version: 10.22
+URL: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-10.31.tar.gz
+Version: 10.31
diff --git a/dist2/132html b/dist2/132html
index 3a16a59..1bd62ba 100755
--- a/dist2/132html
+++ b/dist2/132html
@@ -109,8 +109,9 @@
     # Handling .sp is subtle. If it is inside a literal section, do nothing if
     # the next line is a non literal text line; similarly, if not inside a
     # literal section, do nothing if a literal follows, unless we are inside
-    # a .nf/.ne section. The point being that the <pre> and </pre> that delimit
-    # literal sections will do the spacing. Always skip if no previous output.
+    # a .nf/.fi section or about to enter one. The point being that the <pre>
+    # and </pre> that delimit literal sections will do the spacing. Always skip
+    # if no previous output.
 
     elsif (/^\.sp/)
       {
@@ -123,7 +124,7 @@
           }
         else
           {
-          print TEMP "<br>\n<br>\n" if ($innf || !/^[\s.]/);
+          print TEMP "<br>\n<br>\n" if ($innf || /^\.nf/ || !/^[\s.]/);
           }
         redo;    # Now process the lookahead line we just read
         }
diff --git a/dist2/AUTHORS b/dist2/AUTHORS
index d9a0e15..d5592bb 100644
--- a/dist2/AUTHORS
+++ b/dist2/AUTHORS
@@ -8,7 +8,7 @@
 University of Cambridge Computing Service,
 Cambridge, England.
 
-Copyright (c) 1997-2016 University of Cambridge
+Copyright (c) 1997-2018 University of Cambridge
 All rights reserved
 
 
@@ -19,7 +19,7 @@
 Email local part: hzmester
 Emain domain:     freemail.hu
 
-Copyright(c) 2010-2016 Zoltan Herczeg
+Copyright(c) 2010-2018 Zoltan Herczeg
 All rights reserved.
 
 
@@ -30,7 +30,7 @@
 Email local part: hzmester
 Emain domain:     freemail.hu
 
-Copyright(c) 2009-2016 Zoltan Herczeg
+Copyright(c) 2009-2018 Zoltan Herczeg
 All rights reserved.
 
 ####
diff --git a/dist2/CMakeLists.txt b/dist2/CMakeLists.txt
index ced3df2..bde940a 100644
--- a/dist2/CMakeLists.txt
+++ b/dist2/CMakeLists.txt
@@ -74,6 +74,12 @@
 # 2016-03-01 PH applied Chris Wilson's patch for MSVC static
 # 2016-06-24 PH applied Chris Wilson's second patch, putting the first under
 #            a new option instead of being unconditional.
+# 2016-10-05 PH fixed a typo (PCRE should be PCRE2) in above patch
+#            fix by David Gaussmann
+# 2016-10-07 PH added PCREGREP_MAX_BUFSIZE
+# 2017-03-11 PH turned HEAP_MATCH_RECURSE into a NO-OP for 10.30
+# 2017-04-08 PH added HEAP_LIMIT
+# 2017-06-15 ZH added SUPPORT_JIT_SEALLOC support
 
 PROJECT(PCRE2 C)
 
@@ -139,24 +145,33 @@
 SET(PCRE2_PARENS_NEST_LIMIT "250" CACHE STRING
     "Default nested parentheses limit. See PARENS_NEST_LIMIT in config.h.in for details.")
 
+SET(PCRE2_HEAP_LIMIT "20000000" CACHE STRING
+    "Default limit on heap memory (kilobytes). See HEAP_LIMIT in config.h.in for details.")
+
 SET(PCRE2_MATCH_LIMIT "10000000" CACHE STRING
     "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.")
 
-SET(PCRE2_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING
-    "Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.")
+SET(PCRE2_MATCH_LIMIT_DEPTH "MATCH_LIMIT" CACHE STRING
+    "Default limit on internal depth of search. See MATCH_LIMIT_DEPTH in config.h.in for details.")
 
 SET(PCRE2GREP_BUFSIZE "20480" CACHE STRING
-    "Buffer size parameter for pcre2grep. See PCRE2GREP_BUFSIZE in config.h.in for details.")
+    "Buffer starting size parameter for pcre2grep. See PCRE2GREP_BUFSIZE in config.h.in for details.")
+
+SET(PCRE2GREP_MAX_BUFSIZE "1048576" CACHE STRING
+    "Buffer maximum size parameter for pcre2grep. See PCRE2GREP_MAX_BUFSIZE in config.h.in for details.")
 
 SET(PCRE2_NEWLINE "LF" CACHE STRING
-    "What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF).")
+    "What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF, NUL).")
 
 SET(PCRE2_HEAP_MATCH_RECURSE OFF CACHE BOOL
-    "If ON, then don't use stack recursion when matching. See HEAP_MATCH_RECURSE in config.h.in for details.")
+    "Obsolete option: do not use")
 
 SET(PCRE2_SUPPORT_JIT OFF CACHE BOOL
     "Enable support for Just-in-time compiling.")
 
+SET(PCRE2_SUPPORT_JIT_SEALLOC OFF CACHE BOOL
+    "Enable SELinux compatible execmem allocator in JIT.")
+
 SET(PCRE2_SUPPORT_PCRE2GREP_JIT ON CACHE BOOL
     "Enable use of Just-in-time compiling in pcre2grep.")
 
@@ -190,7 +205,7 @@
 ENDIF(MINGW)
 
 IF(MSVC)
-  OPTION(PCRE_STATIC_RUNTIME OFF CACHE BOOL
+  OPTION(PCRE2_STATIC_RUNTIME
 	"ON=Compile against the static runtime (/MT)."
 	OFF)
   OPTION(INSTALL_MSVC_PDB
@@ -277,6 +292,10 @@
         SET(SUPPORT_JIT 1)
 ENDIF(PCRE2_SUPPORT_JIT)
 
+IF(PCRE2_SUPPORT_JIT_SEALLOC)
+        SET(SLJIT_PROT_EXECUTABLE_ALLOCATOR 1)
+ENDIF(PCRE2_SUPPORT_JIT_SEALLOC)
+
 IF(PCRE2_SUPPORT_PCRE2GREP_JIT)
         SET(SUPPORT_PCRE2GREP_JIT 1)
 ENDIF(PCRE2_SUPPORT_PCRE2GREP_JIT)
@@ -333,6 +352,9 @@
 IF(PCRE2_NEWLINE STREQUAL "ANYCRLF")
         SET(NEWLINE_DEFAULT "5")
 ENDIF(PCRE2_NEWLINE STREQUAL "ANYCRLF")
+IF(PCRE2_NEWLINE STREQUAL "NUL")
+        SET(NEWLINE_DEFAULT "6")
+ENDIF(PCRE2_NEWLINE STREQUAL "NUL")
 
 IF(NEWLINE_DEFAULT STREQUAL "")
         MESSAGE(FATAL_ERROR "The PCRE2_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".")
@@ -347,10 +369,6 @@
         SET(EBCDIC_NL25 1)
 ENDIF(PCRE2_EBCDIC_NL25)
 
-IF(PCRE2_HEAP_MATCH_RECURSE)
-        SET(HEAP_MATCH_RECURSE 1)
-ENDIF(PCRE2_HEAP_MATCH_RECURSE)
-
 # Output files
 
 CONFIGURE_FILE(config-cmake.h.in
@@ -411,8 +429,10 @@
   src/pcre2_compile.c
   src/pcre2_config.c
   src/pcre2_context.c
+  src/pcre2_convert.c
   src/pcre2_dfa_match.c
   src/pcre2_error.c
+  src/pcre2_extuni.c
   src/pcre2_find_bracket.c
   src/pcre2_jit_compile.c
   src/pcre2_maketables.c
@@ -505,18 +525,18 @@
 SET_PROPERTY(TARGET pcre2-8
   PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8)
 SET(targets ${targets} pcre2-8)
-ADD_LIBRARY(pcre2posix ${PCRE2POSIX_HEADERS} ${PCRE2POSIX_SOURCES})
-SET_PROPERTY(TARGET pcre2posix
+ADD_LIBRARY(pcre2-posix ${PCRE2POSIX_HEADERS} ${PCRE2POSIX_SOURCES})
+SET_PROPERTY(TARGET pcre2-posix
   PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8)
-SET(targets ${targets} pcre2posix)
-TARGET_LINK_LIBRARIES(pcre2posix pcre2-8)
+SET(targets ${targets} pcre2-posix)
+TARGET_LINK_LIBRARIES(pcre2-posix pcre2-8)
 
 IF(MINGW AND NOT PCRE2_STATIC)
   IF(NON_STANDARD_LIB_PREFIX)
-    SET_TARGET_PROPERTIES(pcre2-8 pcre2posix PROPERTIES PREFIX "")
+    SET_TARGET_PROPERTIES(pcre2-8 pcre2-posix PROPERTIES PREFIX "")
   ENDIF(NON_STANDARD_LIB_PREFIX)
   IF(NON_STANDARD_LIB_SUFFIX)
-    SET_TARGET_PROPERTIES(pcre2-8 pcre2posix PROPERTIES SUFFIX "-0.dll")
+    SET_TARGET_PROPERTIES(pcre2-8 pcre2-posix PROPERTIES SUFFIX "-0.dll")
   ENDIF(NON_STANDARD_LIB_SUFFIX)
 ENDIF(MINGW AND NOT PCRE2_STATIC)
 ENDIF(PCRE2_BUILD_PCRE2_8)
@@ -564,7 +584,7 @@
   SET_PROPERTY(TARGET pcre2grep
     PROPERTY COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8)
   SET(targets ${targets} pcre2grep)
-  TARGET_LINK_LIBRARIES(pcre2grep pcre2posix ${PCRE2GREP_LIBS})
+  TARGET_LINK_LIBRARIES(pcre2grep pcre2-posix ${PCRE2GREP_LIBS})
 ENDIF(PCRE2_BUILD_PCRE2GREP)
 
 # Testing
@@ -577,7 +597,7 @@
   ADD_EXECUTABLE(pcre2test ${PCRE2TEST_SOURCES})
   SET(targets ${targets} pcre2test)
   IF(PCRE2_BUILD_PCRE2_8)
-    LIST(APPEND PCRE2TEST_LIBS pcre2posix pcre2-8)
+    LIST(APPEND PCRE2TEST_LIBS pcre2-posix pcre2-8)
   ENDIF(PCRE2_BUILD_PCRE2_8)
   IF(PCRE2_BUILD_PCRE2_16)
     LIST(APPEND PCRE2TEST_LIBS pcre2-16)
@@ -732,6 +752,10 @@
   SET(BUILD_STATIC_LIBS ON)
 ENDIF(BUILD_SHARED_LIBS)
 
+IF(PCRE2_HEAP_MATCH_RECURSE)
+  MESSAGE(WARNING "HEAP_MATCH_RECURSE is obsolete and does nothing.")
+ENDIF(PCRE2_HEAP_MATCH_RECURSE)
+
 IF(PCRE2_SHOW_REPORT)
   STRING(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype)
   IF (CMAKE_C_FLAGS)
@@ -749,6 +773,7 @@
   MESSAGE(STATUS "  Build 16 bit PCRE2 library ...... : ${PCRE2_BUILD_PCRE2_16}")
   MESSAGE(STATUS "  Build 32 bit PCRE2 library ...... : ${PCRE2_BUILD_PCRE2_32}")
   MESSAGE(STATUS "  Enable JIT compiling support .... : ${PCRE2_SUPPORT_JIT}")
+  MESSAGE(STATUS "  Use SELinux allocator in JIT .... : ${PCRE2_SUPPORT_JIT_SEALLOC}")
   MESSAGE(STATUS "  Enable Unicode support .......... : ${PCRE2_SUPPORT_UNICODE}")
   MESSAGE(STATUS "  Newline char/sequence ........... : ${PCRE2_NEWLINE}")
   MESSAGE(STATUS "  \\R matches only ANYCRLF ......... : ${PCRE2_SUPPORT_BSR_ANYCRLF}")
@@ -756,11 +781,11 @@
   MESSAGE(STATUS "  EBCDIC coding ................... : ${PCRE2_EBCDIC}")
   MESSAGE(STATUS "  EBCDIC coding with NL=0x25 ...... : ${PCRE2_EBCDIC_NL25}")
   MESSAGE(STATUS "  Rebuild char tables ............. : ${PCRE2_REBUILD_CHARTABLES}")
-  MESSAGE(STATUS "  Use heap recursion .............. : ${PCRE2_HEAP_MATCH_RECURSE}")
   MESSAGE(STATUS "  Internal link size .............. : ${PCRE2_LINK_SIZE}")
   MESSAGE(STATUS "  Parentheses nest limit .......... : ${PCRE2_PARENS_NEST_LIMIT}")
+  MESSAGE(STATUS "  Heap limit ...................... : ${PCRE2_HEAP_LIMIT}")
   MESSAGE(STATUS "  Match limit ..................... : ${PCRE2_MATCH_LIMIT}")
-  MESSAGE(STATUS "  Match limit recursion ........... : ${PCRE2_MATCH_LIMIT_RECURSION}")
+  MESSAGE(STATUS "  Match depth limit ............... : ${PCRE2_MATCH_LIMIT_DEPTH}")
   MESSAGE(STATUS "  Build shared libs ............... : ${BUILD_SHARED_LIBS}")
   MESSAGE(STATUS "  Build static libs ............... : ${BUILD_STATIC_LIBS}")
   MESSAGE(STATUS "  Build pcre2grep ................. : ${PCRE2_BUILD_PCRE2GREP}")
diff --git a/dist2/ChangeLog b/dist2/ChangeLog
index 3dcebb9..7f520bf 100644
--- a/dist2/ChangeLog
+++ b/dist2/ChangeLog
@@ -2,6 +2,743 @@
 --------------------
 
 
+Version 10.31 12-February-2018
+------------------------------
+
+1. Fix typo (missing ]) in VMS code in pcre2test.c.
+
+2. Replace the replicated code for matching extended Unicode grapheme sequences
+(which got a lot more complicated by change 10.30/49) by a single subroutine
+that is called by both pcre2_match() and pcre2_dfa_match().
+
+3. Add idempotent guard to pcre2_internal.h.
+
+4. Add new pcre2_config() options: PCRE2_CONFIG_NEVER_BACKSLASH_C and
+PCRE2_CONFIG_COMPILED_WIDTHS.
+
+5. Cut out \C tests in the JIT regression tests when NEVER_BACKSLASH_C is
+defined (e.g. by --enable-never-backslash-C).
+
+6. Defined public names for all the pcre2_compile() error numbers, and used
+the public names in pcre2_convert.c.
+
+7. Fixed a small memory leak in pcre2test (convert contexts).
+
+8. Added two casts to compile.c and one to match.c to avoid compiler warnings.
+
+9. Added code to pcre2grep when compiled under VMS to set the symbol
+PCRE2GREP_RC to the exit status, because VMS does not distinguish between
+exit(0) and exit(1).
+
+10. Added the -LM (list modifiers) option to pcre2test. Also made -C complain
+about a bad option only if the following argument item does not start with a
+hyphen.
+
+11. pcre2grep was truncating components of file names to 128 characters when
+processing files with the -r option, and also (some very odd code) truncating
+path names to 512 characters. There is now a check on the absolute length of
+full path file names, which may be up to 2047 characters long.
+
+12. When an assertion contained (*ACCEPT) it caused all open capturing groups
+to be closed (as for a non-assertion ACCEPT), which was wrong and could lead to
+misbehaviour for subsequent references to groups that started outside the
+assertion. ACCEPT in an assertion now closes only those groups that were
+started within that assertion. Fixes oss-fuzz issues 3852 and 3891.
+
+13. Multiline matching in pcre2grep was misbehaving if the pattern matched
+within a line, and then matched again at the end of the line and over into
+subsequent lines. Behaviour was different with and without colouring, and
+sometimes context lines were incorrectly printed and/or line endings were lost.
+All these issues should now be fixed.
+
+14. If --line-buffered was specified for pcre2grep when input was from a
+compressed file (.gz or .bz2) a segfault occurred. (Line buffering should be
+ignored for compressed files.)
+
+15. Although pcre2_jit_match checks whether the pattern is compiled
+in a given mode, it was also expected that at least one mode is available.
+This is fixed and pcre2_jit_match returns with PCRE2_ERROR_JIT_BADOPTION
+when the pattern is not optimized by JIT at all.
+
+16. The line number and related variables such as match counts in pcre2grep
+were all int variables, causing overflow when files with more than 2147483647
+lines were processed (assuming 32-bit ints). They have all been changed to
+unsigned long ints.
+
+17. If a backreference with a minimum repeat count of zero was first in a
+pattern, apart from assertions, an incorrect first matching character could be
+recorded. For example, for the pattern /(?=(a))\1?b/, "b" was incorrectly set
+as the first character of a match.
+
+18. Characters in a leading positive assertion are considered for recording a
+first character of a match when the rest of the pattern does not provide one.
+However, a character in a non-assertive group within a leading assertion such
+as in the pattern /(?=(a))\1?b/ caused this process to fail. This was an
+infelicity rather than an outright bug, because it did not affect the result of
+a match, just its speed. (In fact, in this case, the starting 'a' was
+subsequently picked up in the study.)
+
+19. A minor tidy in pcre2_match(): making all PCRE2_ERROR_ returns use "return"
+instead of "RRETURN" saves unwinding the backtracks in these cases (only one
+didn't).
+
+20. Allocate a single callout block on the stack at the start of pcre2_match()
+and set its never-changing fields once only. Do the same for pcre2_dfa_match().
+
+21. Save the extra compile options (set in the compile context) with the
+compiled pattern (they were not previously saved), add PCRE2_INFO_EXTRAOPTIONS
+to retrieve them, and update pcre2test to show them.
+
+22. Added PCRE2_CALLOUT_STARTMATCH and PCRE2_CALLOUT_BACKTRACK bits to a new
+field callout_flags in callout blocks. The bits are set by pcre2_match(), but
+not by JIT or pcre2_dfa_match(). Their settings are shown in pcre2test callouts
+if the callout_extra subject modifier is set. These bits are provided to help
+with tracking how a backtracking match is proceeding.
+
+23. Updated the pcre2demo.c demonstration program, which was missing the extra
+code for -g that handles the case when \K in an assertion causes the match to
+end at the original start point. Also arranged for it to detect when \K causes
+the end of a match to be before its start.
+
+24. Similar to 23 above, strange things (including loops) could happen in
+pcre2grep when \K was used in an assertion when --colour was used or in
+multiline mode. The "end at original start point" bug is fixed, and if the end
+point is found to be before the start point, they are swapped.
+
+25. When PCRE2_FIRSTLINE without PCRE2_NO_START_OPTIMIZE was used in non-JIT
+matching (both pcre2_match() and pcre2_dfa_match()) and the matched string
+started with the first code unit of a newline sequence, matching failed because
+it was not tried at the newline.
+
+26. Code for giving up a non-partial match after failing to find a starting
+code unit anywhere in the subject was missing when searching for one of a
+number of code units (the bitmap case) in both pcre2_match() and
+pcre2_dfa_match(). This was a missing optimization rather than a bug.
+
+27. Tidied up the ACROSSCHAR macro to be like FORWARDCHAR and BACKCHAR, using a
+pointer argument rather than a code unit value. This should not have affected
+the generated code.
+
+28. The JIT compiler has been updated.
+
+29. Avoid pointer overflow for unset captures in pcre2_substring_list_get().
+This could not actually cause a crash because it was always used in a memcpy()
+call with zero length.
+
+30. Some internal structures have a variable-length ovector[] as their last
+element. Their actual memory is obtained dynamically, giving an ovector of
+appropriate length. However, they are defined in the structure as
+ovector[NUMBER], where NUMBER is large so that array bound checkers don't
+grumble. The value of NUMBER was 10000, but a fuzzer exceeded 5000 capturing
+groups, making the ovector larger than this. The number has been increased to
+131072, which allows for the maximum number of captures (65535) plus the
+overall match. This fixes oss-fuzz issue 5415.
+
+31. Auto-possessification at the end of a capturing group was dependent on what
+follows the group (e.g. /(a+)b/ would auto-possessify the a+) but this caused
+incorrect behaviour when the group was called recursively from elsewhere in the
+pattern where something different might follow. This bug is an unforseen
+consequence of change #1 for 10.30 - the implementation of backtracking into
+recursions. Iterators at the ends of capturing groups are no longer considered
+for auto-possessification if the pattern contains any recursions. Fixes
+Bugzilla #2232.
+
+
+Version 10.30 14-August-2017
+----------------------------
+
+1. The main interpreter, pcre2_match(), has been refactored into a new version
+that does not use recursive function calls (and therefore the stack) for
+remembering backtracking positions. This makes --disable-stack-for-recursion a
+NOOP. The new implementation allows backtracking into recursive group calls in
+patterns, making it more compatible with Perl, and also fixes some other
+hard-to-do issues such as #1887 in Bugzilla. The code is also cleaner because
+the old code had a number of fudges to try to reduce stack usage. It seems to
+run no slower than the old code.
+
+A number of bugs in the refactored code were subsequently fixed during testing
+before release, but after the code was made available in the repository. These
+bugs were never in fully released code, but are noted here for the record.
+
+  (a) If a pattern had fewer capturing parentheses than the ovector supplied in
+      the match data block, a memory error (detectable by ASAN) occurred after
+      a match, because the external block was being set from non-existent
+      internal ovector fields. Fixes oss-fuzz issue 781.
+
+  (b) A pattern with very many capturing parentheses (when the internal frame
+      size was greater than the initial frame vector on the stack) caused a
+      crash. A vector on the heap is now set up at the start of matching if the
+      vector on the stack is not big enough to handle at least 10 frames.
+      Fixes oss-fuzz issue 783.
+
+  (c) Handling of (*VERB)s in recursions was wrong in some cases.
+
+  (d) Captures in negative assertions that were used as conditions were not
+      happening if the assertion matched via (*ACCEPT).
+
+  (e) Mark values were not being passed out of recursions.
+
+  (f) Refactor some code in do_callout() to avoid picky compiler warnings about
+      negative indices. Fixes oss-fuzz issue 1454.
+
+  (g) Similarly refactor the way the variable length ovector is addressed for
+      similar reasons. Fixes oss-fuzz issue 1465.
+
+2. Now that pcre2_match() no longer uses recursive function calls (see above),
+the "match limit recursion" value seems misnamed. It still exists, and limits
+the depth of tree that is searched. To avoid future confusion, it has been
+renamed as "depth limit" in all relevant places (--with-depth-limit,
+(*LIMIT_DEPTH), pcre2_set_depth_limit(), etc) but the old names are still
+available for backwards compatibility.
+
+3. Hardened pcre2test so as to reduce the number of bugs reported by fuzzers:
+
+  (a) Check for malloc failures when getting memory for the ovector (POSIX) or
+      the match data block (non-POSIX).
+
+4. In the 32-bit library in non-UTF mode, an attempt to find a Unicode property
+for a character with a code point greater than 0x10ffff (the Unicode maximum)
+caused a crash.
+
+5. If a lookbehind assertion that contained a back reference to a group
+appearing later in the pattern was compiled with the PCRE2_ANCHORED option,
+undefined actions (often a segmentation fault) could occur, depending on what
+other options were set. An example assertion is (?<!\1(abc)) where the
+reference \1 precedes the group (abc). This fixes oss-fuzz issue 865.
+
+6. Added the PCRE2_INFO_FRAMESIZE item to pcre2_pattern_info() and arranged for
+pcre2test to use it to output the frame size when the "framesize" modifier is
+given.
+
+7. Reworked the recursive pattern matching in the JIT compiler to follow the
+interpreter changes.
+
+8. When the zero_terminate modifier was specified on a pcre2test subject line
+for global matching, unpredictable things could happen. For example, in UTF-8
+mode, the pattern //g,zero_terminate read random memory when matched against an
+empty string with zero_terminate. This was a bug in pcre2test, not the library.
+
+9. Moved some Windows-specific code in pcre2grep (introduced in 10.23/13) out
+of the section that is compiled when Unix-style directory scanning is
+available, and into a new section that is always compiled for Windows.
+
+10. In pcre2test, explicitly close the file after an error during serialization
+or deserialization (the "load" or "save" commands).
+
+11. Fix memory leak in pcre2_serialize_decode() when the input is invalid.
+
+12. Fix potential NULL dereference in pcre2_callout_enumerate() if called with
+a NULL pattern pointer when Unicode support is available.
+
+13. When the 32-bit library was being tested by pcre2test, error messages that
+were longer than 64 code units could cause a buffer overflow. This was a bug in
+pcre2test.
+
+14. The alternative matching function, pcre2_dfa_match() misbehaved if it
+encountered a character class with a possessive repeat, for example [a-f]{3}+.
+
+15. The depth (formerly recursion) limit now applies to DFA matching (as
+of 10.23/36); pcre2test has been upgraded so that \=find_limits works with DFA
+matching to find the minimum value for this limit.
+
+16. Since 10.21, if pcre2_match() was called with a null context, default
+memory allocation functions were used instead of whatever was used when the
+pattern was compiled.
+
+17. Changes to the pcre2test "memory" modifier on a subject line. These apply
+only to pcre2_match():
+
+  (a) Warn if null_context is set on both pattern and subject, because the
+      memory details cannot then be shown.
+
+  (b) Remember (up to a certain number of) memory allocations and their
+      lengths, and list only the lengths, so as to be system-independent.
+      (In practice, the new interpreter never has more than 2 blocks allocated
+      simultaneously.)
+
+18. Make pcre2test detect an error return from pcre2_get_error_message(), give
+a message, and abandon the run (this would have detected #13 above).
+
+19. Implemented PCRE2_ENDANCHORED.
+
+20. Applied Jason Hood's patches (slightly modified) to pcre2grep, to implement
+the --output=text (-O) option and the inbuilt callout echo.
+
+21. Extend auto-anchoring etc. to ignore groups with a zero qualifier and
+single-branch conditions with a false condition (e.g. DEFINE) at the start of a
+branch. For example, /(?(DEFINE)...)^A/ and /(...){0}^B/ are now flagged as
+anchored.
+
+22. Added an explicit limit on the amount of heap used by pcre2_match(), set by
+pcre2_set_heap_limit() or (*LIMIT_HEAP=xxx). Upgraded pcre2test to show the
+heap limit along with other pattern information, and to find the minimum when
+the find_limits modifier is set.
+
+23. Write to the last 8 bytes of the pcre2_real_code structure when a compiled
+pattern is set up so as to initialize any padding the compiler might have
+included. This avoids valgrind warnings when a compiled pattern is copied, in
+particular when it is serialized.
+
+24. Remove a redundant line of code left in accidentally a long time ago.
+
+25. Remove a duplication typo in pcre2_tables.c
+
+26. Correct an incorrect cast in pcre2_valid_utf.c
+
+27. Update pcre2test, remove some unused code in pcre2_match(), and upgrade the
+tests to improve coverage.
+
+28. Some fixes/tidies as a result of looking at Coverity Scan output:
+
+    (a) Typo: ">" should be ">=" in opcode check in pcre2_auto_possess.c.
+    (b) Added some casts to avoid "suspicious implicit sign extension".
+    (c) Resource leaks in pcre2test in rare error cases.
+    (d) Avoid warning for never-use case OP_TABLE_LENGTH which is just a fudge
+        for checking at compile time that tables are the right size.
+    (e) Add missing "fall through" comment.
+
+29. Implemented PCRE2_EXTENDED_MORE and related /xx and (?xx) features.
+
+30. Implement (?n: for PCRE2_NO_AUTO_CAPTURE, because Perl now has this.
+
+31. If more than one of "push", "pushcopy", or "pushtablescopy" were set in
+pcre2test, a crash could occur.
+
+32. Make -bigstack in RunTest allocate a 64Mb stack (instead of 16 MB) so that
+all the tests can run with clang's sanitizing options.
+
+33. Implement extra compile options in the compile context and add the first
+one: PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES.
+
+34. Implement newline type PCRE2_NEWLINE_NUL.
+
+35. A lookbehind assertion that had a zero-length branch caused undefined
+behaviour when processed by pcre2_dfa_match(). This is oss-fuzz issue 1859.
+
+36. The match limit value now also applies to pcre2_dfa_match() as there are
+patterns that can use up a lot of resources without necessarily recursing very
+deeply. (Compare item 10.23/36.) This should fix oss-fuzz #1761.
+
+37. Implement PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL.
+
+38. Fix returned offsets from regexec() when REG_STARTEND is used with a
+starting offset greater than zero.
+
+39. Implement REG_PEND (GNU extension) for the POSIX wrapper.
+
+40. Implement the subject_literal modifier in pcre2test, and allow jitstack on
+pattern lines.
+
+41. Implement PCRE2_LITERAL and use it to support REG_NOSPEC.
+
+42. Implement PCRE2_EXTRA_MATCH_LINE and PCRE2_EXTRA_MATCH_WORD for the benefit
+of pcre2grep.
+
+43. Re-implement pcre2grep's -F, -w, and -x options using PCRE2_LITERAL,
+PCRE2_EXTRA_MATCH_WORD, and PCRE2_EXTRA_MATCH_LINE. This fixes two bugs:
+
+    (a) The -F option did not work for fixed strings containing \E.
+    (b) The -w option did not work for patterns with multiple branches.
+
+44. Added configuration options for the SELinux compatible execmem allocator in
+JIT.
+
+45. Increased the limit for searching for a "must be present" code unit in
+subjects from 1000 to 2000 for 8-bit searches, since they use memchr() and are
+much faster.
+
+46. Arrange for anchored patterns to record and use "first code unit" data,
+because this can give a fast "no match" without searching for a "required code
+unit". Previously only non-anchored patterns did this.
+
+47. Upgraded the Unicode tables from Unicode 8.0.0 to Unicode 10.0.0.
+
+48. Add the callout_no_where modifier to pcre2test.
+
+49. Update extended grapheme breaking rules to the latest set that are in
+Unicode Standard Annex #29.
+
+50. Added experimental foreign pattern conversion facilities
+(pcre2_pattern_convert() and friends).
+
+51. Change the macro FWRITE, used in pcre2grep, to FWRITE_IGNORE because FWRITE
+is defined in a system header in cygwin. Also modified some of the #ifdefs in
+pcre2grep related to Windows and Cygwin support.
+
+52. Change 3(g) for 10.23 was a bit too zealous. If a hyphen that follows a
+character class is the last character in the class, Perl does not give a
+warning. PCRE2 now also treats this as a literal.
+
+53. Related to 52, though PCRE2 was throwing an error for [[:digit:]-X] it was
+not doing so for [\d-X] (and similar escapes), as is documented.
+
+54. Fixed a MIPS issue in the JIT compiler reported by Joshua Kinard.
+
+55. Fixed a "maybe uninitialized" warning for class_uchardata in \p handling in
+pcre2_compile() which could never actually trigger (code should have been cut
+out when Unicode support is disabled).
+
+
+Version 10.23 14-February-2017
+------------------------------
+
+1. Extended pcre2test with the utf8_input modifier so that it is able to
+generate all possible 16-bit and 32-bit code unit values in non-UTF modes.
+
+2. In any wide-character mode (8-bit UTF or any 16-bit or 32-bit mode), without
+PCRE2_UCP set, a negative character type such as \D in a positive class should
+cause all characters greater than 255 to match, whatever else is in the class.
+There was a bug that caused this not to happen if a Unicode property item was
+added to such a class, for example [\D\P{Nd}] or [\W\pL].
+
+3. There has been a major re-factoring of the pcre2_compile.c file. Most syntax
+checking is now done in the pre-pass that identifies capturing groups. This has
+reduced the amount of duplication and made the code tidier. While doing this,
+some minor bugs and Perl incompatibilities were fixed, including:
+
+  (a) \Q\E in the middle of a quantifier such as A+\Q\E+ is now ignored instead
+      of giving an invalid quantifier error.
+
+  (b) {0} can now be used after a group in a lookbehind assertion; previously
+      this caused an "assertion is not fixed length" error.
+
+  (c) Perl always treats (?(DEFINE) as a "define" group, even if a group with
+      the name "DEFINE" exists. PCRE2 now does likewise.
+
+  (d) A recursion condition test such as (?(R2)...) must now refer to an
+      existing subpattern.
+
+  (e) A conditional recursion test such as (?(R)...) misbehaved if there was a
+      group whose name began with "R".
+
+  (f) When testing zero-terminated patterns under valgrind, the terminating
+      zero is now marked "no access". This catches bugs that would otherwise
+      show up only with non-zero-terminated patterns.
+
+  (g) A hyphen appearing immediately after a POSIX character class (for example
+      /[[:ascii:]-z]/) now generates an error. Perl does accept this as a
+      literal, but gives a warning, so it seems best to fail it in PCRE.
+
+  (h) An empty \Q\E sequence may appear after a callout that precedes an
+      assertion condition (it is, of course, ignored).
+
+One effect of the refactoring is that some error numbers and messages have
+changed, and the pattern offset given for compiling errors is not always the
+right-most character that has been read. In particular, for a variable-length
+lookbehind assertion it now points to the start of the assertion. Another
+change is that when a callout appears before a group, the "length of next
+pattern item" that is passed now just gives the length of the opening
+parenthesis item, not the length of the whole group. A length of zero is now
+given only for a callout at the end of the pattern. Automatic callouts are no
+longer inserted before and after explicit callouts in the pattern.
+
+A number of bugs in the refactored code were subsequently fixed during testing
+before release, but after the code was made available in the repository. Many
+of the bugs were discovered by fuzzing testing. Several of them were related to
+the change from assuming a zero-terminated pattern (which previously had
+required non-zero terminated strings to be copied). These bugs were never in
+fully released code, but are noted here for the record.
+
+  (a) An overall recursion such as (?0) inside a lookbehind assertion was not
+      being diagnosed as an error.
+
+  (b) In utf mode, the length of a *MARK (or other verb) name was being checked
+      in characters instead of code units, which could lead to bad code being
+      compiled, leading to unpredictable behaviour.
+
+  (c) In extended /x mode, characters whose code was greater than 255 caused
+      a lookup outside one of the global tables. A similar bug existed for wide
+      characters in *VERB names.
+
+  (d) The amount of memory needed for a compiled pattern was miscalculated if a
+      lookbehind contained more than one toplevel branch and the first branch
+      was of length zero.
+
+  (e) In UTF-8 or UTF-16 modes with PCRE2_EXTENDED (/x) set and a non-zero-
+      terminated pattern, if a # comment ran on to the end of the pattern, one
+      or more code units past the end were being read.
+
+  (f) An unterminated repeat at the end of a non-zero-terminated pattern (e.g.
+      "{2,2") could cause reading beyond the pattern.
+
+  (g) When reading a callout string, if the end delimiter was at the end of the
+      pattern one further code unit was read.
+
+  (h) An unterminated number after \g' could cause reading beyond the pattern.
+
+  (i) An insufficient memory size was being computed for compiling with
+      PCRE2_AUTO_CALLOUT.
+
+  (j) A conditional group with an assertion condition used more memory than was
+      allowed for it during parsing, so too many of them could therefore
+      overrun a buffer.
+
+  (k) If parsing a pattern exactly filled the buffer, the internal test for
+      overrun did not check when the final META_END item was added.
+
+  (l) If a lookbehind contained a subroutine call, and the called group
+      contained an option setting such as (?s), and the PCRE2_ANCHORED option
+      was set, unpredictable behaviour could occur. The underlying bug was
+      incorrect code and insufficient checking while searching for the end of
+      the called subroutine in the parsed pattern.
+
+  (m) Quantifiers following (*VERB)s were not being diagnosed as errors.
+
+  (n) The use of \Q...\E in a (*VERB) name when PCRE2_ALT_VERBNAMES and
+      PCRE2_AUTO_CALLOUT were both specified caused undetermined behaviour.
+
+  (o) If \Q was preceded by a quantified item, and the following \E was
+      followed by '?' or '+', and there was at least one literal character
+      between them, an internal error "unexpected repeat" occurred (example:
+      /.+\QX\E+/).
+
+  (p) A buffer overflow could occur while sorting the names in the group name
+      list (depending on the order in which the names were seen).
+
+  (q) A conditional group that started with a callout was not doing the right
+      check for a following assertion, leading to compiling bad code. Example:
+      /(?(C'XX))?!XX/
+
+  (r) If a character whose code point was greater than 0xffff appeared within
+      a lookbehind that was within another lookbehind, the calculation of the
+      lookbehind length went wrong and could provoke an internal error.
+
+  (t) The sequence \E- or \Q\E- after a POSIX class in a character class caused
+      an internal error. Now the hyphen is treated as a literal.
+
+4. Back references are now permitted in lookbehind assertions when there are
+no duplicated group numbers (that is, (?| has not been used), and, if the
+reference is by name, there is only one group of that name. The referenced
+group must, of course be of fixed length.
+
+5. pcre2test has been upgraded so that, when run under valgrind with valgrind
+support enabled, reading past the end of the pattern is detected, both when
+compiling and during callout processing.
+
+6. \g{+<number>} (e.g. \g{+2} ) is now supported. It is a "forward back
+reference" and can be useful in repetitions (compare \g{-<number>} ). Perl does
+not recognize this syntax.
+
+7. Automatic callouts are no longer generated before and after callouts in the
+pattern.
+
+8. When pcre2test was outputing information from a callout, the caret indicator
+for the current position in the subject line was incorrect if it was after an
+escape sequence for a character whose code point was greater than \x{ff}.
+
+9. Change 19 for 10.22 had a typo (PCRE_STATIC_RUNTIME should be
+PCRE2_STATIC_RUNTIME). Fix from David Gaussmann.
+
+10. Added --max-buffer-size to pcre2grep, to allow for automatic buffer
+expansion when long lines are encountered. Original patch by Dmitry
+Cherniachenko.
+
+11. If pcre2grep was compiled with JIT support, but the library was compiled
+without it (something that neither ./configure nor CMake allow, but it can be
+done by editing config.h), pcre2grep was giving a JIT error. Now it detects
+this situation and does not try to use JIT.
+
+12. Added some "const" qualifiers to variables in pcre2grep.
+
+13. Added Dmitry Cherniachenko's patch for colouring output in Windows
+(untested by me). Also, look for GREP_COLOUR or GREP_COLOR if the environment
+variables PCRE2GREP_COLOUR and PCRE2GREP_COLOR are not found.
+
+14. Add the -t (grand total) option to pcre2grep.
+
+15. A number of bugs have been mended relating to match start-up optimizations
+when the first thing in a pattern is a positive lookahead. These all applied
+only when PCRE2_NO_START_OPTIMIZE was *not* set:
+
+    (a) A pattern such as (?=.*X)X$ was incorrectly optimized as if it needed
+        both an initial 'X' and a following 'X'.
+    (b) Some patterns starting with an assertion that started with .* were
+        incorrectly optimized as having to match at the start of the subject or
+        after a newline. There are cases where this is not true, for example,
+        (?=.*[A-Z])(?=.{8,16})(?!.*[\s]) matches after the start in lines that
+        start with spaces. Starting .* in an assertion is no longer taken as an
+        indication of matching at the start (or after a newline).
+
+16. The "offset" modifier in pcre2test was not being ignored (as documented)
+when the POSIX API was in use.
+
+17. Added --enable-fuzz-support to "configure", causing an non-installed
+library containing a test function that can be called by fuzzers to be
+compiled. A non-installed  binary to run the test function locally, called
+pcre2fuzzcheck is also compiled.
+
+18. A pattern with PCRE2_DOTALL (/s) set but not PCRE2_NO_DOTSTAR_ANCHOR, and
+which started with .* inside a positive lookahead was incorrectly being
+compiled as implicitly anchored.
+
+19. Removed all instances of "register" declarations, as they are considered
+obsolete these days and in any case had become very haphazard.
+
+20. Add strerror() to pcre2test for failed file opening.
+
+21. Make pcre2test -C list valgrind support when it is enabled.
+
+22. Add the use_length modifier to pcre2test.
+
+23. Fix an off-by-one bug in pcre2test for the list of names for 'get' and
+'copy' modifiers.
+
+24. Add PCRE2_CALL_CONVENTION into the prototype declarations in pcre2.h as it
+is apparently needed there as well as in the function definitions. (Why did
+nobody ask for this in PCRE1?)
+
+25. Change the _PCRE2_H and _PCRE2_UCP_H guard macros in the header files to
+PCRE2_H_IDEMPOTENT_GUARD and PCRE2_UCP_H_IDEMPOTENT_GUARD to be more standard
+compliant and unique.
+
+26. pcre2-config --libs-posix was listing -lpcre2posix instead of
+-lpcre2-posix. Also, the CMake build process was building the library with the
+wrong name.
+
+27. In pcre2test, give some offset information for errors in hex patterns.
+This uses the C99 formatting sequence %td, except for MSVC which doesn't
+support it - %lu is used instead.
+
+28. Implemented pcre2_code_copy_with_tables(), and added pushtablescopy to
+pcre2test for testing it.
+
+29. Fix small memory leak in pcre2test.
+
+30. Fix out-of-bounds read for partial matching of /./ against an empty string
+when the newline type is CRLF.
+
+31. Fix a bug in pcre2test that caused a crash when a locale was set either in
+the current pattern or a previous one and a wide character was matched.
+
+32. The appearance of \p, \P, or \X in a substitution string when
+PCRE2_SUBSTITUTE_EXTENDED was set caused a segmentation fault (NULL
+dereference).
+
+33. If the starting offset was specified as greater than the subject length in
+a call to pcre2_substitute() an out-of-bounds memory reference could occur.
+
+34. When PCRE2 was compiled to use the heap instead of the stack for recursive
+calls to match(), a repeated minimizing caseless back reference, or a
+maximizing one where the two cases had different numbers of code units,
+followed by a caseful back reference, could lose the caselessness of the first
+repeated back reference (example: /(Z)(a)\2{1,2}?(?-i)\1X/i should match ZaAAZX
+but didn't).
+
+35. When a pattern is too complicated, PCRE2 gives up trying to find a minimum
+matching length and just records zero. Typically this happens when there are
+too many nested or recursive back references. If the limit was reached in
+certain recursive cases it failed to be triggered and an internal error could
+be the result.
+
+36. The pcre2_dfa_match() function now takes note of the recursion limit for
+the internal recursive calls that are used for lookrounds and recursions within
+the pattern.
+
+37. More refactoring has got rid of the internal could_be_empty_branch()
+function (around 400 lines of code, including comments) by keeping track of
+could-be-emptiness as the pattern is compiled instead of scanning compiled
+groups. (This would have been much harder before the refactoring of #3 above.)
+This lifts a restriction on the number of branches in a group (more than about
+1100 would give "pattern is too complicated").
+
+38. Add the "-ac" command line option to pcre2test as a synonym for "-pattern
+auto_callout".
+
+39. In a library with Unicode support, incorrect data was compiled for a
+pattern with PCRE2_UCP set without PCRE2_UTF if a class required all wide
+characters to match (for example, /[\s[:^ascii:]]/).
+
+40. The callout_error modifier has been added to pcre2test to make it possible
+to return PCRE2_ERROR_CALLOUT from a callout.
+
+41. A minor change to pcre2grep: colour reset is now "<esc>[0m" instead of
+"<esc>[00m".
+
+42. The limit in the auto-possessification code that was intended to catch
+overly-complicated patterns and not spend too much time auto-possessifying was
+being reset too often, resulting in very long compile times for some patterns.
+Now such patterns are no longer completely auto-possessified.
+
+43. Applied Jason Hood's revised patch for RunTest.bat.
+
+44. Added a new Windows script RunGrepTest.bat, courtesy of Jason Hood.
+
+45. Minor cosmetic fix to pcre2test: move a variable that is not used under
+Windows into the "not Windows" code.
+
+46. Applied Jason Hood's patches to upgrade pcre2grep under Windows and tidy
+some of the code:
+
+  * normalised the Windows condition by ensuring WIN32 is defined;
+  * enables the callout feature under Windows;
+  * adds globbing (Microsoft's implementation expands quoted args),
+    using a tweaked opendirectory;
+  * implements the is_*_tty functions for Windows;
+  * --color=always will write the ANSI sequences to file;
+  * add sequences 4 (underline works on Win10) and 5 (blink as bright
+    background, relatively standard on DOS/Win);
+  * remove the (char *) casts for the now-const strings;
+  * remove GREP_COLOUR (grep's command line allowed the 'u', but not
+    the environment), parsing GREP_COLORS instead;
+  * uses the current colour if not set, rather than black;
+  * add print_match for the undefined case;
+  * fixes a typo.
+
+In addition, colour settings containing anything other than digits and
+semicolon are ignored, and the colour controls are no longer output for empty
+strings.
+
+47. Detecting patterns that are too large inside the length-measuring loop
+saves processing ridiculously long patterns to their end.
+
+48. Ignore PCRE2_CASELESS when processing \h, \H, \v, and \V in classes as it
+just wastes time. In the UTF case it can also produce redundant entries in
+XCLASS lists caused by characters with multiple other cases and pairs of
+characters in the same "not-x" sublists.
+
+49. A pattern such as /(?=(a\K))/ can report the end of the match being before
+its start; pcre2test was not handling this correctly when using the POSIX
+interface (it was OK with the native interface).
+
+50. In pcre2grep, ignore all JIT compile errors. This means that pcre2grep will
+continue to work, falling back to interpretation if anything goes wrong with
+JIT.
+
+51. Applied patches from Christian Persch to configure.ac to make use of the
+AC_USE_SYSTEM_EXTENSIONS macro and to test for functions used by the JIT
+modules.
+
+52. Minor fixes to pcre2grep from Jason Hood:
+    * fixed some spacing;
+    * Windows doesn't usually use single quotes, so I've added a define
+      to use appropriate quotes [in an example];
+    * LC_ALL was displayed as "LCC_ALL";
+    * numbers 11, 12 & 13 should end in "th";
+    * use double quotes in usage message.
+
+53. When autopossessifying, skip empty branches without recursion, to reduce
+stack usage for the benefit of clang with -fsanitize-address, which uses huge
+stack frames. Example pattern: /X?(R||){3335}/. Fixes oss-fuzz issue 553.
+
+54. A pattern with very many explicit back references to a group that is a long
+way from the start of the pattern could take a long time to compile because
+searching for the referenced group in order to find the minimum length was
+being done repeatedly. Now up to 128 group minimum lengths are cached and the
+attempt to find a minimum length is abandoned if there is a back reference to a
+group whose number is greater than 128. (In that case, the pattern is so
+complicated that this optimization probably isn't worth it.) This fixes
+oss-fuzz issue 557.
+
+55. Issue 32 for 10.22 below was not correctly fixed. If pcre2grep in multiline
+mode with --only-matching matched several lines, it restarted scanning at the
+next line instead of moving on to the end of the matched string, which can be
+several lines after the start.
+
+56. Applied Jason Hood's new patch for RunGrepTest.bat that updates it in line
+with updates to the non-Windows version.
+
+
+
 Version 10.22 29-July-2016
 --------------------------
 
diff --git a/dist2/HACKING b/dist2/HACKING
index 883aa64..d727add 100644
--- a/dist2/HACKING
+++ b/dist2/HACKING
@@ -7,8 +7,8 @@
 library is referred to as PCRE1 below. For information about testing PCRE2, see
 the pcre2test documentation and the comment at the head of the RunTest file.
 
-PCRE1 releases were up to 8.3x when PCRE2 was developed. The 8.xx series will
-continue for bugfixes if necessary. PCRE2 releases started at 10.00 to avoid
+PCRE1 releases were up to 8.3x when PCRE2 was developed, and later bug fix
+releases remain in the 8.xx series. PCRE2 releases started at 10.00 to avoid
 confusion with PCRE1.
 
 
@@ -16,19 +16,20 @@
 -----------------
 
 Many years ago I implemented some regular expression functions to an algorithm
-suggested by Martin Richards. These were not Unix-like in form, and were quite
-restricted in what they could do by comparison with Perl. The interesting part
-about the algorithm was that the amount of space required to hold the compiled
-form of an expression was known in advance. The code to apply an expression did
-not operate by backtracking, as the original Henry Spencer code and current
-PCRE2 and Perl code does, but instead checked all possibilities simultaneously
-by keeping a list of current states and checking all of them as it advanced
-through the subject string. In the terminology of Jeffrey Friedl's book, it was
-a "DFA algorithm", though it was not a traditional Finite State Machine (FSM).
-When the pattern was all used up, all remaining states were possible matches,
-and the one matching the longest subset of the subject string was chosen. This
-did not necessarily maximize the individual wild portions of the pattern, as is
-expected in Unix and Perl-style regular expressions.
+suggested by Martin Richards. The rather simple patterns were not Unix-like in
+form, and were quite restricted in what they could do by comparison with Perl.
+The interesting part about the algorithm was that the amount of space required
+to hold the compiled form of an expression was known in advance. The code to
+apply an expression did not operate by backtracking, as the original Henry
+Spencer code and current PCRE2 and Perl code does, but instead checked all
+possibilities simultaneously by keeping a list of current states and checking
+all of them as it advanced through the subject string. In the terminology of
+Jeffrey Friedl's book, it was a "DFA algorithm", though it was not a
+traditional Finite State Machine (FSM). When the pattern was all used up, all
+remaining states were possible matches, and the one matching the longest subset
+of the subject string was chosen. This did not necessarily maximize the
+individual wild portions of the pattern, as is expected in Unix and Perl-style
+regular expressions.
 
 
 Historical note 2
@@ -47,18 +48,20 @@
 OK, here's the real stuff
 -------------------------
 
-For the set of functions that formed the original PCRE1 library (which are
-unrelated to those mentioned above), I tried at first to invent an algorithm
-that used an amount of store bounded by a multiple of the number of characters
-in the pattern, to save on compiling time. However, because of the greater
-complexity in Perl regular expressions, I couldn't do this. In any case, a
-first pass through the pattern is helpful for other reasons.
+For the set of functions that formed the original PCRE1 library in 1997 (which
+are unrelated to those mentioned above), I tried at first to invent an
+algorithm that used an amount of store bounded by a multiple of the number of
+characters in the pattern, to save on compiling time. However, because of the
+greater complexity in Perl regular expressions, I couldn't do this, even though
+the then current Perl 5.004 patterns were much simpler than those supported
+nowadays. In any case, a first pass through the pattern is helpful for other
+reasons.
 
 
 Support for 16-bit and 32-bit data strings
 -------------------------------------------
 
-The library can be compiled in any combination of 8-bit, 16-bit or 32-bit
+The PCRE2 library can be compiled in any combination of 8-bit, 16-bit or 32-bit
 modes, creating up to three different libraries. In the description that
 follows, the word "short" is used for a 16-bit data quantity, and the phrase
 "code unit" is used for a quantity that is a byte in 8-bit mode, a short in
@@ -85,12 +88,12 @@
 things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then
 I had a flash of inspiration as to how I could run the real compile function in
 a "fake" mode that enables it to compute how much memory it would need, while
-actually only ever using a few hundred bytes of working memory, and without too
+in most cases only ever using a small amount of working memory, and without too
 many tests of the mode that might slow it down. So I refactored the compiling
-functions to work this way. This got rid of about 600 lines of source. It
-should make future maintenance and development easier. As this was such a major
-change, I never released 6.8, instead upping the number to 7.0 (other quite
-major changes were also present in the 7.0 release).
+functions to work this way. This got rid of about 600 lines of source and made
+further maintenance and development easier. As this was such a major change, I
+never released 6.8, instead upping the number to 7.0 (other quite major changes
+were also present in the 7.0 release).
 
 A side effect of this work was that the previous limit of 200 on the nesting
 depth of parentheses was removed. However, there was a downside: compiling ran
@@ -104,20 +107,208 @@
 for nested parenthesized groups. This is a safety feature for environments with
 small stacks where the patterns are provided by users.
 
-History repeated itself for release 10.20. A number of bugs relating to named 
-subpatterns had been discovered by fuzzers. Most of these were related to the 
-handling of forward references when it was not known if the named pattern was
+
+Yet another pattern scan
+------------------------
+
+History repeated itself for PCRE2 release 10.20. A number of bugs relating to
+named subpatterns had been discovered by fuzzers. Most of these were related to
+the handling of forward references when it was not known if the named group was
 unique. (References to non-unique names use a different opcode and more
 memory.) The use of duplicate group numbers (the (?| facility) also caused
-issues. 
+issues.
 
-To get around these problems I adopted a new approach by adding a third pass,
-really a "pre-pass", over the pattern, which does nothing other than identify
-all the named subpatterns and their corresponding group numbers. This means 
-that the actual compile (both pre-pass and real compile) have full knowledge of 
-group names and numbers throughout. Several dozen lines of messy code were 
-eliminated, though the new pre-pass is not short (skipping over [] classes is 
-complicated).
+To get around these problems I adopted a new approach by adding a third pass
+over the pattern (really a "pre-pass"), which did nothing other than identify
+all the named subpatterns and their corresponding group numbers. This means
+that the actual compile (both the memory-computing dummy run and the real
+compile) has full knowledge of group names and numbers throughout. Several
+dozen lines of messy code were eliminated, though the new pre-pass was not
+short. In particular, parsing and skipping over [] classes is complicated.
+
+While working on 10.22 I realized that I could simplify yet again by moving
+more of the parsing into the pre-pass, thus avoiding doing it in two places, so
+after 10.22 was released, the code underwent yet another big refactoring. This
+is how it is from 10.23 onwards:
+
+The function called parse_regex() scans the pattern characters, parsing them
+into literal data and meta characters. It converts escapes such as \x{123}
+into literals, handles \Q...\E, and skips over comments and non-significant
+white space. The result of the scanning is put into a vector of 32-bit unsigned
+integers. Values less than 0x80000000 are literal data. Higher values represent
+meta-characters. The top 16-bits of such values identify the meta-character,
+and these are given names such as META_CAPTURE. The lower 16-bits are available
+for data, for example, the capturing group number. The only situation in which
+literal data values greater than 0x7fffffff can appear is when the 32-bit
+library is running in non-UTF mode. This is handled by having a special
+meta-character that is followed by the 32-bit data value.
+
+The size of the parsed pattern vector, when auto-callouts are not enabled, is
+bounded by the length of the pattern (with one exception). The code is written
+so that each item in the pattern uses no more vector elements than the number
+of code units in the item itself. The exception is the aforementioned large
+32-bit number handling. For this reason, 32-bit non-UTF patterns are scanned in
+advance to check for such values. When auto-callouts are enabled, the generous
+assumption is made that there will be a callout for each pattern code unit
+(which of course is only actually true if all code units are literals) plus one
+at the end. There is a default parsed pattern vector on the system stack, but
+if this is not big enough, heap memory is used.
+
+As before, the actual compiling function is run twice, the first time to
+determine the amount of memory needed for the final compiled pattern. It
+now processes the parsed pattern vector, not the pattern itself, although some
+of the parsed items refer to strings in the pattern - for example, group
+names. As escapes and comments have already been processed, the code is a bit
+simpler than before.
+
+Most errors can be diagnosed during the parsing scan. For those that cannot
+(for example, "lookbehind assertion is not fixed length"), the parsed code
+contains offsets into the pattern so that the actual compiling code can
+report where errors are.
+
+
+The elements of the parsed pattern vector
+-----------------------------------------
+
+The word "offset" below means a code unit offset into the pattern. When
+PCRE2_SIZE (which is usually size_t) is no bigger than uint32_t, an offset is
+stored in a single parsed pattern element. Otherwise (typically on 64-bit
+systems) it occupies two elements. The following meta items occupy just one
+element, with no data:
+
+META_ACCEPT           (*ACCEPT)
+META_ASTERISK         *
+META_ASTERISK_PLUS    *+
+META_ASTERISK_QUERY   *?
+META_ATOMIC           (?> start of atomic group
+META_CIRCUMFLEX       ^ metacharacter
+META_CLASS            [ start of non-empty class
+META_CLASS_EMPTY      [] empty class - only with PCRE2_ALLOW_EMPTY_CLASS
+META_CLASS_EMPTY_NOT  [^] negative empty class - ditto
+META_CLASS_END        ] end of non-empty class
+META_CLASS_NOT        [^ start non-empty negative class
+META_COMMIT           (*COMMIT)
+META_COND_ASSERT      (?(?assertion)
+META_DOLLAR           $ metacharacter
+META_DOT              . metacharacter
+META_END              End of pattern (this value is 0x80000000)
+META_FAIL             (*FAIL)
+META_KET              ) closing parenthesis
+META_LOOKAHEAD        (?= start of lookahead
+META_LOOKAHEADNOT     (?! start of negative lookahead
+META_NOCAPTURE        (?: no capture parens
+META_PLUS             +
+META_PLUS_PLUS        ++
+META_PLUS_QUERY       +?
+META_PRUNE            (*PRUNE) - no argument
+META_QUERY            ?
+META_QUERY_PLUS       ?+
+META_QUERY_QUERY      ??
+META_RANGE_ESCAPED    hyphen in class range with at least one escape
+META_RANGE_LITERAL    hyphen in class range defined literally
+META_SKIP             (*SKIP) - no argument
+META_THEN             (*THEN) - no argument
+
+The two RANGE values occur only in character classes. They are positioned
+between two literals that define the start and end of the range. In an EBCDIC
+evironment it is necessary to know whether either of the range values was
+specified as an escape. In an ASCII/Unicode environment the distinction is not
+relevant.
+
+The following have data in the lower 16 bits, and may be followed by other data
+elements:
+
+META_ALT              | alternation
+META_BACKREF          back reference
+META_CAPTURE          start of capturing group
+META_ESCAPE           non-literal escape sequence
+META_RECURSE          recursion call
+
+If the data for META_ALT is non-zero, it is inside a lookbehind, and the data
+is the length of its branch, for which OP_REVERSE must be generated.
+
+META_BACKREF, META_CAPTURE, and META_RECURSE have the capture group number as
+their data in the lower 16 bits of the element.
+
+META_BACKREF is followed by an offset if the back reference group number is 10
+or more. The offsets of the first ocurrences of references to groups whose
+numbers are less than 10 are put in cb->small_ref_offset[] (only the first
+occurrence is useful). On 64-bit systems this avoids using more than two parsed
+pattern elements for items such as \3. The offset is used when an error occurs
+because the reference is to a non-existent group.
+
+META_RECURSE is always followed by an offset, for use in error messages.
+
+META_ESCAPE has an ESC_xxx value as its data. For ESC_P and ESC_p, the next
+element contains the 16-bit type and data property values, packed together.
+ESC_g and ESC_k are used only for named references - numerical ones are turned
+into META_RECURSE or META_BACKREF as appropriate. ESC_g and ESC_k are followed
+by a length and an offset into the pattern to specify the name.
+
+The following have one data item that follows in the next vector element:
+
+META_BIGVALUE         Next is a literal >= META_END
+META_OPTIONS          (?i) and friends (data is new option bits)
+META_POSIX            POSIX class item (data identifies the class)
+META_POSIX_NEG        negative POSIX class item (ditto)
+
+The following are followed by a length element, then a number of character code
+values (which should match with the length):
+
+META_MARK             (*MARK:xxxx)
+META_PRUNE_ARG        (*PRUNE:xxx)
+META_SKIP_ARG         (*SKIP:xxxx)
+META_THEN_ARG         (*THEN:xxxx)
+
+The following are followed by a length element, then an offset in the pattern
+that identifies the name:
+
+META_COND_NAME        (?(<name>) or (?('name') or (?(name)
+META_COND_RNAME       (?(R&name)
+META_COND_RNUMBER     (?(Rdigits)
+META_RECURSE_BYNAME   (?&name)
+META_BACKREF_BYNAME   \k'name'
+
+META_COND_RNUMBER is used for names that start with R and continue with digits,
+because this is an ambiguous case. It could be a back reference to a group with
+that name, or it could be a recursion test on a numbered group.
+
+This one is followed by an offset, for use in error messages, then a number:
+
+META_COND_NUMBER       (?([+-]digits)
+
+The following is followed just by an offset, for use in error messages:
+
+META_COND_DEFINE      (?(DEFINE)
+
+The following are also followed just by an offset, but also the lower 16 bits
+of the main word contain the length of the first branch of the lookbehind
+group; this is used when generating OP_REVERSE for that branch.
+
+META_LOOKBEHIND       (?<=
+META_LOOKBEHINDNOT    (?<!
+
+The following are followed by two elements, the minimum and maximum. Repeat
+values are limited to 65535 (MAX_REPEAT). A maximum value of "unlimited" is
+represented by UNLIMITED_REPEAT, which is bigger than MAX_REPEAT:
+
+META_MINMAX           {n,m}  repeat
+META_MINMAX_PLUS      {n,m}+ repeat
+META_MINMAX_QUERY     {n,m}? repeat
+
+This one is followed by three elements. The first is 0 for '>' and 1 for '>=';
+the next two are the major and minor numbers:
+
+META_COND_VERSION     (?(VERSION<op>x.y)
+
+Callouts are converted into one of two items:
+
+META_CALLOUT_NUMBER   (?C with numerical argument
+META_CALLOUT_STRING   (?C with string argument
+
+In both cases, the next two elements contain the offset and length of the next
+item in the pattern. Then there is either one callout number, or a length and
+an offset for the string argument. The length includes both delimiters.
 
 
 Traditional matching function
@@ -154,9 +345,14 @@
 ------------------
 
 The /i, /m, or /s options (PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL, and
-some others) may change in the middle of patterns. Their processing is handled
-entirely at compile time by generating different opcodes for the different
-settings. The runtime functions do not need to keep track of an options state.
+others) may be changed in the middle of patterns by items such as (?i). Their
+processing is handled entirely at compile time by generating different opcodes
+for the different settings. The runtime functions do not need to keep track of
+an options state.
+
+PCRE2_DUPNAMES, PCRE2_EXTENDED, PCRE2_EXTENDED_MORE, and PCRE2_NO_AUTO_CAPTURE
+are tracked and processed during the parsing pre-pass. The others are handled
+from META_OPTIONS items during the main compile phase.
 
 
 Format of compiled patterns
@@ -180,7 +376,7 @@
 
 In this description, we assume the "normal" compilation options. Data values
 that are counts (e.g. quantifiers) are always two bytes long in 8-bit mode
-(most significant byte first), or one code unit in 16-bit and 32-bit modes.
+(most significant byte first), and one code unit in 16-bit and 32-bit modes.
 
 
 Opcodes with no following data
@@ -220,16 +416,16 @@
   OP_ACCEPT              ) These are Perl 5.10's "backtracking control
   OP_COMMIT              ) verbs". If OP_ACCEPT is inside capturing
   OP_FAIL                ) parentheses, it may be preceded by one or more
-  OP_PRUNE               ) OP_CLOSE, each followed by a count that
+  OP_PRUNE               ) OP_CLOSE, each followed by a number that
   OP_SKIP                ) indicates which parentheses must be closed.
   OP_THEN                )
 
 OP_ASSERT_ACCEPT is used when (*ACCEPT) is encountered within an assertion.
-This ends the assertion, not the entire pattern match. The assertion (?!) is 
+This ends the assertion, not the entire pattern match. The assertion (?!) is
 always optimized to OP_FAIL.
 
 OP_ALLANY is used for '.' when PCRE2_DOTALL is set. It is also used for \C in
-non-UTF modes and in UTF-32 mode (since one code unit still equals one 
+non-UTF modes and in UTF-32 mode (since one code unit still equals one
 character). Another use is for [^] when empty classes are permitted
 (PCRE2_ALLOW_EMPTY_CLASS is set).
 
@@ -248,14 +444,22 @@
 ---------------------------
 
 The OP_CHAR opcode is followed by a single character that is to be matched
-casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes,
-the character may be more than one code unit long. In UTF-32 mode, characters
-are always exactly one code unit long.
+casefully. For caseless matching of characters that have at most two
+case-equivalent code points, OP_CHARI is used. In UTF-8 or UTF-16 modes, the
+character may be more than one code unit long. In UTF-32 mode, characters are
+always exactly one code unit long.
 
 If there is only one character in a character class, OP_CHAR or OP_CHARI is
 used for a positive class, and OP_NOT or OP_NOTI for a negative one (that is,
 for something like [^a]).
 
+Caseless matching (positive or negative) of characters that have more than two
+case-equivalent code points (which is possible only in UTF mode) is handled by
+compiling a Unicode property item (see below), with the pseudo-property
+PT_CLIST. The value of this property is an offset in a vector called
+"ucd_caseless_sets" which identifies the start of a short list of equivalent
+characters, terminated by the value NOTACHAR (0xffffffff).
+
 
 Repeating single characters
 ---------------------------
@@ -331,7 +535,8 @@
 and a value. The types are a set of #defines of the form PT_xxx, and the values
 are enumerations of the form ucp_xx, defined in the pcre2_ucp.h source file.
 The value is relevant only for PT_GC (General Category), PT_PC (Particular
-Category), and PT_SC (Script).
+Category), PT_SC (Script), and the pseudo-property PT_CLIST, which is used to
+identify a list of case-equivalent characters when there are three or more.
 
 Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by
 three code units: OP_PROP or OP_NOTPROP, and then the desired property type and
@@ -343,7 +548,10 @@
 
 If there is only one character in a class, OP_CHAR or OP_CHARI is used for a
 positive class, and OP_NOT or OP_NOTI for a negative one (that is, for
-something like [^a]).
+something like [^a]), except when caselessly matching a character that has more
+than two case-equivalent code points (which can happen only in UTF mode). In
+this case a Unicode property item is used, as described above in "Matching
+literal characters".
 
 A set of repeating opcodes (called OP_NOTSTAR etc.) are used for repeated,
 negated, single-character classes. The normal single-character opcodes
@@ -364,8 +572,8 @@
 For classes containing characters with values greater than 255 or that contain
 \p or \P, OP_XCLASS is used. It optionally uses a bit map if any acceptable
 code points are less than 256, followed by a list of pairs (for a range) and/or
-single characters and/or properties. In caseless mode, both cases are
-explicitly listed.
+single characters and/or properties. In caseless mode, all equivalent
+characters are explicitly listed.
 
 OP_XCLASS is followed by a LINK_SIZE value containing the total length of the
 opcode and its data. This is followed by a code unit containing flag bits:
@@ -422,8 +630,8 @@
   OP_CRMINRANGE
   OP_CRPOSRANGE
 
-All but the last three are single-code-unit items, with no data. The others are
-followed by the minimum and maximum repeat counts.
+All but the last three are single-code-unit items, with no data. The range
+opcodes are followed by the minimum and maximum repeat counts.
 
 
 Brackets and alternation
@@ -438,16 +646,17 @@
 
 Non-capturing brackets use the opcode OP_BRA, capturing brackets use OP_CBRA. A
 bracket opcode is followed by a LINK_SIZE value which gives the offset to the
-next alternative OP_ALT or, if there aren't any branches, to the matching
-OP_KET opcode. Each OP_ALT is followed by a LINK_SIZE value giving the offset
-to the next one, or to the OP_KET opcode. For capturing brackets, the bracket
-number is a count that immediately follows the offset.
+next alternative OP_ALT or, if there aren't any branches, to the terminating
+opcode. Each OP_ALT is followed by a LINK_SIZE value giving the offset to the
+next one, or to the final opcode. For capturing brackets, the bracket number is
+a count that immediately follows the offset.
 
-OP_KET is used for subpatterns that do not repeat indefinitely, and OP_KETRMIN
-and OP_KETRMAX are used for indefinite repetitions, minimally or maximally
-respectively (see below for possessive repetitions). All three are followed by
-a LINK_SIZE value giving (as a positive number) the offset back to the matching
-bracket opcode.
+There are several opcodes that mark the end of a subpattern group. OP_KET is
+used for subpatterns that do not repeat indefinitely, OP_KETRMIN and
+OP_KETRMAX are used for indefinite repetitions, minimally or maximally
+respectively, and OP_KETRPOS for possessive repetitions (see below for more 
+details). All four are followed by a LINK_SIZE value giving (as a positive
+number) the offset back to the matching bracket opcode.
 
 If a subpattern is quantified such that it is permitted to match zero times, it
 is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are
@@ -488,17 +697,9 @@
 Once-only (atomic) groups
 -------------------------
 
-These are just like other subpatterns, but they start with the opcode
-OP_ONCE or OP_ONCE_NC. The former is used when there are no capturing brackets
-within the atomic group; the latter when there are. The distinction is needed
-for when there is a backtrack to before the group - any captures within the
-group must be reset, so it is necessary to retain backtracking points inside
-the group, even after it is complete, in order to do this. When there are no
-captures in an atomic group, all the backtracking can be discarded when it is
-complete. This is more efficient, and also uses less stack.
-
+These are just like other subpatterns, but they start with the opcode OP_ONCE.
 The check for matching an empty string in an unbounded repeat is handled
-entirely at runtime, so there are just these two opcodes for atomic groups.
+entirely at runtime, so there is just this one opcode for atomic groups.
 
 
 Assertions
@@ -544,14 +745,14 @@
 or OP_FALSE.
 
 If a condition is not a back reference, recursion test, DEFINE, or VERSION, it
-must start with an assertion, whose opcode normally immediately follows OP_COND
-or OP_SCOND. However, if automatic callouts are enabled, a callout is inserted
-immediately before the assertion. It is also possible to insert a manual
-callout at this point. Only assertion conditions may have callouts preceding
-the condition.
+must start with a parenthesized assertion, whose opcode normally immediately
+follows OP_COND or OP_SCOND. However, if automatic callouts are enabled, a
+callout is inserted immediately before the assertion. It is also possible to
+insert a manual callout at this point. Only assertion conditions may have
+callouts preceding the condition.
 
-A condition that is the negative assertion (?!) is optimized to OP_FAIL in all 
-parts of the pattern, so this is another opcode that may appear as a condition. 
+A condition that is the negative assertion (?!) is optimized to OP_FAIL in all
+parts of the pattern, so this is another opcode that may appear as a condition.
 It is treated the same as OP_FALSE.
 
 
@@ -561,21 +762,28 @@
 Recursion either matches the current pattern, or some subexpression. The opcode
 OP_RECURSE is followed by a LINK_SIZE value that is the offset to the starting
 bracket from the start of the whole pattern. OP_RECURSE is also used for
-"subroutine" calls, even though they are not strictly a recursion. Repeated
-recursions are automatically wrapped inside OP_ONCE brackets, because otherwise
-some patterns broke them. A non-repeated recursion is not wrapped in OP_ONCE
-brackets, but it is nevertheless still treated as an atomic group.
+"subroutine" calls, even though they are not strictly a recursion. Up till
+release 10.30 recursions were treated as atomic groups, making them
+incompatible with Perl (but PCRE had then well before Perl did). From 10.30,
+backtracking into recursions is supported.
+
+Repeated recursions used to be wrapped inside OP_ONCE brackets, which not only
+forced no backtracking, but also allowed repetition to be handled as for other
+bracketed groups. From 10.30 onwards, repeated recursions are duplicated for
+their minimum repetitions, and then wrapped in non-capturing brackets for the
+remainder. For example, (?1){3} is treated as (?1)(?1)(?1), and (?1){2,4} is
+treated as (?1)(?1)(?:(?1)){0,2}.
 
 
-Callout
--------
+Callouts
+--------
 
-A callout can nowadays have either a numerical argument or a string argument.
-These use OP_CALLOUT or OP_CALLOUT_STR, respectively. In each case these are
-followed by two LINK_SIZE values giving the offset in the pattern string to the
-start of the following item, and another count giving the length of this item.
-These values make it possible for pcre2test to output useful tracing
-information using callouts.
+A callout may have either a numerical argument or a string argument. These use
+OP_CALLOUT or OP_CALLOUT_STR, respectively. In each case these are followed by
+two LINK_SIZE values giving the offset in the pattern string to the start of
+the following item, and another count giving the length of this item. These
+values make it possible for pcre2test to output useful tracing information
+using callouts.
 
 In the case of a numeric callout, after these two values there is a single code
 unit containing the callout number, in the range 0-255, with 255 being used for
@@ -593,17 +801,17 @@
 the application needs it. In the 8-bit library, the callout in /X(?C'abc')Y/ is
 compiled as the following bytes (decimal numbers represent binary values):
 
-  [OP_CALLOUT]  [0] [10]  [0] [1]  [0] [14]  [0] [5] ['] [a] [b] [c] [0]
-                --------  -------  --------  -------
-                   |         |        |         |
-                   ------- LINK_SIZE items ------
+  [OP_CALLOUT_STR]  [0] [10]  [0] [1]  [0] [14]  [0] [5] ['] [a] [b] [c] [0]
+                    --------  -------  --------  -------
+                       |         |        |         |
+                       ------- LINK_SIZE items ------
 
 Opcode table checking
 ---------------------
 
 The last opcode that is defined in pcre2_internal.h is OP_TABLE_LENGTH. This is
-not a real opcode, but is used to check that tables indexed by opcode are the
-correct length, in order to catch updating errors.
+not a real opcode, but is used to check at compile time that tables indexed by
+opcode are the correct length, in order to catch updating errors.
 
 Philip Hazel
-June 2016
+21 April 2017
diff --git a/dist2/INSTALL b/dist2/INSTALL
index 2099840..8865734 100644
--- a/dist2/INSTALL
+++ b/dist2/INSTALL
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
-Inc.
+   Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
+Foundation, Inc.
 
    Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
@@ -12,97 +12,96 @@
 Basic Installation
 ==================
 
-   Briefly, the shell command `./configure && make && make install'
+   Briefly, the shell command './configure && make && make install'
 should configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
+more-detailed instructions are generic; see the 'README' file for
 instructions specific to this package.  Some packages provide this
-`INSTALL' file but do not implement all of the features documented
+'INSTALL' file but do not implement all of the features documented
 below.  The lack of an optional feature in a given package is not
 necessarily a bug.  More recommendations for GNU packages can be found
 in *note Makefile Conventions: (standards)Makefile Conventions.
 
-   The `configure' shell script attempts to guess correct values for
+   The 'configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
+those values to create a 'Makefile' in each directory of the package.
+It may also create one or more '.h' files containing system-dependent
+definitions.  Finally, it creates a shell script 'config.status' that
 you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
+file 'config.log' containing compiler output (useful mainly for
+debugging 'configure').
 
-   It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
+   It can also use an optional file (typically called 'config.cache' and
+enabled with '--cache-file=config.cache' or simply '-C') that saves the
+results of its tests to speed up reconfiguring.  Caching is disabled by
+default to prevent problems with accidental use of stale cache files.
 
    If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
+to figure out how 'configure' could check whether to do them, and mail
+diffs or instructions to the address given in the 'README' so they can
 be considered for the next release.  If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
+some point 'config.cache' contains results you don't want to keep, you
 may remove or edit it.
 
-   The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
+   The file 'configure.ac' (or 'configure.in') is used to create
+'configure' by a program called 'autoconf'.  You need 'configure.ac' if
+you want to change it or regenerate 'configure' using a newer version of
+'autoconf'.
 
    The simplest way to compile this package is:
 
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.
+  1. 'cd' to the directory containing the package's source code and type
+     './configure' to configure the package for your system.
 
-     Running `configure' might take a while.  While running, it prints
+     Running 'configure' might take a while.  While running, it prints
      some messages telling which features it is checking for.
 
-  2. Type `make' to compile the package.
+  2. Type 'make' to compile the package.
 
-  3. Optionally, type `make check' to run any self-tests that come with
+  3. Optionally, type 'make check' to run any self-tests that come with
      the package, generally using the just-built uninstalled binaries.
 
-  4. Type `make install' to install the programs and any data files and
+  4. Type 'make install' to install the programs and any data files and
      documentation.  When installing into a prefix owned by root, it is
      recommended that the package be configured and built as a regular
-     user, and only the `make install' phase executed with root
+     user, and only the 'make install' phase executed with root
      privileges.
 
-  5. Optionally, type `make installcheck' to repeat any self-tests, but
+  5. Optionally, type 'make installcheck' to repeat any self-tests, but
      this time using the binaries in their final installed location.
      This target does not install anything.  Running this target as a
-     regular user, particularly if the prior `make install' required
+     regular user, particularly if the prior 'make install' required
      root privileges, verifies that the installation completed
      correctly.
 
   6. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
+     source code directory by typing 'make clean'.  To also remove the
+     files that 'configure' created (so you can compile the package for
+     a different kind of computer), type 'make distclean'.  There is
+     also a 'make maintainer-clean' target, but that is intended mainly
      for the package's developers.  If you use it, you may have to get
      all sorts of other programs in order to regenerate files that came
      with the distribution.
 
-  7. Often, you can also type `make uninstall' to remove the installed
+  7. Often, you can also type 'make uninstall' to remove the installed
      files again.  In practice, not all packages have tested that
      uninstallation works correctly, even though it is required by the
      GNU Coding Standards.
 
-  8. Some packages, particularly those that use Automake, provide `make
+  8. Some packages, particularly those that use Automake, provide 'make
      distcheck', which can by used by developers to test that all other
-     targets like `make install' and `make uninstall' work correctly.
+     targets like 'make install' and 'make uninstall' work correctly.
      This target is generally not run by end users.
 
 Compilers and Options
 =====================
 
    Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  Run `./configure --help'
+the 'configure' script does not know about.  Run './configure --help'
 for details on some of the pertinent environment variables.
 
-   You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment.  Here
-is an example:
+   You can give 'configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here is
+an example:
 
      ./configure CC=c99 CFLAGS=-g LIBS=-lposix
 
@@ -113,21 +112,21 @@
 
    You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU `make'.  `cd' to the
+own directory.  To do this, you can use GNU 'make'.  'cd' to the
 directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.  This
-is known as a "VPATH" build.
+the 'configure' script.  'configure' automatically checks for the source
+code in the directory that 'configure' is in and in '..'.  This is known
+as a "VPATH" build.
 
-   With a non-GNU `make', it is safer to compile the package for one
+   With a non-GNU 'make', it is safer to compile the package for one
 architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use `make distclean' before
+installed the package for one architecture, use 'make distclean' before
 reconfiguring for another architecture.
 
    On MacOS X 10.5 and later systems, you can create libraries and
 executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor.  Like
+"universal" binaries--by specifying multiple '-arch' options to the
+compiler but only a single '-arch' option to the preprocessor.  Like
 this:
 
      ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
@@ -136,105 +135,104 @@
 
    This is not guaranteed to produce working output in all cases, you
 may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
+using the 'lipo' tool if you have problems.
 
 Installation Names
 ==================
 
-   By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc.  You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
+   By default, 'make install' installs the package's commands under
+'/usr/local/bin', include files under '/usr/local/include', etc.  You
+can specify an installation prefix other than '/usr/local' by giving
+'configure' the option '--prefix=PREFIX', where PREFIX must be an
 absolute file name.
 
    You can specify separate installation prefixes for
 architecture-specific files and architecture-independent files.  If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
 PREFIX as the prefix for installing programs and libraries.
 Documentation and other data files still use the regular prefix.
 
    In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.  In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
+options like '--bindir=DIR' to specify different values for particular
+kinds of files.  Run 'configure --help' for a list of the directories
+you can set and what kinds of files go in them.  In general, the default
+for these options is expressed in terms of '${prefix}', so that
+specifying just '--prefix' will affect all of the other directory
 specifications that were not explicitly provided.
 
    The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
+correct locations to 'configure'; however, many packages provide one or
 both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
+'make install' command line to change installation locations without
 having to reconfigure or recompile.
 
    The first method involves providing an override variable for each
-affected directory.  For example, `make install
+affected directory.  For example, 'make install
 prefix=/alternate/directory' will choose an alternate location for all
 directory configuration variables that were expressed in terms of
-`${prefix}'.  Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated.  The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
+'${prefix}'.  Any directories that were specified during 'configure',
+but not in terms of '${prefix}', must each be overridden at install time
+for the entire installation to be relocated.  The approach of makefile
+variable overrides for each directory variable is required by the GNU
+Coding Standards, and ideally causes no recompilation.  However, some
+platforms have known limitations with the semantics of shared libraries
+that end up requiring recompilation when using this method, particularly
+noticeable in packages that use GNU Libtool.
 
-   The second method involves providing the `DESTDIR' variable.  For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names.  The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
+   The second method involves providing the 'DESTDIR' variable.  For
+example, 'make install DESTDIR=/alternate/directory' will prepend
+'/alternate/directory' before all installation names.  The approach of
+'DESTDIR' overrides is not required by the GNU Coding Standards, and
 does not work on platforms that have drive letters.  On the other hand,
 it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
+when some directory options were not specified in terms of '${prefix}'
+at 'configure' time.
 
 Optional Features
 =================
 
    If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+with an extra prefix or suffix on their names by giving 'configure' the
+option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
 
-   Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
+   Some packages pay attention to '--enable-FEATURE' options to
+'configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to '--with-PACKAGE' options, where PACKAGE
+is something like 'gnu-as' or 'x' (for the X Window System).  The
+'README' should mention any '--enable-' and '--with-' options that the
 package recognizes.
 
-   For packages that use the X Window System, `configure' can usually
+   For packages that use the X Window System, 'configure' can usually
 find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
+you can use the 'configure' options '--x-includes=DIR' and
+'--x-libraries=DIR' to specify their locations.
 
    Some packages offer the ability to configure how verbose the
-execution of `make' will be.  For these packages, running `./configure
+execution of 'make' will be.  For these packages, running './configure
 --enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
+overridden with 'make V=1'; while running './configure
 --disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
+overridden with 'make V=0'.
 
 Particular systems
 ==================
 
-   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
-CC is not installed, it is recommended to use the following options in
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU CC
+is not installed, it is recommended to use the following options in
 order to use an ANSI C compiler:
 
      ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
 
 and if that doesn't work, install pre-built binaries of GCC for HP-UX.
 
-   HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved.  Use GNU `make'
-instead.
+   HP-UX 'make' updates targets which have the same time stamps as their
+prerequisites, which makes it generally unusable when shipped generated
+files such as 'configure' are involved.  Use GNU 'make' instead.
 
    On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
-a workaround.  If GNU CC is not installed, it is therefore recommended
-to try
+parse its '<wchar.h>' header file.  The option '-nodtk' can be used as a
+workaround.  If GNU CC is not installed, it is therefore recommended to
+try
 
      ./configure CC="cc"
 
@@ -242,26 +240,26 @@
 
      ./configure CC="cc -nodtk"
 
-   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+   On Solaris, don't put '/usr/ucb' early in your 'PATH'.  This
 directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
+these programs are available in '/usr/bin'.  So, if you need '/usr/ucb'
+in your 'PATH', put it _after_ '/usr/bin'.
 
-   On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'.  It is recommended to use the following options:
+   On Haiku, software installed for all users goes in '/boot/common',
+not '/usr/local'.  It is recommended to use the following options:
 
      ./configure --prefix=/boot/common
 
 Specifying the System Type
 ==========================
 
-   There may be some features `configure' cannot figure out
+   There may be some features 'configure' cannot figure out
 automatically, but needs to determine by the type of machine the package
 will run on.  Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
+_same_ architectures, 'configure' can figure that out, but if it prints
 a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
+'--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as 'sun4', or a canonical name which has the form:
 
      CPU-COMPANY-SYSTEM
 
@@ -270,101 +268,101 @@
      OS
      KERNEL-OS
 
-   See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
+   See the file 'config.sub' for the possible values of each field.  If
+'config.sub' isn't included in this package, then this package doesn't
 need to know the machine type.
 
    If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
+use the option '--target=TYPE' to select the type of system they will
 produce code for.
 
    If you want to _use_ a cross compiler, that generates code for a
 platform different from the build platform, you should specify the
 "host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
+eventually be run) with '--host=TYPE'.
 
 Sharing Defaults
 ================
 
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
+   If you want to set default values for 'configure' scripts to share,
+you can create a site shell script called 'config.site' that gives
+default values for variables like 'CC', 'cache_file', and 'prefix'.
+'configure' looks for 'PREFIX/share/config.site' if it exists, then
+'PREFIX/etc/config.site' if it exists.  Or, you can set the
+'CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all 'configure' scripts look for a site script.
 
 Defining Variables
 ==================
 
    Variables not defined in a site shell script can be set in the
-environment passed to `configure'.  However, some packages may run
+environment passed to 'configure'.  However, some packages may run
 configure again during the build, and the customized values of these
 variables may be lost.  In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'.  For example:
+them in the 'configure' command line, using 'VAR=value'.  For example:
 
      ./configure CC=/usr/local2/bin/gcc
 
-causes the specified `gcc' to be used as the C compiler (unless it is
+causes the specified 'gcc' to be used as the C compiler (unless it is
 overridden in the site shell script).
 
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf limitation.  Until the limitation is lifted, you can use
-this workaround:
+Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
+Autoconf limitation.  Until the limitation is lifted, you can use this
+workaround:
 
      CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
 
-`configure' Invocation
+'configure' Invocation
 ======================
 
-   `configure' recognizes the following options to control how it
+   'configure' recognizes the following options to control how it
 operates.
 
-`--help'
-`-h'
-     Print a summary of all of the options to `configure', and exit.
+'--help'
+'-h'
+     Print a summary of all of the options to 'configure', and exit.
 
-`--help=short'
-`--help=recursive'
+'--help=short'
+'--help=recursive'
      Print a summary of the options unique to this package's
-     `configure', and exit.  The `short' variant lists options used
-     only in the top level, while the `recursive' variant lists options
-     also present in any nested packages.
+     'configure', and exit.  The 'short' variant lists options used only
+     in the top level, while the 'recursive' variant lists options also
+     present in any nested packages.
 
-`--version'
-`-V'
-     Print the version of Autoconf used to generate the `configure'
+'--version'
+'-V'
+     Print the version of Autoconf used to generate the 'configure'
      script, and exit.
 
-`--cache-file=FILE'
+'--cache-file=FILE'
      Enable the cache: use and save the results of the tests in FILE,
-     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     traditionally 'config.cache'.  FILE defaults to '/dev/null' to
      disable caching.
 
-`--config-cache'
-`-C'
-     Alias for `--cache-file=config.cache'.
+'--config-cache'
+'-C'
+     Alias for '--cache-file=config.cache'.
 
-`--quiet'
-`--silent'
-`-q'
+'--quiet'
+'--silent'
+'-q'
      Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
+     suppress all normal output, redirect it to '/dev/null' (any error
      messages will still be shown).
 
-`--srcdir=DIR'
+'--srcdir=DIR'
      Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
+     'configure' can determine that directory automatically.
 
-`--prefix=DIR'
-     Use DIR as the installation prefix.  *note Installation Names::
-     for more details, including other options available for fine-tuning
-     the installation locations.
+'--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names:: for
+     more details, including other options available for fine-tuning the
+     installation locations.
 
-`--no-create'
-`-n'
+'--no-create'
+'-n'
      Run the configure checks, but stop before creating any output
      files.
 
-`configure' also accepts some other, not widely useful, options.  Run
-`configure --help' for more details.
+'configure' also accepts some other, not widely useful, options.  Run
+'configure --help' for more details.
diff --git a/dist2/LICENCE b/dist2/LICENCE
index 6600a65..bfe3c8d 100644
--- a/dist2/LICENCE
+++ b/dist2/LICENCE
@@ -5,9 +5,10 @@
 and semantics are as close as possible to those of the Perl 5 language.
 
 Release 10 of PCRE2 is distributed under the terms of the "BSD" licence, as
-specified below. The documentation for PCRE2, supplied in the "doc"
-directory, is distributed under the same terms as the software itself. The data
-in the testdata directory is not copyrighted and is in the public domain.
+specified below, with one exemption for certain binary redistributions. The
+documentation for PCRE2, supplied in the "doc" directory, is distributed under
+the same terms as the software itself. The data in the testdata directory is
+not copyrighted and is in the public domain.
 
 The basic library functions are written in C and are freestanding. Also
 included in the distribution is a just-in-time compiler that can be used to
@@ -25,7 +26,7 @@
 University of Cambridge Computing Service,
 Cambridge, England.
 
-Copyright (c) 1997-2016 University of Cambridge
+Copyright (c) 1997-2018 University of Cambridge
 All rights reserved.
 
 
@@ -36,7 +37,7 @@
 Email local part: hzmester
 Emain domain:     freemail.hu
 
-Copyright(c) 2010-2016 Zoltan Herczeg
+Copyright(c) 2010-2018 Zoltan Herczeg
 All rights reserved.
 
 
@@ -47,7 +48,7 @@
 Email local part: hzmester
 Emain domain:     freemail.hu
 
-Copyright(c) 2009-2016 Zoltan Herczeg
+Copyright(c) 2009-2018 Zoltan Herczeg
 All rights reserved.
 
 
@@ -57,11 +58,11 @@
 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,
+    * Redistributions of source code must retain the above copyright notices,
       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
+      notices, 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 any
@@ -80,4 +81,14 @@
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 
+
+EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
+------------------------------------------
+
+The second condition in the BSD licence (covering binary redistributions) does
+not apply all the way down a chain of software. If binary package A includes
+PCRE2, it must respect the condition, but if package B is software that
+includes package A, the condition is not imposed on package B unless it uses
+PCRE2 independently.
+
 End
diff --git a/dist2/Makefile.am b/dist2/Makefile.am
index 38f1d41..d0efa12 100644
--- a/dist2/Makefile.am
+++ b/dist2/Makefile.am
@@ -2,7 +2,10 @@
 
 AUTOMAKE_OPTIONS = subdir-objects
 ACLOCAL_AMFLAGS = -I m4
-AM_CPPFLAGS = -I$(builddir)/src -I$(srcdir)/src
+
+## This seems to have become necessary for building in non-source directory.
+
+AM_CPPFLAGS="-I$(srcdir)/src"
 
 ## Specify the documentation files that are distributed.
 
@@ -26,12 +29,17 @@
   doc/html/pcre2.html \
   doc/html/pcre2_callout_enumerate.html \
   doc/html/pcre2_code_copy.html \
+  doc/html/pcre2_code_copy_with_tables.html \
   doc/html/pcre2_code_free.html \
   doc/html/pcre2_compile.html \
   doc/html/pcre2_compile_context_copy.html \
   doc/html/pcre2_compile_context_create.html \
   doc/html/pcre2_compile_context_free.html \
   doc/html/pcre2_config.html \
+  doc/html/pcre2_convert_context_copy.html \
+  doc/html/pcre2_convert_context_create.html \
+  doc/html/pcre2_convert_context_free.html \
+  doc/html/pcre2_converted_pattern_free.html \
   doc/html/pcre2_dfa_match.html \
   doc/html/pcre2_general_context_copy.html \
   doc/html/pcre2_general_context_create.html \
@@ -55,6 +63,7 @@
   doc/html/pcre2_match_data_create.html \
   doc/html/pcre2_match_data_create_from_pattern.html \
   doc/html/pcre2_match_data_free.html \
+  doc/html/pcre2_pattern_convert.html \
   doc/html/pcre2_pattern_info.html \
   doc/html/pcre2_serialize_decode.html \
   doc/html/pcre2_serialize_encode.html \
@@ -63,8 +72,14 @@
   doc/html/pcre2_set_bsr.html \
   doc/html/pcre2_set_callout.html \
   doc/html/pcre2_set_character_tables.html \
+  doc/html/pcre2_set_compile_extra_options.html \
   doc/html/pcre2_set_compile_recursion_guard.html \
+  doc/html/pcre2_set_depth_limit.html \
+  doc/html/pcre2_set_glob_escape.html \
+  doc/html/pcre2_set_glob_separator.html \
+  doc/html/pcre2_set_heap_limit.html \
   doc/html/pcre2_set_match_limit.html \
+  doc/html/pcre2_set_max_pattern_length.html \
   doc/html/pcre2_set_offset_limit.html \
   doc/html/pcre2_set_newline.html \
   doc/html/pcre2_set_parens_nest_limit.html \
@@ -86,6 +101,7 @@
   doc/html/pcre2build.html \
   doc/html/pcre2callout.html \
   doc/html/pcre2compat.html \
+  doc/html/pcre2convert.html \
   doc/html/pcre2demo.html \
   doc/html/pcre2grep.html \
   doc/html/pcre2jit.html \
@@ -97,7 +113,6 @@
   doc/html/pcre2posix.html \
   doc/html/pcre2sample.html \
   doc/html/pcre2serialize.html \
-  doc/html/pcre2stack.html \
   doc/html/pcre2syntax.html \
   doc/html/pcre2test.html \
   doc/html/pcre2unicode.html
@@ -107,12 +122,17 @@
   doc/pcre2.3 \
   doc/pcre2_callout_enumerate.3 \
   doc/pcre2_code_copy.3 \
+  doc/pcre2_code_copy_with_tables.3 \
   doc/pcre2_code_free.3 \
   doc/pcre2_compile.3 \
   doc/pcre2_compile_context_copy.3 \
   doc/pcre2_compile_context_create.3 \
   doc/pcre2_compile_context_free.3 \
   doc/pcre2_config.3 \
+  doc/pcre2_convert_context_copy.3 \
+  doc/pcre2_convert_context_create.3 \
+  doc/pcre2_convert_context_free.3 \
+  doc/pcre2_converted_pattern_free.3 \
   doc/pcre2_dfa_match.3 \
   doc/pcre2_general_context_copy.3 \
   doc/pcre2_general_context_create.3 \
@@ -136,6 +156,7 @@
   doc/pcre2_match_data_create.3 \
   doc/pcre2_match_data_create_from_pattern.3 \
   doc/pcre2_match_data_free.3 \
+  doc/pcre2_pattern_convert.3 \
   doc/pcre2_pattern_info.3 \
   doc/pcre2_serialize_decode.3 \
   doc/pcre2_serialize_encode.3 \
@@ -144,8 +165,14 @@
   doc/pcre2_set_bsr.3 \
   doc/pcre2_set_callout.3 \
   doc/pcre2_set_character_tables.3 \
+  doc/pcre2_set_compile_extra_options.3 \
   doc/pcre2_set_compile_recursion_guard.3 \
+  doc/pcre2_set_depth_limit.3 \
+  doc/pcre2_set_glob_escape.3 \
+  doc/pcre2_set_glob_separator.3 \
+  doc/pcre2_set_heap_limit.3 \
   doc/pcre2_set_match_limit.3 \
+  doc/pcre2_set_max_pattern_length.3 \
   doc/pcre2_set_offset_limit.3 \
   doc/pcre2_set_newline.3 \
   doc/pcre2_set_parens_nest_limit.3 \
@@ -167,6 +194,7 @@
   doc/pcre2build.3 \
   doc/pcre2callout.3 \
   doc/pcre2compat.3 \
+  doc/pcre2convert.3 \
   doc/pcre2demo.3 \
   doc/pcre2grep.1 \
   doc/pcre2jit.3 \
@@ -178,7 +206,6 @@
   doc/pcre2posix.3 \
   doc/pcre2sample.3 \
   doc/pcre2serialize.3 \
-  doc/pcre2stack.3 \
   doc/pcre2syntax.3 \
   doc/pcre2test.1 \
   doc/pcre2unicode.3
@@ -321,8 +348,10 @@
   src/pcre2_compile.c \
   src/pcre2_config.c \
   src/pcre2_context.c \
+  src/pcre2_convert.c \
   src/pcre2_dfa_match.c \
   src/pcre2_error.c \
+  src/pcre2_extuni.c \
   src/pcre2_find_bracket.c \
   src/pcre2_internal.h \
   src/pcre2_intmodedep.h \
@@ -414,6 +443,7 @@
   src/sljit/sljitNativeX86_32.c \
   src/sljit/sljitNativeX86_64.c \
   src/sljit/sljitNativeX86_common.c \
+  src/sljit/sljitProtExecAllocator.c \
   src/sljit/sljitUtils.c
 
 # Some of the JIT sources are also in separate files that are #included.
@@ -471,7 +501,7 @@
 endif # WITH_GCOV
 endif # WITH_PCRE2_8
 
-## Build pcre2grep if the 8-bit library is enabled
+## Build pcre2grep and optional fuzzer stuff if the 8-bit library is enabled
 
 if WITH_PCRE2_8
 bin_PROGRAMS += pcre2grep
@@ -483,6 +513,22 @@
 pcre2grep_CFLAGS += $(GCOV_CFLAGS)
 pcre2grep_LDADD += $(GCOV_LIBS)
 endif # WITH_GCOV
+
+## If fuzzer support is enabled, build a non-distributed library containing the
+## fuzzing function. Also build the standalone checking binary from the same
+## source but using -DSTANDALONE.
+
+if WITH_FUZZ_SUPPORT
+noinst_LIBRARIES = .libs/libpcre2-fuzzsupport.a
+_libs_libpcre2_fuzzsupport_a_SOURCES = src/pcre2_fuzzsupport.c
+_libs_libpcre2_fuzzsupport_a_CFLAGS = $(AM_CFLAGS)
+_libs_libpcre2_fuzzsupport_a_LIBADD =
+
+noinst_PROGRAMS += pcre2fuzzcheck
+pcre2fuzzcheck_SOURCES = src/pcre2_fuzzsupport.c
+pcre2fuzzcheck_CFLAGS = -DSTANDALONE $(AM_CFLAGS)
+pcre2fuzzcheck_LDADD = libpcre2-8.la
+endif # WITH FUZZ_SUPPORT
 endif # WITH_PCRE2_8
 
 ## -------- Testing ----------
@@ -543,17 +589,17 @@
 
 ## The main library tests. Each test is a binary plus a script that runs that
 ## binary in various ways. We install these test binaries in case folks find it
-## helpful.
+## helpful. The two .bat files are for running the tests under Windows.
 
 TESTS += RunTest
-dist_noinst_SCRIPTS += RunTest
-
 EXTRA_DIST += RunTest.bat
+dist_noinst_SCRIPTS += RunTest
 
 ## When the 8-bit library is configured, pcre2grep will have been built.
 
 if WITH_PCRE2_8
 TESTS += RunGrepTest
+EXTRA_DIST += RunGrepTest.bat
 dist_noinst_SCRIPTS += RunGrepTest
 endif # WITH_PCRE2_8
 
@@ -565,6 +611,7 @@
   testdata/grepinput \
   testdata/grepinput3 \
   testdata/grepinput8 \
+  testdata/grepinputM \
   testdata/grepinputv \
   testdata/grepinputx \
   testdata/greplist \
@@ -596,6 +643,8 @@
   testdata/testinput21 \
   testdata/testinput22 \
   testdata/testinput23 \
+  testdata/testinput24 \
+  testdata/testinput25 \
   testdata/testinputEBC \
   testdata/testoutput1 \
   testdata/testoutput2 \
@@ -636,6 +685,8 @@
   testdata/testoutput22-32 \
   testdata/testoutput22-8 \
   testdata/testoutput23 \
+  testdata/testoutput24 \
+  testdata/testoutput25 \
   testdata/testoutputEBC \
   testdata/valgrind-jit.supp \
   testdata/wintestinput3 \
diff --git a/dist2/Makefile.in b/dist2/Makefile.in
index ddc5132..47ec217 100644
--- a/dist2/Makefile.in
+++ b/dist2/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -18,6 +18,7 @@
 
 
 
+
 VPATH = @srcdir@
 am__is_gnu_make = { \
   if test -z '$(MAKELEVEL)'; then \
@@ -92,9 +93,9 @@
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-TESTS = $(am__EXEEXT_3) RunTest $(am__append_29)
+TESTS = $(am__EXEEXT_4) RunTest $(am__append_30)
 bin_PROGRAMS = $(am__EXEEXT_1) pcre2test$(EXEEXT)
-noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3)
+noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4)
 @WITH_REBUILD_CHARTABLES_TRUE@am__append_1 = dftables
 @WITH_PCRE2_8_TRUE@am__append_2 = libpcre2-8.la
 @WITH_PCRE2_16_TRUE@am__append_3 = libpcre2-16.la
@@ -110,25 +111,27 @@
 @WITH_PCRE2_8_TRUE@am__append_13 = pcre2grep
 @WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_14 = $(GCOV_CFLAGS)
 @WITH_GCOV_TRUE@@WITH_PCRE2_8_TRUE@am__append_15 = $(GCOV_LIBS)
-@WITH_JIT_TRUE@am__append_16 = pcre2_jit_test
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@am__append_16 = pcre2fuzzcheck
 @WITH_JIT_TRUE@am__append_17 = pcre2_jit_test
-@WITH_JIT_TRUE@@WITH_PCRE2_8_TRUE@am__append_18 = libpcre2-8.la
-@WITH_JIT_TRUE@@WITH_PCRE2_16_TRUE@am__append_19 = libpcre2-16.la
-@WITH_JIT_TRUE@@WITH_PCRE2_32_TRUE@am__append_20 = libpcre2-32.la
-@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_21 = $(GCOV_CFLAGS)
-@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_22 = $(GCOV_LIBS)
-@WITH_PCRE2_8_TRUE@am__append_23 = libpcre2-8.la libpcre2-posix.la
-@WITH_PCRE2_16_TRUE@am__append_24 = libpcre2-16.la
-@WITH_PCRE2_32_TRUE@am__append_25 = libpcre2-32.la
-@WITH_VALGRIND_TRUE@am__append_26 = $(VALGRIND_CFLAGS)
-@WITH_GCOV_TRUE@am__append_27 = $(GCOV_CFLAGS)
-@WITH_GCOV_TRUE@am__append_28 = $(GCOV_LIBS)
-@WITH_PCRE2_8_TRUE@am__append_29 = RunGrepTest
+@WITH_JIT_TRUE@am__append_18 = pcre2_jit_test
+@WITH_JIT_TRUE@@WITH_PCRE2_8_TRUE@am__append_19 = libpcre2-8.la
+@WITH_JIT_TRUE@@WITH_PCRE2_16_TRUE@am__append_20 = libpcre2-16.la
+@WITH_JIT_TRUE@@WITH_PCRE2_32_TRUE@am__append_21 = libpcre2-32.la
+@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_22 = $(GCOV_CFLAGS)
+@WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__append_23 = $(GCOV_LIBS)
+@WITH_PCRE2_8_TRUE@am__append_24 = libpcre2-8.la libpcre2-posix.la
+@WITH_PCRE2_16_TRUE@am__append_25 = libpcre2-16.la
+@WITH_PCRE2_32_TRUE@am__append_26 = libpcre2-32.la
+@WITH_VALGRIND_TRUE@am__append_27 = $(VALGRIND_CFLAGS)
+@WITH_GCOV_TRUE@am__append_28 = $(GCOV_CFLAGS)
+@WITH_GCOV_TRUE@am__append_29 = $(GCOV_LIBS)
 @WITH_PCRE2_8_TRUE@am__append_30 = RunGrepTest
-@WITH_PCRE2_8_TRUE@am__append_31 = libpcre2-8.pc libpcre2-posix.pc
-@WITH_PCRE2_16_TRUE@am__append_32 = libpcre2-16.pc
-@WITH_PCRE2_32_TRUE@am__append_33 = libpcre2-32.pc
-@WITH_GCOV_FALSE@am__append_34 = src/*.gcda src/*.gcno
+@WITH_PCRE2_8_TRUE@am__append_31 = RunGrepTest.bat
+@WITH_PCRE2_8_TRUE@am__append_32 = RunGrepTest
+@WITH_PCRE2_8_TRUE@am__append_33 = libpcre2-8.pc libpcre2-posix.pc
+@WITH_PCRE2_16_TRUE@am__append_34 = libpcre2-16.pc
+@WITH_PCRE2_32_TRUE@am__append_35 = libpcre2-32.pc
+@WITH_GCOV_FALSE@am__append_36 = src/*.gcda src/*.gcno
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
@@ -150,6 +153,20 @@
 CONFIG_CLEAN_FILES = libpcre2-8.pc libpcre2-16.pc libpcre2-32.pc \
 	libpcre2-posix.pc pcre2-config src/pcre2.h
 CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_@AM_V@)
+am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+_libs_libpcre2_fuzzsupport_a_AR = $(AR) $(ARFLAGS)
+_libs_libpcre2_fuzzsupport_a_DEPENDENCIES =
+am___libs_libpcre2_fuzzsupport_a_SOURCES_DIST =  \
+	src/pcre2_fuzzsupport.c
+am__dirstamp = $(am__leading_dot)dirstamp
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@am__libs_libpcre2_fuzzsupport_a_OBJECTS = src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.$(OBJEXT)
+_libs_libpcre2_fuzzsupport_a_OBJECTS =  \
+	$(am__libs_libpcre2_fuzzsupport_a_OBJECTS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -186,23 +203,24 @@
 libpcre2_16_la_DEPENDENCIES =
 am__libpcre2_16_la_SOURCES_DIST = src/pcre2_auto_possess.c \
 	src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \
-	src/pcre2_dfa_match.c src/pcre2_error.c \
-	src/pcre2_find_bracket.c src/pcre2_internal.h \
-	src/pcre2_intmodedep.h src/pcre2_jit_compile.c \
-	src/pcre2_maketables.c src/pcre2_match.c \
-	src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \
-	src/pcre2_pattern_info.c src/pcre2_serialize.c \
-	src/pcre2_string_utils.c src/pcre2_study.c \
-	src/pcre2_substitute.c src/pcre2_substring.c \
+	src/pcre2_convert.c src/pcre2_dfa_match.c src/pcre2_error.c \
+	src/pcre2_extuni.c src/pcre2_find_bracket.c \
+	src/pcre2_internal.h src/pcre2_intmodedep.h \
+	src/pcre2_jit_compile.c src/pcre2_maketables.c \
+	src/pcre2_match.c src/pcre2_match_data.c src/pcre2_newline.c \
+	src/pcre2_ord2utf.c src/pcre2_pattern_info.c \
+	src/pcre2_serialize.c src/pcre2_string_utils.c \
+	src/pcre2_study.c src/pcre2_substitute.c src/pcre2_substring.c \
 	src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \
 	src/pcre2_valid_utf.c src/pcre2_xclass.c
-am__dirstamp = $(am__leading_dot)dirstamp
 am__objects_1 = src/libpcre2_16_la-pcre2_auto_possess.lo \
 	src/libpcre2_16_la-pcre2_compile.lo \
 	src/libpcre2_16_la-pcre2_config.lo \
 	src/libpcre2_16_la-pcre2_context.lo \
+	src/libpcre2_16_la-pcre2_convert.lo \
 	src/libpcre2_16_la-pcre2_dfa_match.lo \
 	src/libpcre2_16_la-pcre2_error.lo \
+	src/libpcre2_16_la-pcre2_extuni.lo \
 	src/libpcre2_16_la-pcre2_find_bracket.lo \
 	src/libpcre2_16_la-pcre2_jit_compile.lo \
 	src/libpcre2_16_la-pcre2_maketables.lo \
@@ -237,22 +255,24 @@
 libpcre2_32_la_DEPENDENCIES =
 am__libpcre2_32_la_SOURCES_DIST = src/pcre2_auto_possess.c \
 	src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \
-	src/pcre2_dfa_match.c src/pcre2_error.c \
-	src/pcre2_find_bracket.c src/pcre2_internal.h \
-	src/pcre2_intmodedep.h src/pcre2_jit_compile.c \
-	src/pcre2_maketables.c src/pcre2_match.c \
-	src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \
-	src/pcre2_pattern_info.c src/pcre2_serialize.c \
-	src/pcre2_string_utils.c src/pcre2_study.c \
-	src/pcre2_substitute.c src/pcre2_substring.c \
+	src/pcre2_convert.c src/pcre2_dfa_match.c src/pcre2_error.c \
+	src/pcre2_extuni.c src/pcre2_find_bracket.c \
+	src/pcre2_internal.h src/pcre2_intmodedep.h \
+	src/pcre2_jit_compile.c src/pcre2_maketables.c \
+	src/pcre2_match.c src/pcre2_match_data.c src/pcre2_newline.c \
+	src/pcre2_ord2utf.c src/pcre2_pattern_info.c \
+	src/pcre2_serialize.c src/pcre2_string_utils.c \
+	src/pcre2_study.c src/pcre2_substitute.c src/pcre2_substring.c \
 	src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \
 	src/pcre2_valid_utf.c src/pcre2_xclass.c
 am__objects_3 = src/libpcre2_32_la-pcre2_auto_possess.lo \
 	src/libpcre2_32_la-pcre2_compile.lo \
 	src/libpcre2_32_la-pcre2_config.lo \
 	src/libpcre2_32_la-pcre2_context.lo \
+	src/libpcre2_32_la-pcre2_convert.lo \
 	src/libpcre2_32_la-pcre2_dfa_match.lo \
 	src/libpcre2_32_la-pcre2_error.lo \
+	src/libpcre2_32_la-pcre2_extuni.lo \
 	src/libpcre2_32_la-pcre2_find_bracket.lo \
 	src/libpcre2_32_la-pcre2_jit_compile.lo \
 	src/libpcre2_32_la-pcre2_maketables.lo \
@@ -283,22 +303,24 @@
 libpcre2_8_la_DEPENDENCIES =
 am__libpcre2_8_la_SOURCES_DIST = src/pcre2_auto_possess.c \
 	src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c \
-	src/pcre2_dfa_match.c src/pcre2_error.c \
-	src/pcre2_find_bracket.c src/pcre2_internal.h \
-	src/pcre2_intmodedep.h src/pcre2_jit_compile.c \
-	src/pcre2_maketables.c src/pcre2_match.c \
-	src/pcre2_match_data.c src/pcre2_newline.c src/pcre2_ord2utf.c \
-	src/pcre2_pattern_info.c src/pcre2_serialize.c \
-	src/pcre2_string_utils.c src/pcre2_study.c \
-	src/pcre2_substitute.c src/pcre2_substring.c \
+	src/pcre2_convert.c src/pcre2_dfa_match.c src/pcre2_error.c \
+	src/pcre2_extuni.c src/pcre2_find_bracket.c \
+	src/pcre2_internal.h src/pcre2_intmodedep.h \
+	src/pcre2_jit_compile.c src/pcre2_maketables.c \
+	src/pcre2_match.c src/pcre2_match_data.c src/pcre2_newline.c \
+	src/pcre2_ord2utf.c src/pcre2_pattern_info.c \
+	src/pcre2_serialize.c src/pcre2_string_utils.c \
+	src/pcre2_study.c src/pcre2_substitute.c src/pcre2_substring.c \
 	src/pcre2_tables.c src/pcre2_ucd.c src/pcre2_ucp.h \
 	src/pcre2_valid_utf.c src/pcre2_xclass.c
 am__objects_5 = src/libpcre2_8_la-pcre2_auto_possess.lo \
 	src/libpcre2_8_la-pcre2_compile.lo \
 	src/libpcre2_8_la-pcre2_config.lo \
 	src/libpcre2_8_la-pcre2_context.lo \
+	src/libpcre2_8_la-pcre2_convert.lo \
 	src/libpcre2_8_la-pcre2_dfa_match.lo \
 	src/libpcre2_8_la-pcre2_error.lo \
+	src/libpcre2_8_la-pcre2_extuni.lo \
 	src/libpcre2_8_la-pcre2_find_bracket.lo \
 	src/libpcre2_8_la-pcre2_jit_compile.lo \
 	src/libpcre2_8_la-pcre2_maketables.lo \
@@ -337,7 +359,8 @@
 @WITH_PCRE2_8_TRUE@am_libpcre2_posix_la_rpath = -rpath $(libdir)
 @WITH_PCRE2_8_TRUE@am__EXEEXT_1 = pcre2grep$(EXEEXT)
 @WITH_REBUILD_CHARTABLES_TRUE@am__EXEEXT_2 = dftables$(EXEEXT)
-@WITH_JIT_TRUE@am__EXEEXT_3 = pcre2_jit_test$(EXEEXT)
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@am__EXEEXT_3 = pcre2fuzzcheck$(EXEEXT)
+@WITH_JIT_TRUE@am__EXEEXT_4 = pcre2_jit_test$(EXEEXT)
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
 am__dftables_SOURCES_DIST = src/dftables.c
 @WITH_REBUILD_CHARTABLES_TRUE@am_dftables_OBJECTS =  \
@@ -351,13 +374,22 @@
 am__DEPENDENCIES_1 =
 @WITH_GCOV_TRUE@@WITH_JIT_TRUE@am__DEPENDENCIES_2 =  \
 @WITH_GCOV_TRUE@@WITH_JIT_TRUE@	$(am__DEPENDENCIES_1)
-@WITH_JIT_TRUE@pcre2_jit_test_DEPENDENCIES = $(am__append_18) \
-@WITH_JIT_TRUE@	$(am__append_19) $(am__append_20) \
+@WITH_JIT_TRUE@pcre2_jit_test_DEPENDENCIES = $(am__append_19) \
+@WITH_JIT_TRUE@	$(am__append_20) $(am__append_21) \
 @WITH_JIT_TRUE@	$(am__DEPENDENCIES_2)
 pcre2_jit_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(pcre2_jit_test_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
 	$@
+am__pcre2fuzzcheck_SOURCES_DIST = src/pcre2_fuzzsupport.c
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@am_pcre2fuzzcheck_OBJECTS = src/pcre2fuzzcheck-pcre2_fuzzsupport.$(OBJEXT)
+pcre2fuzzcheck_OBJECTS = $(am_pcre2fuzzcheck_OBJECTS)
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@pcre2fuzzcheck_DEPENDENCIES =  \
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@	libpcre2-8.la
+pcre2fuzzcheck_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(pcre2fuzzcheck_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+	$@
 am__pcre2grep_SOURCES_DIST = src/pcre2grep.c
 @WITH_PCRE2_8_TRUE@am_pcre2grep_OBJECTS =  \
 @WITH_PCRE2_8_TRUE@	src/pcre2grep-pcre2grep.$(OBJEXT)
@@ -373,8 +405,8 @@
 am_pcre2test_OBJECTS = src/pcre2test-pcre2test.$(OBJEXT)
 pcre2test_OBJECTS = $(am_pcre2test_OBJECTS)
 @WITH_GCOV_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1)
-pcre2test_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_23) \
-	$(am__append_24) $(am__append_25) $(am__DEPENDENCIES_4)
+pcre2test_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_24) \
+	$(am__append_25) $(am__append_26) $(am__DEPENDENCIES_4)
 pcre2test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(pcre2test_CFLAGS) \
 	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
@@ -414,18 +446,21 @@
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libpcre2_16_la_SOURCES) $(nodist_libpcre2_16_la_SOURCES) \
+SOURCES = $(_libs_libpcre2_fuzzsupport_a_SOURCES) \
+	$(libpcre2_16_la_SOURCES) $(nodist_libpcre2_16_la_SOURCES) \
 	$(libpcre2_32_la_SOURCES) $(nodist_libpcre2_32_la_SOURCES) \
 	$(libpcre2_8_la_SOURCES) $(nodist_libpcre2_8_la_SOURCES) \
 	$(libpcre2_posix_la_SOURCES) $(dftables_SOURCES) \
-	$(pcre2_jit_test_SOURCES) $(pcre2grep_SOURCES) \
-	$(pcre2test_SOURCES)
-DIST_SOURCES = $(am__libpcre2_16_la_SOURCES_DIST) \
+	$(pcre2_jit_test_SOURCES) $(pcre2fuzzcheck_SOURCES) \
+	$(pcre2grep_SOURCES) $(pcre2test_SOURCES)
+DIST_SOURCES = $(am___libs_libpcre2_fuzzsupport_a_SOURCES_DIST) \
+	$(am__libpcre2_16_la_SOURCES_DIST) \
 	$(am__libpcre2_32_la_SOURCES_DIST) \
 	$(am__libpcre2_8_la_SOURCES_DIST) \
 	$(am__libpcre2_posix_la_SOURCES_DIST) \
 	$(am__dftables_SOURCES_DIST) \
 	$(am__pcre2_jit_test_SOURCES_DIST) \
+	$(am__pcre2fuzzcheck_SOURCES_DIST) \
 	$(am__pcre2grep_SOURCES_DIST) $(pcre2test_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
@@ -811,7 +846,7 @@
 top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = subdir-objects
 ACLOCAL_AMFLAGS = -I m4
-AM_CPPFLAGS = -I$(builddir)/src -I$(srcdir)/src
+AM_CPPFLAGS = "-I$(srcdir)/src"
 dist_doc_DATA = \
   AUTHORS \
   COPYING \
@@ -832,12 +867,17 @@
   doc/html/pcre2.html \
   doc/html/pcre2_callout_enumerate.html \
   doc/html/pcre2_code_copy.html \
+  doc/html/pcre2_code_copy_with_tables.html \
   doc/html/pcre2_code_free.html \
   doc/html/pcre2_compile.html \
   doc/html/pcre2_compile_context_copy.html \
   doc/html/pcre2_compile_context_create.html \
   doc/html/pcre2_compile_context_free.html \
   doc/html/pcre2_config.html \
+  doc/html/pcre2_convert_context_copy.html \
+  doc/html/pcre2_convert_context_create.html \
+  doc/html/pcre2_convert_context_free.html \
+  doc/html/pcre2_converted_pattern_free.html \
   doc/html/pcre2_dfa_match.html \
   doc/html/pcre2_general_context_copy.html \
   doc/html/pcre2_general_context_create.html \
@@ -861,6 +901,7 @@
   doc/html/pcre2_match_data_create.html \
   doc/html/pcre2_match_data_create_from_pattern.html \
   doc/html/pcre2_match_data_free.html \
+  doc/html/pcre2_pattern_convert.html \
   doc/html/pcre2_pattern_info.html \
   doc/html/pcre2_serialize_decode.html \
   doc/html/pcre2_serialize_encode.html \
@@ -869,8 +910,14 @@
   doc/html/pcre2_set_bsr.html \
   doc/html/pcre2_set_callout.html \
   doc/html/pcre2_set_character_tables.html \
+  doc/html/pcre2_set_compile_extra_options.html \
   doc/html/pcre2_set_compile_recursion_guard.html \
+  doc/html/pcre2_set_depth_limit.html \
+  doc/html/pcre2_set_glob_escape.html \
+  doc/html/pcre2_set_glob_separator.html \
+  doc/html/pcre2_set_heap_limit.html \
   doc/html/pcre2_set_match_limit.html \
+  doc/html/pcre2_set_max_pattern_length.html \
   doc/html/pcre2_set_offset_limit.html \
   doc/html/pcre2_set_newline.html \
   doc/html/pcre2_set_parens_nest_limit.html \
@@ -892,6 +939,7 @@
   doc/html/pcre2build.html \
   doc/html/pcre2callout.html \
   doc/html/pcre2compat.html \
+  doc/html/pcre2convert.html \
   doc/html/pcre2demo.html \
   doc/html/pcre2grep.html \
   doc/html/pcre2jit.html \
@@ -903,7 +951,6 @@
   doc/html/pcre2posix.html \
   doc/html/pcre2sample.html \
   doc/html/pcre2serialize.html \
-  doc/html/pcre2stack.html \
   doc/html/pcre2syntax.html \
   doc/html/pcre2test.html \
   doc/html/pcre2unicode.html
@@ -913,12 +960,17 @@
   doc/pcre2.3 \
   doc/pcre2_callout_enumerate.3 \
   doc/pcre2_code_copy.3 \
+  doc/pcre2_code_copy_with_tables.3 \
   doc/pcre2_code_free.3 \
   doc/pcre2_compile.3 \
   doc/pcre2_compile_context_copy.3 \
   doc/pcre2_compile_context_create.3 \
   doc/pcre2_compile_context_free.3 \
   doc/pcre2_config.3 \
+  doc/pcre2_convert_context_copy.3 \
+  doc/pcre2_convert_context_create.3 \
+  doc/pcre2_convert_context_free.3 \
+  doc/pcre2_converted_pattern_free.3 \
   doc/pcre2_dfa_match.3 \
   doc/pcre2_general_context_copy.3 \
   doc/pcre2_general_context_create.3 \
@@ -942,6 +994,7 @@
   doc/pcre2_match_data_create.3 \
   doc/pcre2_match_data_create_from_pattern.3 \
   doc/pcre2_match_data_free.3 \
+  doc/pcre2_pattern_convert.3 \
   doc/pcre2_pattern_info.3 \
   doc/pcre2_serialize_decode.3 \
   doc/pcre2_serialize_encode.3 \
@@ -950,8 +1003,14 @@
   doc/pcre2_set_bsr.3 \
   doc/pcre2_set_callout.3 \
   doc/pcre2_set_character_tables.3 \
+  doc/pcre2_set_compile_extra_options.3 \
   doc/pcre2_set_compile_recursion_guard.3 \
+  doc/pcre2_set_depth_limit.3 \
+  doc/pcre2_set_glob_escape.3 \
+  doc/pcre2_set_glob_separator.3 \
+  doc/pcre2_set_heap_limit.3 \
   doc/pcre2_set_match_limit.3 \
+  doc/pcre2_set_max_pattern_length.3 \
   doc/pcre2_set_offset_limit.3 \
   doc/pcre2_set_newline.3 \
   doc/pcre2_set_parens_nest_limit.3 \
@@ -973,6 +1032,7 @@
   doc/pcre2build.3 \
   doc/pcre2callout.3 \
   doc/pcre2compat.3 \
+  doc/pcre2convert.3 \
   doc/pcre2demo.3 \
   doc/pcre2grep.1 \
   doc/pcre2jit.3 \
@@ -984,7 +1044,6 @@
   doc/pcre2posix.3 \
   doc/pcre2sample.3 \
   doc/pcre2serialize.3 \
-  doc/pcre2stack.3 \
   doc/pcre2syntax.3 \
   doc/pcre2test.1 \
   doc/pcre2unicode.3
@@ -994,7 +1053,7 @@
 lib_LTLIBRARIES = $(am__append_2) $(am__append_3) $(am__append_4) \
 	$(am__append_11)
 check_SCRIPTS = 
-dist_noinst_SCRIPTS = RunTest $(am__append_30)
+dist_noinst_SCRIPTS = RunTest $(am__append_32)
 
 # Additional files to delete on 'make clean', 'make distclean',
 # and 'make maintainer-clean'.
@@ -1005,7 +1064,7 @@
 	test3outputA test3outputB testtry teststdout teststderr \
 	teststderrgrep testtemp1grep testtemp2grep testtrygrep \
 	testNinputgrep
-DISTCLEANFILES = src/config.h.in~ config.h $(am__append_34)
+DISTCLEANFILES = src/config.h.in~ config.h $(am__append_36)
 MAINTAINERCLEANFILES = src/pcre2.h.generic src/config.h.generic
 
 # Additional files to bundle with the distribution, over and above what
@@ -1048,21 +1107,23 @@
 	src/sljit/sljitNativeTILEGX-encoder.c \
 	src/sljit/sljitNativeTILEGX_64.c src/sljit/sljitNativeX86_32.c \
 	src/sljit/sljitNativeX86_64.c \
-	src/sljit/sljitNativeX86_common.c src/sljit/sljitUtils.c \
+	src/sljit/sljitNativeX86_common.c \
+	src/sljit/sljitProtExecAllocator.c src/sljit/sljitUtils.c \
 	src/pcre2_jit_match.c src/pcre2_jit_misc.c \
-	src/pcre2_printint.c RunTest.bat testdata/grepbinary \
-	testdata/grepfilelist testdata/grepinput testdata/grepinput3 \
-	testdata/grepinput8 testdata/grepinputv testdata/grepinputx \
-	testdata/greplist testdata/grepoutput testdata/grepoutput8 \
-	testdata/grepoutputC testdata/grepoutputN testdata/greppatN4 \
-	testdata/testinput1 testdata/testinput2 testdata/testinput3 \
-	testdata/testinput4 testdata/testinput5 testdata/testinput6 \
-	testdata/testinput7 testdata/testinput8 testdata/testinput9 \
-	testdata/testinput10 testdata/testinput11 testdata/testinput12 \
-	testdata/testinput13 testdata/testinput14 testdata/testinput15 \
-	testdata/testinput16 testdata/testinput17 testdata/testinput18 \
-	testdata/testinput19 testdata/testinput20 testdata/testinput21 \
-	testdata/testinput22 testdata/testinput23 \
+	src/pcre2_printint.c RunTest.bat $(am__append_31) \
+	testdata/grepbinary testdata/grepfilelist testdata/grepinput \
+	testdata/grepinput3 testdata/grepinput8 testdata/grepinputM \
+	testdata/grepinputv testdata/grepinputx testdata/greplist \
+	testdata/grepoutput testdata/grepoutput8 testdata/grepoutputC \
+	testdata/grepoutputN testdata/greppatN4 testdata/testinput1 \
+	testdata/testinput2 testdata/testinput3 testdata/testinput4 \
+	testdata/testinput5 testdata/testinput6 testdata/testinput7 \
+	testdata/testinput8 testdata/testinput9 testdata/testinput10 \
+	testdata/testinput11 testdata/testinput12 testdata/testinput13 \
+	testdata/testinput14 testdata/testinput15 testdata/testinput16 \
+	testdata/testinput17 testdata/testinput18 testdata/testinput19 \
+	testdata/testinput20 testdata/testinput21 testdata/testinput22 \
+	testdata/testinput23 testdata/testinput24 testdata/testinput25 \
 	testdata/testinputEBC testdata/testoutput1 \
 	testdata/testoutput2 testdata/testoutput3 \
 	testdata/testoutput3A testdata/testoutput3B \
@@ -1082,7 +1143,8 @@
 	testdata/testoutput19 testdata/testoutput20 \
 	testdata/testoutput21 testdata/testoutput22-16 \
 	testdata/testoutput22-32 testdata/testoutput22-8 \
-	testdata/testoutput23 testdata/testoutputEBC \
+	testdata/testoutput23 testdata/testoutput24 \
+	testdata/testoutput25 testdata/testoutputEBC \
 	testdata/valgrind-jit.supp testdata/wintestinput3 \
 	testdata/wintestoutput3 perltest.sh src/pcre2demo.c \
 	cmake/COPYING-CMAKE-SCRIPTS \
@@ -1105,8 +1167,10 @@
   src/pcre2_compile.c \
   src/pcre2_config.c \
   src/pcre2_context.c \
+  src/pcre2_convert.c \
   src/pcre2_dfa_match.c \
   src/pcre2_error.c \
+  src/pcre2_extuni.c \
   src/pcre2_find_bracket.c \
   src/pcre2_internal.h \
   src/pcre2_intmodedep.h \
@@ -1174,19 +1238,26 @@
 @WITH_PCRE2_8_TRUE@pcre2grep_CFLAGS = $(AM_CFLAGS) $(am__append_14)
 @WITH_PCRE2_8_TRUE@pcre2grep_LDADD = $(LIBZ) $(LIBBZ2) libpcre2-8.la \
 @WITH_PCRE2_8_TRUE@	$(am__append_15)
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@noinst_LIBRARIES = .libs/libpcre2-fuzzsupport.a
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@_libs_libpcre2_fuzzsupport_a_SOURCES = src/pcre2_fuzzsupport.c
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@_libs_libpcre2_fuzzsupport_a_CFLAGS = $(AM_CFLAGS)
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@_libs_libpcre2_fuzzsupport_a_LIBADD = 
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@pcre2fuzzcheck_SOURCES = src/pcre2_fuzzsupport.c
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@pcre2fuzzcheck_CFLAGS = -DSTANDALONE $(AM_CFLAGS)
+@WITH_FUZZ_SUPPORT_TRUE@@WITH_PCRE2_8_TRUE@pcre2fuzzcheck_LDADD = libpcre2-8.la
 @WITH_JIT_TRUE@pcre2_jit_test_SOURCES = src/pcre2_jit_test.c
-@WITH_JIT_TRUE@pcre2_jit_test_CFLAGS = $(AM_CFLAGS) $(am__append_21)
-@WITH_JIT_TRUE@pcre2_jit_test_LDADD = $(am__append_18) \
-@WITH_JIT_TRUE@	$(am__append_19) $(am__append_20) \
-@WITH_JIT_TRUE@	$(am__append_22)
+@WITH_JIT_TRUE@pcre2_jit_test_CFLAGS = $(AM_CFLAGS) $(am__append_22)
+@WITH_JIT_TRUE@pcre2_jit_test_LDADD = $(am__append_19) \
+@WITH_JIT_TRUE@	$(am__append_20) $(am__append_21) \
+@WITH_JIT_TRUE@	$(am__append_23)
 pcre2test_SOURCES = src/pcre2test.c
-pcre2test_CFLAGS = $(AM_CFLAGS) $(am__append_26) $(am__append_27)
-pcre2test_LDADD = $(LIBREADLINE) $(am__append_23) $(am__append_24) \
-	$(am__append_25) $(am__append_28)
+pcre2test_CFLAGS = $(AM_CFLAGS) $(am__append_27) $(am__append_28)
+pcre2test_LDADD = $(LIBREADLINE) $(am__append_24) $(am__append_25) \
+	$(am__append_26) $(am__append_29)
 
 # We have .pc files for pkg-config users.
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = $(am__append_31) $(am__append_32) $(am__append_33)
+pkgconfig_DATA = $(am__append_33) $(am__append_34) $(am__append_35)
 
 # gcov/lcov code coverage reporting
 #
@@ -1277,6 +1348,25 @@
 src/pcre2.h: $(top_builddir)/config.status $(top_srcdir)/src/pcre2.h.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+src/$(am__dirstamp):
+	@$(MKDIR_P) src
+	@: > src/$(am__dirstamp)
+src/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/$(DEPDIR)
+	@: > src/$(DEPDIR)/$(am__dirstamp)
+src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.$(OBJEXT):  \
+	src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+.libs/$(am__dirstamp):
+	@$(MKDIR_P) .libs
+	@: > .libs/$(am__dirstamp)
+
+.libs/libpcre2-fuzzsupport.a: $(_libs_libpcre2_fuzzsupport_a_OBJECTS) $(_libs_libpcre2_fuzzsupport_a_DEPENDENCIES) $(EXTRA__libs_libpcre2_fuzzsupport_a_DEPENDENCIES) .libs/$(am__dirstamp)
+	$(AM_V_at)-rm -f .libs/libpcre2-fuzzsupport.a
+	$(AM_V_AR)$(_libs_libpcre2_fuzzsupport_a_AR) .libs/libpcre2-fuzzsupport.a $(_libs_libpcre2_fuzzsupport_a_OBJECTS) $(_libs_libpcre2_fuzzsupport_a_LIBADD)
+	$(AM_V_at)$(RANLIB) .libs/libpcre2-fuzzsupport.a
+
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
 	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
@@ -1311,12 +1401,6 @@
 	  echo rm -f $${locs}; \
 	  rm -f $${locs}; \
 	}
-src/$(am__dirstamp):
-	@$(MKDIR_P) src
-	@: > src/$(am__dirstamp)
-src/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) src/$(DEPDIR)
-	@: > src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_16_la-pcre2_auto_possess.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_16_la-pcre2_compile.lo: src/$(am__dirstamp) \
@@ -1325,10 +1409,14 @@
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_16_la-pcre2_context.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
+src/libpcre2_16_la-pcre2_convert.lo: src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_16_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_16_la-pcre2_error.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
+src/libpcre2_16_la-pcre2_extuni.lo: src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_16_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_16_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \
@@ -1376,10 +1464,14 @@
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_32_la-pcre2_context.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
+src/libpcre2_32_la-pcre2_convert.lo: src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_32_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_32_la-pcre2_error.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
+src/libpcre2_32_la-pcre2_extuni.lo: src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_32_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_32_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \
@@ -1427,10 +1519,14 @@
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_8_la-pcre2_context.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
+src/libpcre2_8_la-pcre2_convert.lo: src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_8_la-pcre2_dfa_match.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_8_la-pcre2_error.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
+src/libpcre2_8_la-pcre2_extuni.lo: src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_8_la-pcre2_find_bracket.lo: src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 src/libpcre2_8_la-pcre2_jit_compile.lo: src/$(am__dirstamp) \
@@ -1545,6 +1641,12 @@
 pcre2_jit_test$(EXEEXT): $(pcre2_jit_test_OBJECTS) $(pcre2_jit_test_DEPENDENCIES) $(EXTRA_pcre2_jit_test_DEPENDENCIES) 
 	@rm -f pcre2_jit_test$(EXEEXT)
 	$(AM_V_CCLD)$(pcre2_jit_test_LINK) $(pcre2_jit_test_OBJECTS) $(pcre2_jit_test_LDADD) $(LIBS)
+src/pcre2fuzzcheck-pcre2_fuzzsupport.$(OBJEXT): src/$(am__dirstamp) \
+	src/$(DEPDIR)/$(am__dirstamp)
+
+pcre2fuzzcheck$(EXEEXT): $(pcre2fuzzcheck_OBJECTS) $(pcre2fuzzcheck_DEPENDENCIES) $(EXTRA_pcre2fuzzcheck_DEPENDENCIES) 
+	@rm -f pcre2fuzzcheck$(EXEEXT)
+	$(AM_V_CCLD)$(pcre2fuzzcheck_LINK) $(pcre2fuzzcheck_OBJECTS) $(pcre2fuzzcheck_LDADD) $(LIBS)
 src/pcre2grep-pcre2grep.$(OBJEXT): src/$(am__dirstamp) \
 	src/$(DEPDIR)/$(am__dirstamp)
 
@@ -1601,14 +1703,17 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dftables.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_chartables.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_compile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_config.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_convert.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_extuni.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_jit_compile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_16_la-pcre2_maketables.Plo@am__quote@
@@ -1631,8 +1736,10 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_compile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_config.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_convert.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_extuni.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_jit_compile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_32_la-pcre2_maketables.Plo@am__quote@
@@ -1655,8 +1762,10 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_compile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_config.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_convert.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_extuni.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_jit_compile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_maketables.Plo@am__quote@
@@ -1676,6 +1785,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_8_la-pcre2_xclass.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libpcre2_posix_la-pcre2posix.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2_jit_test-pcre2_jit_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2fuzzcheck-pcre2_fuzzsupport.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2grep-pcre2grep.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pcre2test-pcre2test.Po@am__quote@
 
@@ -1703,6 +1813,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.o: src/pcre2_fuzzsupport.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_libs_libpcre2_fuzzsupport_a_CFLAGS) $(CFLAGS) -MT src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.o -MD -MP -MF src/$(DEPDIR)/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.Tpo -c -o src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.o `test -f 'src/pcre2_fuzzsupport.c' || echo '$(srcdir)/'`src/pcre2_fuzzsupport.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.Tpo src/$(DEPDIR)/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_fuzzsupport.c' object='src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_libs_libpcre2_fuzzsupport_a_CFLAGS) $(CFLAGS) -c -o src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.o `test -f 'src/pcre2_fuzzsupport.c' || echo '$(srcdir)/'`src/pcre2_fuzzsupport.c
+
+src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.obj: src/pcre2_fuzzsupport.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_libs_libpcre2_fuzzsupport_a_CFLAGS) $(CFLAGS) -MT src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.obj -MD -MP -MF src/$(DEPDIR)/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.Tpo -c -o src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.obj `if test -f 'src/pcre2_fuzzsupport.c'; then $(CYGPATH_W) 'src/pcre2_fuzzsupport.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_fuzzsupport.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.Tpo src/$(DEPDIR)/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_fuzzsupport.c' object='src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_libs_libpcre2_fuzzsupport_a_CFLAGS) $(CFLAGS) -c -o src/_libs_libpcre2_fuzzsupport_a-pcre2_fuzzsupport.obj `if test -f 'src/pcre2_fuzzsupport.c'; then $(CYGPATH_W) 'src/pcre2_fuzzsupport.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_fuzzsupport.c'; fi`
+
 src/libpcre2_16_la-pcre2_auto_possess.lo: src/pcre2_auto_possess.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_auto_possess.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Tpo -c -o src/libpcre2_16_la-pcre2_auto_possess.lo `test -f 'src/pcre2_auto_possess.c' || echo '$(srcdir)/'`src/pcre2_auto_possess.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_auto_possess.Plo
@@ -1731,6 +1855,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c
 
+src/libpcre2_16_la-pcre2_convert.lo: src/pcre2_convert.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_convert.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_convert.Tpo -c -o src/libpcre2_16_la-pcre2_convert.lo `test -f 'src/pcre2_convert.c' || echo '$(srcdir)/'`src/pcre2_convert.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_convert.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_convert.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_convert.c' object='src/libpcre2_16_la-pcre2_convert.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_convert.lo `test -f 'src/pcre2_convert.c' || echo '$(srcdir)/'`src/pcre2_convert.c
+
 src/libpcre2_16_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_16_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_dfa_match.Plo
@@ -1745,6 +1876,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c
 
+src/libpcre2_16_la-pcre2_extuni.lo: src/pcre2_extuni.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_extuni.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_extuni.Tpo -c -o src/libpcre2_16_la-pcre2_extuni.lo `test -f 'src/pcre2_extuni.c' || echo '$(srcdir)/'`src/pcre2_extuni.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_extuni.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_extuni.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_extuni.c' object='src/libpcre2_16_la-pcre2_extuni.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_16_la-pcre2_extuni.lo `test -f 'src/pcre2_extuni.c' || echo '$(srcdir)/'`src/pcre2_extuni.c
+
 src/libpcre2_16_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_16_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_16_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_16_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_16_la-pcre2_find_bracket.Plo
@@ -1899,6 +2037,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c
 
+src/libpcre2_32_la-pcre2_convert.lo: src/pcre2_convert.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_convert.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_convert.Tpo -c -o src/libpcre2_32_la-pcre2_convert.lo `test -f 'src/pcre2_convert.c' || echo '$(srcdir)/'`src/pcre2_convert.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_convert.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_convert.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_convert.c' object='src/libpcre2_32_la-pcre2_convert.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_convert.lo `test -f 'src/pcre2_convert.c' || echo '$(srcdir)/'`src/pcre2_convert.c
+
 src/libpcre2_32_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_32_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_dfa_match.Plo
@@ -1913,6 +2058,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c
 
+src/libpcre2_32_la-pcre2_extuni.lo: src/pcre2_extuni.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_extuni.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_extuni.Tpo -c -o src/libpcre2_32_la-pcre2_extuni.lo `test -f 'src/pcre2_extuni.c' || echo '$(srcdir)/'`src/pcre2_extuni.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_extuni.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_extuni.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_extuni.c' object='src/libpcre2_32_la-pcre2_extuni.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_32_la-pcre2_extuni.lo `test -f 'src/pcre2_extuni.c' || echo '$(srcdir)/'`src/pcre2_extuni.c
+
 src/libpcre2_32_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_32_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_32_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_32_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_32_la-pcre2_find_bracket.Plo
@@ -2067,6 +2219,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_context.lo `test -f 'src/pcre2_context.c' || echo '$(srcdir)/'`src/pcre2_context.c
 
+src/libpcre2_8_la-pcre2_convert.lo: src/pcre2_convert.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_convert.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_convert.Tpo -c -o src/libpcre2_8_la-pcre2_convert.lo `test -f 'src/pcre2_convert.c' || echo '$(srcdir)/'`src/pcre2_convert.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_convert.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_convert.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_convert.c' object='src/libpcre2_8_la-pcre2_convert.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_convert.lo `test -f 'src/pcre2_convert.c' || echo '$(srcdir)/'`src/pcre2_convert.c
+
 src/libpcre2_8_la-pcre2_dfa_match.lo: src/pcre2_dfa_match.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_dfa_match.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Tpo -c -o src/libpcre2_8_la-pcre2_dfa_match.lo `test -f 'src/pcre2_dfa_match.c' || echo '$(srcdir)/'`src/pcre2_dfa_match.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_dfa_match.Plo
@@ -2081,6 +2240,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_error.lo `test -f 'src/pcre2_error.c' || echo '$(srcdir)/'`src/pcre2_error.c
 
+src/libpcre2_8_la-pcre2_extuni.lo: src/pcre2_extuni.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_extuni.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_extuni.Tpo -c -o src/libpcre2_8_la-pcre2_extuni.lo `test -f 'src/pcre2_extuni.c' || echo '$(srcdir)/'`src/pcre2_extuni.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_extuni.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_extuni.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_extuni.c' object='src/libpcre2_8_la-pcre2_extuni.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -c -o src/libpcre2_8_la-pcre2_extuni.lo `test -f 'src/pcre2_extuni.c' || echo '$(srcdir)/'`src/pcre2_extuni.c
+
 src/libpcre2_8_la-pcre2_find_bracket.lo: src/pcre2_find_bracket.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpcre2_8_la_CFLAGS) $(CFLAGS) -MT src/libpcre2_8_la-pcre2_find_bracket.lo -MD -MP -MF src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Tpo -c -o src/libpcre2_8_la-pcre2_find_bracket.lo `test -f 'src/pcre2_find_bracket.c' || echo '$(srcdir)/'`src/pcre2_find_bracket.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Tpo src/$(DEPDIR)/libpcre2_8_la-pcre2_find_bracket.Plo
@@ -2228,6 +2394,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2_jit_test_CFLAGS) $(CFLAGS) -c -o src/pcre2_jit_test-pcre2_jit_test.obj `if test -f 'src/pcre2_jit_test.c'; then $(CYGPATH_W) 'src/pcre2_jit_test.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_jit_test.c'; fi`
 
+src/pcre2fuzzcheck-pcre2_fuzzsupport.o: src/pcre2_fuzzsupport.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2fuzzcheck_CFLAGS) $(CFLAGS) -MT src/pcre2fuzzcheck-pcre2_fuzzsupport.o -MD -MP -MF src/$(DEPDIR)/pcre2fuzzcheck-pcre2_fuzzsupport.Tpo -c -o src/pcre2fuzzcheck-pcre2_fuzzsupport.o `test -f 'src/pcre2_fuzzsupport.c' || echo '$(srcdir)/'`src/pcre2_fuzzsupport.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2fuzzcheck-pcre2_fuzzsupport.Tpo src/$(DEPDIR)/pcre2fuzzcheck-pcre2_fuzzsupport.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_fuzzsupport.c' object='src/pcre2fuzzcheck-pcre2_fuzzsupport.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2fuzzcheck_CFLAGS) $(CFLAGS) -c -o src/pcre2fuzzcheck-pcre2_fuzzsupport.o `test -f 'src/pcre2_fuzzsupport.c' || echo '$(srcdir)/'`src/pcre2_fuzzsupport.c
+
+src/pcre2fuzzcheck-pcre2_fuzzsupport.obj: src/pcre2_fuzzsupport.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2fuzzcheck_CFLAGS) $(CFLAGS) -MT src/pcre2fuzzcheck-pcre2_fuzzsupport.obj -MD -MP -MF src/$(DEPDIR)/pcre2fuzzcheck-pcre2_fuzzsupport.Tpo -c -o src/pcre2fuzzcheck-pcre2_fuzzsupport.obj `if test -f 'src/pcre2_fuzzsupport.c'; then $(CYGPATH_W) 'src/pcre2_fuzzsupport.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_fuzzsupport.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2fuzzcheck-pcre2_fuzzsupport.Tpo src/$(DEPDIR)/pcre2fuzzcheck-pcre2_fuzzsupport.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/pcre2_fuzzsupport.c' object='src/pcre2fuzzcheck-pcre2_fuzzsupport.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2fuzzcheck_CFLAGS) $(CFLAGS) -c -o src/pcre2fuzzcheck-pcre2_fuzzsupport.obj `if test -f 'src/pcre2_fuzzsupport.c'; then $(CYGPATH_W) 'src/pcre2_fuzzsupport.c'; else $(CYGPATH_W) '$(srcdir)/src/pcre2_fuzzsupport.c'; fi`
+
 src/pcre2grep-pcre2grep.o: src/pcre2grep.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcre2grep_CFLAGS) $(CFLAGS) -MT src/pcre2grep-pcre2grep.o -MD -MP -MF src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo -c -o src/pcre2grep-pcre2grep.o `test -f 'src/pcre2grep.c' || echo '$(srcdir)/'`src/pcre2grep.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) src/$(DEPDIR)/pcre2grep-pcre2grep.Tpo src/$(DEPDIR)/pcre2grep-pcre2grep.Po
@@ -2733,7 +2913,7 @@
 	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
 	|| chmod -R a+r "$(distdir)"
 dist-gzip: distdir
-	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
 	$(am__post_remove_distdir)
 dist-bzip2: distdir
 	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
@@ -2758,7 +2938,7 @@
 	@echo WARNING: "Support for shar distribution archives is" \
 	               "deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
-	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
 dist-zip: distdir
 	-rm -f $(distdir).zip
@@ -2775,7 +2955,7 @@
 distcheck: dist
 	case '$(DIST_ARCHIVES)' in \
 	*.tar.gz*) \
-	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
 	*.tar.bz2*) \
 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
 	*.tar.lz*) \
@@ -2785,7 +2965,7 @@
 	*.tar.Z*) \
 	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
 	*.shar.gz*) \
-	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
 	esac
@@ -2859,8 +3039,8 @@
 	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \
-		$(HEADERS)
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) \
+		$(MANS) $(DATA) $(HEADERS)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
@@ -2898,6 +3078,7 @@
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f .libs/$(am__dirstamp)
 	-rm -f src/$(DEPDIR)/$(am__dirstamp)
 	-rm -f src/$(am__dirstamp)
 	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
@@ -2911,7 +3092,8 @@
 clean: clean-am
 
 clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
-	clean-libtool clean-local clean-noinstPROGRAMS mostlyclean-am
+	clean-libtool clean-local clean-noinstLIBRARIES \
+	clean-noinstPROGRAMS mostlyclean-am
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -2996,29 +3178,30 @@
 .PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \
 	check-am clean clean-binPROGRAMS clean-cscope clean-generic \
 	clean-libLTLIBRARIES clean-libtool clean-local \
-	clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \
-	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
-	dist-xz dist-zip distcheck distclean distclean-compile \
-	distclean-generic distclean-hdr distclean-libtool \
-	distclean-local distclean-tags distcleancheck distdir \
-	distuninstallcheck dvi dvi-am html html-am info info-am \
-	install install-am install-binPROGRAMS install-binSCRIPTS \
-	install-data install-data-am install-dist_docDATA \
-	install-dist_htmlDATA install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am \
-	install-includeHEADERS install-info install-info-am \
-	install-libLTLIBRARIES install-man install-man1 install-man3 \
-	install-nodist_includeHEADERS install-pdf install-pdf-am \
-	install-pkgconfigDATA install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	recheck tags tags-am uninstall uninstall-am \
-	uninstall-binPROGRAMS uninstall-binSCRIPTS \
-	uninstall-dist_docDATA uninstall-dist_htmlDATA \
-	uninstall-includeHEADERS uninstall-libLTLIBRARIES \
-	uninstall-man uninstall-man1 uninstall-man3 \
-	uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA
+	clean-noinstLIBRARIES clean-noinstPROGRAMS cscope \
+	cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+	dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+	distcheck distclean distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-local distclean-tags \
+	distcleancheck distdir distuninstallcheck dvi dvi-am html \
+	html-am info info-am install install-am install-binPROGRAMS \
+	install-binSCRIPTS install-data install-data-am \
+	install-dist_docDATA install-dist_htmlDATA install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-includeHEADERS install-info \
+	install-info-am install-libLTLIBRARIES install-man \
+	install-man1 install-man3 install-nodist_includeHEADERS \
+	install-pdf install-pdf-am install-pkgconfigDATA install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
+	uninstall uninstall-am uninstall-binPROGRAMS \
+	uninstall-binSCRIPTS uninstall-dist_docDATA \
+	uninstall-dist_htmlDATA uninstall-includeHEADERS \
+	uninstall-libLTLIBRARIES uninstall-man uninstall-man1 \
+	uninstall-man3 uninstall-nodist_includeHEADERS \
+	uninstall-pkgconfigDATA
 
 .PRECIOUS: Makefile
 
diff --git a/dist2/NEWS b/dist2/NEWS
index 602e324..0093eb7 100644
--- a/dist2/NEWS
+++ b/dist2/NEWS
@@ -1,6 +1,117 @@
 News about PCRE2 releases
 -------------------------
 
+Version 10.31 12-February-2018
+------------------------------
+
+This is mainly a bugfix and tidying release (see ChangeLog for full details).
+However, there are some minor enhancements.
+
+1. New pcre2_config() options: PCRE2_CONFIG_NEVER_BACKSLASH_C and
+PCRE2_CONFIG_COMPILED_WIDTHS.
+
+2. New pcre2_pattern_info() option PCRE2_INFO_EXTRAOPTIONS to retrieve the
+extra compile time options.
+
+3. There are now public names for all the pcre2_compile() error numbers.
+
+4. Added PCRE2_CALLOUT_STARTMATCH and PCRE2_CALLOUT_BACKTRACK bits to a new
+field callout_flags in callout blocks.
+
+
+Version 10.30 14-August-2017
+----------------------------
+
+The full list of changes that includes bugfixes and tidies is, as always, in
+ChangeLog. These are the most important new features:
+
+1. The main interpreter, pcre2_match(), has been refactored into a new version
+that does not use recursive function calls (and therefore the system stack) for
+remembering backtracking positions. This makes --disable-stack-for-recursion a
+NOOP. The new implementation allows backtracking into recursive group calls in
+patterns, making it more compatible with Perl, and also fixes some other
+previously hard-to-do issues. For patterns that have a lot of backtracking, the
+heap is now used, and there is explicit limit on the amount, settable by
+pcre2_set_heap_limit() or (*LIMIT_HEAP=xxx). The "recursion limit" is retained,
+but is renamed as "depth limit" (though the old names remain for
+compatibility).
+
+There is also a change in the way callouts from pcre2_match() are handled. The
+offset_vector field in the callout block is no longer a pointer to the
+actual ovector that was passed to the matching function in the match data
+block. Instead it points to an internal ovector of a size large enough to hold
+all possible captured substrings in the pattern.
+
+2. The new option PCRE2_ENDANCHORED insists that a pattern match must end at
+the end of the subject.
+
+3. The new option PCRE2_EXTENDED_MORE implements Perl's /xx feature, and
+pcre2test is upgraded to support it. Setting within the pattern by (?xx) is
+also supported.
+
+4. (?n) can be used to set PCRE2_NO_AUTO_CAPTURE, because Perl now has this.
+
+5. Additional compile options in the compile context are now available, and the
+first two are: PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES and
+PCRE2_EXTRA_BAD_ESCAPE_IS LITERAL.
+
+6. The newline type PCRE2_NEWLINE_NUL is now available.
+
+7. The match limit value now also applies to pcre2_dfa_match() as there are
+patterns that can use up a lot of resources without necessarily recursing very
+deeply.
+
+8. The option REG_PEND (a GNU extension) is now available for the POSIX
+wrapper. Also there is a new option PCRE2_LITERAL which is used to support
+REG_NOSPEC.
+
+9. PCRE2_EXTRA_MATCH_LINE and PCRE2_EXTRA_MATCH_WORD are implemented for the
+benefit of pcre2grep, and pcre2grep's -F, -w, and -x options are re-implemented
+using PCRE2_LITERAL, PCRE2_EXTRA_MATCH_WORD, and PCRE2_EXTRA_MATCH_LINE. This
+is tidier and also fixes some bugs.
+
+10. The Unicode tables are upgraded from Unicode 8.0.0 to Unicode 10.0.0.
+
+11. There are some experimental functions for converting foreign patterns
+(globs and POSIX patterns) into PCRE2 patterns.
+
+
+Version 10.23 14-February-2017
+------------------------------
+
+1. ChangeLog has the details of a lot of bug fixes and tidies.
+
+2. There has been a major re-factoring of the pcre2_compile.c file. Most syntax
+checking is now done in the pre-pass that identifies capturing groups. This has
+reduced the amount of duplication and made the code tidier. While doing this,
+some minor bugs and Perl incompatibilities were fixed (see ChangeLog for
+details.)
+
+3. Back references are now permitted in lookbehind assertions when there are
+no duplicated group numbers (that is, (?| has not been used), and, if the
+reference is by name, there is only one group of that name. The referenced
+group must, of course be of fixed length.
+
+4. \g{+<number>} (e.g. \g{+2} ) is now supported. It is a "forward back
+reference" and can be useful in repetitions (compare \g{-<number>} ). Perl does
+not recognize this syntax.
+
+5. pcre2grep now automatically expands its buffer up to a maximum set by
+--max-buffer-size.
+
+6. The -t option (grand total) has been added to pcre2grep.
+
+7. A new function called pcre2_code_copy_with_tables() exists to copy a
+compiled pattern along with a private copy of the character tables that is
+uses.
+
+8. A user supplied a number of patches to upgrade pcre2grep under Windows and
+tidy the code.
+
+9. Several updates have been made to pcre2test and test scripts (see
+ChangeLog).
+
+
 Version 10.22 29-July-2016
 --------------------------
 
diff --git a/dist2/NON-AUTOTOOLS-BUILD b/dist2/NON-AUTOTOOLS-BUILD
index ceb9245..0775794 100644
--- a/dist2/NON-AUTOTOOLS-BUILD
+++ b/dist2/NON-AUTOTOOLS-BUILD
@@ -1,10 +1,6 @@
 Building PCRE2 without using autotools
 --------------------------------------
 
-This document has been converted from the PCRE1 document. I have removed a
-number of sections about building in various environments, as they applied only
-to PCRE1 and are probably out of date.
-
 This document contains the following sections:
 
   General
@@ -49,7 +45,7 @@
      macro settings that it contains to whatever is appropriate for your
      environment. In particular, you can alter the definition of the NEWLINE
      macro to specify what character(s) you want to be interpreted as line
-     terminators.
+     terminators by default.
 
      When you compile any of the PCRE2 modules, you must specify
      -DHAVE_CONFIG_H to your compiler so that src/config.h is included in the
@@ -95,8 +91,10 @@
        pcre2_compile.c
        pcre2_config.c
        pcre2_context.c
+       pcre2_convert.c
        pcre2_dfa_match.c
        pcre2_error.c
+       pcre2_extuni.c
        pcre2_find_bracket.c
        pcre2_jit_compile.c
        pcre2_maketables.c
@@ -123,10 +121,14 @@
      Note that you must compile pcre2_jit_compile.c, even if you have not
      defined SUPPORT_JIT in src/config.h, because when JIT support is not
      configured, dummy functions are compiled. When JIT support IS configured,
-     pcre2_compile.c #includes other files from the sljit subdirectory, where
-     there should be 16 files, all of whose names begin with "sljit". It also
-     #includes src/pcre2_jit_match.c and src/pcre2_jit_misc.c, so you should
-     not compile these yourself.
+     pcre2_jit_compile.c #includes other files from the sljit subdirectory,
+     all of whose names begin with "sljit". It also #includes
+     src/pcre2_jit_match.c and src/pcre2_jit_misc.c, so you should not compile
+     these yourself.
+
+     Not also that the pcre2_fuzzsupport.c file contains special code that is
+     useful to those who want to run fuzzing tests on the PCRE2 library. Unless
+     you are doing that, you can ignore it.
 
  (5) Now link all the compiled code into an object library in whichever form
      your system keeps such libraries. This is the basic PCRE2 C 8-bit library.
@@ -174,26 +176,18 @@
 
 (11) If you want to use the pcre2grep command, compile and link
      src/pcre2grep.c; it uses only the basic 8-bit PCRE2 library (it does not
-     need the pcre2posix library).
+     need the pcre2posix library). If you have built the PCRE2 library with JIT
+     support by defining SUPPORT_JIT in src/config.h, you can also define
+     SUPPORT_PCRE2GREP_JIT, which causes pcre2grep to make use of JIT (unless
+     it is run with --no-jit). If you define SUPPORT_PCRE2GREP_JIT without
+     defining SUPPORT_JIT, pcre2grep does not try to make use of JIT.
 
 
 STACK SIZE IN WINDOWS ENVIRONMENTS
 
-The default processor stack size of 1Mb in some Windows environments is too
-small for matching patterns that need much recursion. In particular, test 2 may
-fail because of this. Normally, running out of stack causes a crash, but there
-have been cases where the test program has just died silently. See your linker
-documentation for how to increase stack size if you experience problems. If you
-are using CMake (see "BUILDING PCRE2 ON WINDOWS WITH CMAKE" below) and the gcc
-compiler, you can increase the stack size for pcre2test and pcre2grep by
-setting the CMAKE_EXE_LINKER_FLAGS variable to "-Wl,--stack,8388608" (for
-example). The Linux default of 8Mb is a reasonable choice for the stack, though
-even that can be too small for some pattern/subject combinations.
-
-PCRE2 has a compile configuration option to disable the use of stack for
-recursion so that heap is used instead. However, pattern matching is
-significantly slower when this is done. There is more about stack usage in the
-"pcre2stack" documentation.
+Prior to release 10.30 the default system stack size of 1Mb in some Windows
+environments caused issues with some tests. This should no longer be the case
+for 10.30 and later releases.
 
 
 LINKING PROGRAMS IN WINDOWS ENVIRONMENTS
@@ -375,18 +369,19 @@
 z/OS and z/VM are operating systems for mainframe computers, produced by IBM.
 The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and
 applications can be supported through UNIX System Services, and in such an
-environment PCRE2 can be built in the same way as in other systems. However, in
-native z/OS (without UNIX System Services) and in z/VM, special ports are
-required. For details, please see this web site:
+environment it should be possible to build PCRE2 in the same way as in other
+systems, with the EBCDIC related configuration settings, but it is not known if
+anybody has tried this.
 
-  http://www.zaconsultants.net
+In native z/OS (without UNIX System Services) and in z/VM, special ports are
+required. For details, please see file 939 on this web site:
 
-The site currently has ports for PCRE1 releases, but PCRE2 should follow in due
-course.
+  http://www.cbttape.org
 
-You may also download PCRE1 from WWW.CBTTAPE.ORG, file 882. Everything, source
-and executable, is in EBCDIC and native z/OS file formats and this is the
-recommended download site.
+Everything in that location, source and executable, is in EBCDIC and native
+z/OS file formats. The port provides an API for LE languages such as COBOL and
+for the z/OS and z/VM versions of the Rexx languages.
 
-=============================
-Last Updated: 16 July 2015
+===============================
+Last Updated: 13 September 2017
+===============================
diff --git a/dist2/PrepareRelease b/dist2/PrepareRelease
index 114fce0..9aa6b7d 100755
--- a/dist2/PrepareRelease
+++ b/dist2/PrepareRelease
@@ -66,7 +66,7 @@
 echo "Making pcre2.txt"
 for file in pcre2 pcre2api pcre2build pcre2callout pcre2compat pcre2jit \
             pcre2limits pcre2matching pcre2partial pcre2pattern pcre2perform \
-            pcre2posix pcre2sample pcre2serialize pcre2stack pcre2syntax \
+            pcre2posix pcre2sample pcre2serialize pcre2syntax \
             pcre2unicode ; do
   echo "  Processing $file.3"
   nroff -c -man $file.3 >$file.rawtxt
@@ -146,7 +146,6 @@
   toc=-toc
   if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi
   if [ "$base" = "pcre2sample" ]  || \
-     [ "$base" = "pcre2stack" ]   || \
      [ "$base" = "pcre2compat" ]  || \
      [ "$base" = "pcre2limits" ]  || \
      [ "$base" = "pcre2unicode" ] ; then
@@ -197,8 +196,10 @@
   src/pcre2_compile.c \
   src/pcre2_config.c \
   src/pcre2_context.c \
+  src/pcre2_convert.c \
   src/pcre2_dfa_match.c \
   src/pcre2_error.c \
+  src/pcre2_extuni.c \
   src/pcre2_find_bracket.c \
   src/pcre2_internal.h \
   src/pcre2_intmodedep.h \
diff --git a/dist2/README b/dist2/README
index 03d67f6..52859a9 100644
--- a/dist2/README
+++ b/dist2/README
@@ -15,8 +15,8 @@
 
    https://lists.exim.org/mailman/listinfo/pcre-dev
 
-Please read the NEWS file if you are upgrading from a previous release.
-The contents of this README file are:
+Please read the NEWS file if you are upgrading from a previous release. The
+contents of this README file are:
 
   The PCRE2 APIs
   Documentation for PCRE2
@@ -44,8 +44,8 @@
 
 The distribution does contain a set of C wrapper functions for the 8-bit
 library that are based on the POSIX regular expression API (see the pcre2posix
-man page). These can be found in a library called libpcre2posix. Note that this
-just provides a POSIX calling interface to PCRE2; the regular expressions
+man page). These can be found in a library called libpcre2-posix. Note that
+this just provides a POSIX calling interface to PCRE2; the regular expressions
 themselves still follow Perl syntax and semantics. The POSIX API is restricted,
 and does not give full access to all of PCRE2's facilities.
 
@@ -58,8 +58,8 @@
 If you are using the POSIX interface to PCRE2 and there is already a POSIX
 regex library installed on your system, as well as worrying about the regex.h
 header file (as mentioned above), you must also take care when linking programs
-to ensure that they link with PCRE2's libpcre2posix library. Otherwise they may
-pick up the POSIX functions of the same name from the other library.
+to ensure that they link with PCRE2's libpcre2-posix library. Otherwise they
+may pick up the POSIX functions of the same name from the other library.
 
 One way of avoiding this confusion is to compile PCRE2 with the addition of
 -Dregcomp=PCRE2regcomp (and similarly for the other POSIX functions) to the
@@ -95,10 +95,9 @@
 Building PCRE2 on non-Unix-like systems
 ---------------------------------------
 
-For a non-Unix-like system, please read the comments in the file
-NON-AUTOTOOLS-BUILD, though if your system supports the use of "configure" and
-"make" you may be able to build PCRE2 using autotools in the same way as for
-many Unix-like systems.
+For a non-Unix-like system, please read the file NON-AUTOTOOLS-BUILD, though if
+your system supports the use of "configure" and "make" you may be able to build
+PCRE2 using autotools in the same way as for many Unix-like systems.
 
 PCRE2 can also be configured using CMake, which can be run in various ways
 (command line, GUI, etc). This creates Makefiles, solution files, etc. The file
@@ -172,21 +171,24 @@
   give large performance improvements on certain platforms, add --enable-jit to
   the "configure" command. This support is available only for certain hardware
   architectures. If you try to enable it on an unsupported architecture, there
-  will be a compile time error.
+  will be a compile time error. If you are running under SELinux you may also
+  want to add --enable-jit-sealloc, which enables the use of an execmem
+  allocator in JIT that is compatible with SELinux. This has no effect if JIT
+  is not enabled.
 
-. If you do not want to make use of the support for UTF-8 Unicode character
-  strings in the 8-bit library, UTF-16 Unicode character strings in the 16-bit
-  library, or UTF-32 Unicode character strings in the 32-bit library, you can
-  add --disable-unicode to the "configure" command. This reduces the size of
-  the libraries. It is not possible to configure one library with Unicode
-  support, and another without, in the same configuration.
+. If you do not want to make use of the default support for UTF-8 Unicode
+  character strings in the 8-bit library, UTF-16 Unicode character strings in
+  the 16-bit library, or UTF-32 Unicode character strings in the 32-bit
+  library, you can add --disable-unicode to the "configure" command. This
+  reduces the size of the libraries. It is not possible to configure one
+  library with Unicode support, and another without, in the same configuration.
+  It is also not possible to use --enable-ebcdic (see below) with Unicode
+  support, so if this option is set, you must also use --disable-unicode.
 
   When Unicode support is available, the use of a UTF encoding still has to be
   enabled by setting the PCRE2_UTF option at run time or starting a pattern
   with (*UTF). When PCRE2 is compiled with Unicode support, its input can only
-  either be ASCII or UTF-8/16/32, even when running on EBCDIC platforms. It is
-  not possible to use both --enable-unicode and --enable-ebcdic at the same
-  time.
+  either be ASCII or UTF-8/16/32, even when running on EBCDIC platforms.
 
   As well as supporting UTF strings, Unicode support includes support for the
   \P, \p, and \X sequences that recognize Unicode character properties.
@@ -196,20 +198,14 @@
   or starting a pattern with (*UCP).
 
 . You can build PCRE2 to recognize either CR or LF or the sequence CRLF, or any
-  of the preceding, or any of the Unicode newline sequences, as indicating the
-  end of a line. Whatever you specify at build time is the default; the caller
-  of PCRE2 can change the selection at run time. The default newline indicator
-  is a single LF character (the Unix standard). You can specify the default
-  newline indicator by adding --enable-newline-is-cr, --enable-newline-is-lf,
-  --enable-newline-is-crlf, --enable-newline-is-anycrlf, or
-  --enable-newline-is-any to the "configure" command, respectively.
-
-  If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of
-  the standard tests will fail, because the lines in the test files end with
-  LF. Even if the files are edited to change the line endings, there are likely
-  to be some failures. With --enable-newline-is-anycrlf or
-  --enable-newline-is-any, many tests should succeed, but there may be some
-  failures.
+  of the preceding, or any of the Unicode newline sequences, or the NUL (zero)
+  character as indicating the end of a line. Whatever you specify at build time
+  is the default; the caller of PCRE2 can change the selection at run time. The
+  default newline indicator is a single LF character (the Unix standard). You
+  can specify the default newline indicator by adding --enable-newline-is-cr,
+  --enable-newline-is-lf, --enable-newline-is-crlf,
+  --enable-newline-is-anycrlf, --enable-newline-is-any, or
+  --enable-newline-is-nul to the "configure" command, respectively.
 
 . By default, the sequence \R in a pattern matches any Unicode line ending
   sequence. This is independent of the option specifying what PCRE2 considers
@@ -231,49 +227,44 @@
 
   --with-parens-nest-limit=500
 
-. PCRE2 has a counter that can be set to limit the amount of resources it uses
-  when matching a pattern. If the limit is exceeded during a match, the match
-  fails. The default is ten million. You can change the default by setting, for
-  example,
+. PCRE2 has a counter that can be set to limit the amount of computing resource
+  it uses when matching a pattern. If the limit is exceeded during a match, the
+  match fails. The default is ten million. You can change the default by
+  setting, for example,
 
   --with-match-limit=500000
 
   on the "configure" command. This is just the default; individual calls to
-  pcre2_match() can supply their own value. There is more discussion on the
-  pcre2api man page.
+  pcre2_match() or pcre2_dfa_match() can supply their own value. There is more
+  discussion in the pcre2api man page (search for pcre2_set_match_limit).
 
-. There is a separate counter that limits the depth of recursive function calls
-  during a matching process. This also has a default of ten million, which is
-  essentially "unlimited". You can change the default by setting, for example,
+. There is a separate counter that limits the depth of nested backtracking
+  during a matching process, which indirectly limits the amount of heap memory
+  that is used. This also has a default of ten million, which is essentially
+  "unlimited". You can change the default by setting, for example,
 
-  --with-match-limit-recursion=500000
+  --with-match-limit-depth=5000
 
-  Recursive function calls use up the runtime stack; running out of stack can
-  cause programs to crash in strange ways. There is a discussion about stack
-  sizes in the pcre2stack man page.
+  There is more discussion in the pcre2api man page (search for
+  pcre2_set_depth_limit).
+
+. You can also set an explicit limit on the amount of heap memory used by
+  the pcre2_match() interpreter:
+
+  --with-heap-limit=500
+
+  The units are kilobytes. This limit does not apply when the JIT optimization
+  (which has its own memory control features) is used. There is more discussion
+  on the pcre2api man page (search for pcre2_set_heap_limit).
 
 . In the 8-bit library, the default maximum compiled pattern size is around
-  64K. You can increase this by adding --with-link-size=3 to the "configure"
-  command. PCRE2 then uses three bytes instead of two for offsets to different
-  parts of the compiled pattern. In the 16-bit library, --with-link-size=3 is
-  the same as --with-link-size=4, which (in both libraries) uses four-byte
-  offsets. Increasing the internal link size reduces performance in the 8-bit
-  and 16-bit libraries. In the 32-bit library, the link size setting is
-  ignored, as 4-byte offsets are always used.
-
-. You can build PCRE2 so that its internal match() function that is called from
-  pcre2_match() does not call itself recursively. Instead, it uses memory
-  blocks obtained from the heap to save data that would otherwise be saved on
-  the stack. To build PCRE2 like this, use
-
-  --disable-stack-for-recursion
-
-  on the "configure" command. PCRE2 runs more slowly in this mode, but it may
-  be necessary in environments with limited stack sizes. This applies only to
-  the normal execution of the pcre2_match() function; if JIT support is being
-  successfully used, it is not relevant. Equally, it does not apply to
-  pcre2_dfa_match(), which does not use deeply nested recursion. There is a
-  discussion about stack sizes in the pcre2stack man page.
+  64K bytes. You can increase this by adding --with-link-size=3 to the
+  "configure" command. PCRE2 then uses three bytes instead of two for offsets
+  to different parts of the compiled pattern. In the 16-bit library,
+  --with-link-size=3 is the same as --with-link-size=4, which (in both
+  libraries) uses four-byte offsets. Increasing the internal link size reduces
+  performance in the 8-bit and 16-bit libraries. In the 32-bit library, the
+  link size setting is ignored, as 4-byte offsets are always used.
 
 . For speed, PCRE2 uses four tables for manipulating and identifying characters
   whose code point values are less than 256. By default, it uses a set of
@@ -339,12 +330,23 @@
 
   Of course, the relevant libraries must be installed on your system.
 
-. The default size (in bytes) of the internal buffer used by pcre2grep can be
-  set by, for example:
+. The default starting size (in bytes) of the internal buffer used by pcre2grep
+  can be set by, for example:
 
   --with-pcre2grep-bufsize=51200
 
-  The value must be a plain integer. The default is 20480.
+  The value must be a plain integer. The default is 20480. The amount of memory
+  used by pcre2grep is actually three times this number, to allow for "before"
+  and "after" lines. If very long lines are encountered, the buffer is
+  automatically enlarged, up to a fixed maximum size.
+
+. The default maximum size of pcre2grep's internal buffer can be set by, for
+  example:
+
+  --with-pcre2grep-max-bufsize=2097152
+
+  The default is either 1048576 or the value of --with-pcre2grep-bufsize,
+  whichever is the larger.
 
 . It is possible to compile pcre2test so that it links with the libreadline
   or libedit libraries, by specifying, respectively,
@@ -369,6 +371,29 @@
   tgetflag, or tgoto, this is the problem, and linking with the ncurses library
   should fix it.
 
+. There is a special option called --enable-fuzz-support for use by people who
+  want to run fuzzing tests on PCRE2. At present this applies only to the 8-bit
+  library. If set, it causes an extra library called libpcre2-fuzzsupport.a to
+  be built, but not installed. This contains a single function called
+  LLVMFuzzerTestOneInput() whose arguments are a pointer to a string and the
+  length of the string. When called, this function tries to compile the string
+  as a pattern, and if that succeeds, to match it. This is done both with no
+  options and with some random options bits that are generated from the string.
+  Setting --enable-fuzz-support also causes a binary called pcre2fuzzcheck to
+  be created. This is normally run under valgrind or used when PCRE2 is
+  compiled with address sanitizing enabled. It calls the fuzzing function and
+  outputs information about it is doing. The input strings are specified by
+  arguments: if an argument starts with "=" the rest of it is a literal input
+  string. Otherwise, it is assumed to be a file name, and the contents of the
+  file are the test string.
+
+. Releases before 10.30 could be compiled with --disable-stack-for-recursion,
+  which caused pcre2_match() to use individual blocks on the heap for
+  backtracking instead of recursive function calls (which use the stack). This
+  is now obsolete since pcre2_match() was refactored always to use the heap (in
+  a much more efficient way than before). This option is retained for backwards
+  compatibility, but has no effect other than to output a warning.
+
 The "configure" script builds the following files for the basic C library:
 
 . Makefile             the makefile that builds the library
@@ -543,7 +568,7 @@
 
 
 Testing PCRE2
-------------
+-------------
 
 To test the basic PCRE2 library on a Unix-like system, run the RunTest script.
 There is another script called RunGrepTest that tests the pcre2grep command.
@@ -635,32 +660,43 @@
 Tests 6 and 7 check the pcre2_dfa_match() alternative matching function, in
 non-UTF mode and UTF-mode with Unicode property support, respectively.
 
-Test 8 checks some internal offsets and code size features; it is run only when
-the default "link size" of 2 is set (in other cases the sizes change) and when
-Unicode support is enabled.
+Test 8 checks some internal offsets and code size features, but it is run only
+when Unicode support is enabled. The output is different in 8-bit, 16-bit, and
+32-bit modes and for different link sizes, so there are different output files
+for each mode and link size.
 
 Tests 9 and 10 are run only in 8-bit mode, and tests 11 and 12 are run only in
 16-bit and 32-bit modes. These are tests that generate different output in
 8-bit mode. Each pair are for general cases and Unicode support, respectively.
+
 Test 13 checks the handling of non-UTF characters greater than 255 by
 pcre2_dfa_match() in 16-bit and 32-bit modes.
 
-Test 14 contains a number of tests that must not be run with JIT. They check,
+Test 14 contains some special UTF and UCP tests that give different output for
+different code unit widths.
+
+Test 15 contains a number of tests that must not be run with JIT. They check,
 among other non-JIT things, the match-limiting features of the intepretive
 matcher.
 
-Test 15 is run only when JIT support is not available. It checks that an
+Test 16 is run only when JIT support is not available. It checks that an
 attempt to use JIT has the expected behaviour.
 
-Test 16 is run only when JIT support is available. It checks JIT complete and
+Test 17 is run only when JIT support is available. It checks JIT complete and
 partial modes, match-limiting under JIT, and other JIT-specific features.
 
-Tests 17 and 18 are run only in 8-bit mode. They check the POSIX interface to
+Tests 18 and 19 are run only in 8-bit mode. They check the POSIX interface to
 the 8-bit library, without and with Unicode support, respectively.
 
-Test 19 checks the serialization functions by writing a set of compiled
+Test 20 checks the serialization functions by writing a set of compiled
 patterns to a file, and then reloading and checking them.
 
+Tests 21 and 22 test \C support when the use of \C is not locked out, without
+and with UTF support, respectively. Test 23 tests \C when it is locked out.
+
+Tests 24 and 25 test the experimental pattern conversion functions, without and
+with UTF support, respectively.
+
 
 Character tables
 ----------------
@@ -679,7 +715,7 @@
 by the program dftables (compiled from dftables.c), which uses the ANSI C
 character handling functions such as isalnum(), isalpha(), isupper(),
 islower(), etc. to build the table sources. This means that the default C
-locale which is set for your system will control the contents of these default
+locale that is set for your system will control the contents of these default
 tables. You can change the default tables by editing pcre2_chartables.c and
 then re-building PCRE2. If you do this, you should take care to ensure that the
 file does not get automatically re-generated. The best way to do this is to
@@ -734,8 +770,10 @@
   src/pcre2_compile.c      )
   src/pcre2_config.c       )
   src/pcre2_context.c      )
+  src/pcre2_convert.c      )
   src/pcre2_dfa_match.c    )
   src/pcre2_error.c        )
+  src/pcre2_extuni.c       )
   src/pcre2_find_bracket.c )
   src/pcre2_jit_compile.c  )
   src/pcre2_jit_match.c    ) sources for the functions in the library,
@@ -757,6 +795,7 @@
   src/pcre2_xclass.c       )
 
   src/pcre2_printint.c     debugging function that is used by pcre2test,
+  src/pcre2_fuzzsupport.c  function for (optional) fuzzing support
 
   src/config.h.in          template for config.h, when built by "configure"
   src/pcre2.h.in           template for pcre2.h when built by "configure"
@@ -772,7 +811,6 @@
   src/pcre2demo.c          simple demonstration of coding calls to PCRE2
   src/pcre2grep.c          source of a grep utility that uses PCRE2
   src/pcre2test.c          comprehensive test program
-  src/pcre2_printint.c     part of pcre2test
   src/pcre2_jit_test.c     JIT test program
 
 (C) Auxiliary files:
@@ -814,7 +852,7 @@
   libpcre2-8.pc.in         template for libpcre2-8.pc for pkg-config
   libpcre2-16.pc.in        template for libpcre2-16.pc for pkg-config
   libpcre2-32.pc.in        template for libpcre2-32.pc for pkg-config
-  libpcre2posix.pc.in      template for libpcre2posix.pc for pkg-config
+  libpcre2-posix.pc.in     template for libpcre2-posix.pc for pkg-config
   ltmain.sh                file used to build a libtool script
   missing                  ) common stub for a few missing GNU programs while
                            )   installing, generated by automake
@@ -837,12 +875,12 @@
 
 (E) Auxiliary files for building PCRE2 "by hand"
 
-  pcre2.h.generic         ) a version of the public PCRE2 header file
+  src/pcre2.h.generic     ) a version of the public PCRE2 header file
                           )   for use in non-"configure" environments
-  config.h.generic        ) a version of config.h for use in non-"configure"
+  src/config.h.generic    ) a version of config.h for use in non-"configure"
                           )   environments
 
 Philip Hazel
 Email local part: ph10
 Email domain: cam.ac.uk
-Last updated: 01 April 2016
+Last updated: 12 September 2017
diff --git a/dist2/RunGrepTest b/dist2/RunGrepTest
index a3e1312..a26f677 100755
--- a/dist2/RunGrepTest
+++ b/dist2/RunGrepTest
@@ -11,7 +11,8 @@
 
 # Remove any non-default colouring and aliases that the caller may have set.
 
-unset PCRE2GREP_COLOUR PCRE2GREP_COLOR
+unset PCRE2GREP_COLOUR PCRE2GREP_COLOR PCREGREP_COLOUR PCREGREP_COLOR
+unset GREP_COLOR GREP_COLORS
 unset cp ls mv rm
 
 # Remember the current (build) directory, set the program to be tested, and
@@ -22,12 +23,12 @@
 pcre2test=$builddir/pcre2test
 
 if [ ! -x $pcre2grep ] ; then
-  echo "** $pcre2grep does not exist or is not execuatble."
+  echo "** $pcre2grep does not exist or is not executable."
   exit 1
 fi
 
 if [ ! -x $pcre2test ] ; then
-  echo "** $pcre2test does not exist or is not execuatble."
+  echo "** $pcre2test does not exist or is not executable."
   exit 1
 fi
 
@@ -247,7 +248,7 @@
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 36 -----------------------------" >>testtrygrep
-(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude=grepinputM --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 37 -----------------------------" >>testtrygrep
@@ -390,6 +391,12 @@
 echo "---------------------------- Test 70 -----------------------------" >>testtrygrep
 (cd $srcdir; $valgrind $vjs $pcre2grep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep
 echo "RC=$?" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep --color=always -M -n "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -M -n "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep
+echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 71 -----------------------------" >>testtrygrep
 (cd $srcdir; $valgrind $vjs $pcre2grep -o "^01|^02|^03" ./testdata/grepinput) >>testtrygrep
@@ -440,7 +447,7 @@
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 83 -----------------------------" >>testtrygrep
-(cd $srcdir; $valgrind $vjs $pcre2grep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1
+(cd $srcdir; $valgrind $vjs $pcre2grep --buffer-size=10 --max-buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 84 -----------------------------" >>testtrygrep
@@ -493,25 +500,25 @@
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 96 -----------------------------" >>testtrygrep
-(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include-dir=testdata --exclude '^(?!grepinput)' --exclude=grepinputM 'fox' ./test* | sort) >>testtrygrep
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 97 -----------------------------" >>testtrygrep
 echo "grepinput$" >testtemp1grep
 echo "grepinput8" >>testtemp1grep
-(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include=grepinput --exclude=grepinputM --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 98 -----------------------------" >>testtrygrep
 echo "grepinput$" >testtemp1grep
 echo "grepinput8" >>testtemp1grep
-(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --exclude=grepinput3 --exclude=grepinputM --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 99 -----------------------------" >>testtrygrep
 echo "grepinput$" >testtemp1grep
 echo "grepinput8" >testtemp2grep
-(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include grepinput --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -L -r --include grepinput --exclude=grepinputM --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
 echo "RC=$?" >>testtrygrep
 
 echo "---------------------------- Test 100 ------------------------------" >>testtrygrep
@@ -568,6 +575,73 @@
 (cd $srcdir; $valgrind $vjs $pcre2grep --file-offsets -M 'match (\d+):\n (.)\n' testdata/grepinput) >>testtrygrep
 echo "RC=$?" >>testtrygrep
 
+echo "---------------------------- Test 113 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep --total-count 'the' testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 114 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -tc 'the' testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 115 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -tlc 'the' testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 116 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep --exclude=grepinputM -th 'the' testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 117 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -tch 'the' testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 118 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -tL 'the' testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 119 -----------------------------" >>testtrygrep
+printf "123\n456\n789\n---abc\ndef\nxyz\n---\n" >testNinputgrep
+$valgrind $vjs $pcre2grep -Mo '(\n|[^-])*---' testNinputgrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 120 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -HO '$0:$2$1$3' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 121 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -F '\E and (regex)' testdata/grepinputv) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 122 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -w 'cat|dog' testdata/grepinputv) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 123 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -w 'dog|cat' testdata/grepinputv) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 124 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -Mn --colour=always 'start[\s]+end' testdata/grepinputM) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -Mn --colour=always -A2 'start[\s]+end' testdata/grepinputM) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -Mn 'start[\s]+end' testdata/grepinputM) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -Mn -A2 'start[\s]+end' testdata/grepinputM) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 125 -----------------------------" >>testtrygrep
+printf "abcd\n" >testNinputgrep
+$valgrind $vjs $pcre2grep --colour=always '(?<=\K.)' testNinputgrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
+$valgrind $vjs $pcre2grep --colour=always '(?=.\K)' testNinputgrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
+$valgrind $vjs $pcre2grep --colour=always '(?<=\K[ac])' testNinputgrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
+$valgrind $vjs $pcre2grep --colour=always '(?=[ac]\K)' testNinputgrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+
 # Now compare the results.
 
 $cf $srcdir/testdata/grepoutput testtrygrep
@@ -628,6 +702,21 @@
 printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtrygrep
 $valgrind $vjs $pcre2grep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep
 
+# It seems inpossible to handle NUL characters easily in Solaris (aka SunOS).
+# The version of sed explicitly doesn't like them. For the moment, we just
+# don't run this test under SunOS. Fudge the output so that the comparison
+# works. A similar problem has also been reported for MacOS (Darwin).
+
+printf "%c--------------------------- Test N7 ------------------------------\r\n" - >>testtrygrep
+uname=`uname`
+if [ "$uname" != "SunOS" -a "$uname" != "Darwin" ] ; then
+  printf "abc\0def" >testNinputgrep
+  $valgrind $vjs $pcre2grep -na --newline=nul "^(abc|def)" testNinputgrep | sed 's/\x00/ZERO/' >>testtrygrep
+  echo "" >>testtrygrep
+else
+  echo '1:abcZERO2:def' >>testtrygrep
+fi
+
 $cf $srcdir/testdata/grepoutputN testtrygrep
 if [ $? != 0 ] ; then exit 1; fi
 
@@ -637,6 +726,9 @@
   echo "Testing pcre2grep script callouts"
   $valgrind $vjs $pcre2grep '(T)(..(.))(?C"/bin/echo|Arg1: [$1] [$2] [$3]|Arg2: $|${1}$| ($4) ($14) ($0)")()' $srcdir/testdata/grepinputv >testtrygrep
   $valgrind $vjs $pcre2grep '(T)(..(.))()()()()()()()(..)(?C"/bin/echo|Arg1: [$11] [${11}]")' $srcdir/testdata/grepinputv >>testtrygrep
+  $valgrind $vjs $pcre2grep '(T)(?C"|$0:$1$n")' $srcdir/testdata/grepinputv >>testtrygrep
+  $valgrind $vjs $pcre2grep '(T)(?C"|$1$n")(*F)' $srcdir/testdata/grepinputv >>testtrygrep
+  # The above has no newline, which 'diff -ub' ignores, so add one.
   $cf $srcdir/testdata/grepoutputC testtrygrep
   if [ $? != 0 ] ; then exit 1; fi
 else
diff --git a/dist2/RunGrepTest.bat b/dist2/RunGrepTest.bat
new file mode 100644
index 0000000..50a9644
--- /dev/null
+++ b/dist2/RunGrepTest.bat
@@ -0,0 +1,694 @@
+@echo off

+

+:: Run pcre2grep tests. The assumption is that the PCRE2 tests check the library

+:: itself. What we are checking here is the file handling and options that are

+:: supported by pcre2grep. This script must be run in the build directory.

+:: (jmh: I've only tested in the main directory, using my own builds.)

+

+setlocal enabledelayedexpansion

+

+:: Remove any non-default colouring that the caller may have set.

+

+set PCRE2GREP_COLOUR=

+set PCRE2GREP_COLOR=

+set PCREGREP_COLOUR=

+set PCREGREP_COLOR=

+set GREP_COLORS=

+set GREP_COLOR=

+

+:: Remember the current (build) directory and set the program to be tested.

+

+set builddir="%CD%"

+set pcre2grep=%builddir%\pcre2grep.exe

+set pcre2test=%builddir%\pcre2test.exe

+

+if NOT exist %pcre2grep% (

+  echo ** %pcre2grep% does not exist.

+  exit /b 1

+)

+

+if NOT exist %pcre2test% (

+  echo ** %pcre2test% does not exist.

+  exit /b 1

+)

+

+for /f "delims=" %%a in ('"%pcre2grep%" -V') do set pcre2grep_version=%%a

+echo Testing %pcre2grep_version%

+

+:: Set up a suitable "diff" command for comparison. Some systems have a diff

+:: that lacks a -u option. Try to deal with this; better do the test for the -b

+:: option as well. Use FC if there's no diff, taking care to ignore equality.

+

+set cf=

+set cfout=

+diff -b  nul nul 2>nul && set cf=diff -b

+diff -u  nul nul 2>nul && set cf=diff -u

+diff -ub nul nul 2>nul && set cf=diff -ub

+if NOT defined cf (

+  set cf=fc /n

+  set "cfout=>testcf || (type testcf & cmd /c exit /b 1)"

+)

+

+:: Set srcdir to the current or parent directory, whichever one contains the

+:: test data. Subsequently, we run most of the pcre2grep tests in the source

+:: directory so that the file names in the output are always the same.

+

+if NOT defined srcdir set srcdir=.

+if NOT exist %srcdir%\testdata\ (

+  if exist testdata\ (

+    set srcdir=.

+  ) else if exist ..\testdata\ (

+    set srcdir=..

+  ) else if exist ..\..\testdata\ (

+    set srcdir=..\..

+  ) else (

+    echo Cannot find the testdata directory

+    exit /b 1

+  )

+)

+

+:: Check for the availability of UTF-8 support

+

+%pcre2test% -C unicode >nul

+set utf8=%ERRORLEVEL%

+

+:: Check default newline convention. If it does not include LF, force LF.

+

+for /f %%a in ('"%pcre2test%" -C newline') do set nl=%%a

+if NOT "%nl%" == "LF" if NOT "%nl%" == "ANY" if NOT "%nl%" == "ANYCRLF" (

+  set pcre2grep=%pcre2grep% -N LF

+  echo Default newline setting forced to LF

+)

+

+:: Create a simple printf via cscript/JScript (an actual printf may translate

+:: LF to CRLF, which this one does not).

+

+echo WScript.StdOut.Write(WScript.Arguments(0).replace(/\\r/g, "\r").replace(/\\n/g, "\n")) >printf.js

+set printf=cscript //nologo printf.js

+

+:: ------ Normal tests ------

+

+echo Testing pcre2grep main features

+

+echo ---------------------------- Test 1 ------------------------------>testtrygrep

+(pushd %srcdir% & %pcre2grep% PATTERN ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 2 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% "^PATTERN" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 3 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -in PATTERN ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 4 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -ic PATTERN ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 5 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -in PATTERN ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 6 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -inh PATTERN ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 7 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -il PATTERN ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 8 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -l PATTERN ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 9 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -q PATTERN ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 10 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 11 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -vn pattern ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 12 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -ix pattern ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 13 ----------------------------->>testtrygrep

+echo seventeen >testtemp1grep

+(pushd %srcdir% & %pcre2grep% -f./testdata/greplist -f %builddir%\testtemp1grep ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 14 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -w pat ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 15 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% "abc^*" ./testdata/grepinput & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 16 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% abc ./testdata/grepinput ./testdata/nonexistfile & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 17 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -M "the\noutput" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 18 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -Mn "(the\noutput|dog\.\n--)" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 19 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -Mix "Pattern" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 20 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -Mixn "complete pair\nof lines" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 21 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -nA3 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 22 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -nB3 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 23 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -C3 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 24 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -A9 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 25 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -nB9 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 26 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -A9 -B9 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 27 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -A10 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 28 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -nB10 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 29 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -C12 -B10 "four" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 30 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -inB3 "pattern" ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 31 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -inA3 "pattern" ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 32 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -L "fox" ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 33 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% "fox" ./testdata/grepnonexist & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 34 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -s "fox" ./testdata/grepnonexist & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 35 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -L -r --include=grepinputx --include grepinput8 --exclude-dir="^\." "fox" ./testdata | sort & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 36 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -L -r --include=grepinput --exclude "grepinput$" --exclude=grepinput8 --exclude-dir="^\." "fox" ./testdata | sort & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 37 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep%  "^(a+)*\d" ./testdata/grepinput & popd) >>testtrygrep 2>teststderrgrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+echo ======== STDERR ========>>testtrygrep

+type teststderrgrep >>testtrygrep

+

+echo ---------------------------- Test 38 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% ">\x00<" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 39 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -A1 "before the binary zero" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 40 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -B1 "after the binary zero" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 41 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -B1 -o "\w+ the binary zero" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 42 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -B1 -onH "\w+ the binary zero" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 43 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -on "before|zero|after" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 44 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -on -e before -ezero -e after ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 45 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -on -f ./testdata/greplist -e binary ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 46 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -eabc -e "(unclosed" ./testdata/grepinput & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 47 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -Fx AB.VE^

+

+elephant ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 48 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -F AB.VE^

+

+elephant ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 49 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -F -e DATA -e AB.VE^

+

+elephant ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 50 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% "^(abc|def|ghi|jkl)" ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 51 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -Mv "brown\sfox" ./testdata/grepinputv & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 52 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% --colour=always jumps ./testdata/grepinputv & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 53 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% --file-offsets "before|zero|after" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 54 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% --line-offsets "before|zero|after" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 55 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -f./testdata/greplist --color=always ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 56 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -c lazy ./testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 57 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -c -l lazy ./testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 58 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --regex=PATTERN ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 59 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --regexp=PATTERN ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 60 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --regex PATTERN ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 61 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --regexp PATTERN ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 62 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --match-limit=1000 --no-jit -M "This is a file(.|\R)*file." ./testdata/grepinput & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 63 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --recursion-limit=1000 --no-jit -M "This is a file(.|\R)*file." ./testdata/grepinput & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 64 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o1 "(?<=PAT)TERN (ap(pear)s)" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 65 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o2 "(?<=PAT)TERN (ap(pear)s)" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 66 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o3 "(?<=PAT)TERN (ap(pear)s)" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 67 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o12 "(?<=PAT)TERN (ap(pear)s)" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 68 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% --only-matching=2 "(?<=PAT)TERN (ap(pear)s)" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 69 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -vn --colour=always pattern ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 70 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3 & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 71 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o "^01|^02|^03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 72 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --color=always "^01|^02|^03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 73 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o --colour=always "^01|^02|^03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 74 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o "^01|02|^03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 75 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --color=always "^01|02|^03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 76 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o --colour=always "^01|02|^03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 77 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o "^01|^02|03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 78 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --color=always "^01|^02|03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 79 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o --colour=always "^01|^02|03" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 80 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o "\b01|\b02" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 81 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --color=always "\b01|\b02" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 82 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o --colour=always "\b01|\b02" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 83 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --buffer-size=10 --max-buffer-size=100 "^a" ./testdata/grepinput3 & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 84 ----------------------------->>testtrygrep

+echo testdata/grepinput3 >testtemp1grep

+(pushd %srcdir% & %pcre2grep% --file-list ./testdata/grepfilelist --file-list %builddir%\testtemp1grep "fox|complete|t7" & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 85 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3 & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 86 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% "dog" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 87 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% "cat" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 88 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -v "cat" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 89 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -I "dog" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 90 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --binary-files=without-match "dog" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 91 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -a "dog" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 92 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --binary-files=text "dog" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 93 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --text "dog" ./testdata/grepbinary & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 94 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -L -r --include=grepinputx --include grepinput8 "fox" ./testdata/grepinput* | sort & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 95 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete" & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 96 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -L -r --include-dir=testdata --exclude "^^(?^!grepinput)" "fox" ./test* | sort & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 97 ----------------------------->>testtrygrep

+echo grepinput$>testtemp1grep

+echo grepinput8>>testtemp1grep

+(pushd %srcdir% & %pcre2grep% -L -r --include=grepinput --exclude-from %builddir%\testtemp1grep --exclude-dir="^\." "fox" ./testdata | sort & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 98 ----------------------------->>testtrygrep

+echo grepinput$>testtemp1grep

+echo grepinput8>>testtemp1grep

+(pushd %srcdir% & %pcre2grep% -L -r --exclude=grepinput3 --include=grepinput --exclude-from %builddir%\testtemp1grep --exclude-dir="^\." "fox" ./testdata | sort & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 99 ----------------------------->>testtrygrep

+echo grepinput$>testtemp1grep

+echo grepinput8>testtemp2grep

+(pushd %srcdir% & %pcre2grep% -L -r --include grepinput --exclude-from %builddir%\testtemp1grep --exclude-from=%builddir%\testtemp2grep --exclude-dir="^\." "fox" ./testdata | sort & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 100 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -Ho2 --only-matching=1 -o3 "(\w+) binary (\w+)(\.)?" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 101 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator="|" "(\w+) binary (\w+)(\.)?" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 102 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -n "^$" ./testdata/grepinput3 & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 103 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --only-matching "^$" ./testdata/grepinput3 & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 104 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -n --only-matching "^$" ./testdata/grepinput3 & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 105 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --colour=always "ipsum|" ./testdata/grepinput3 & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 106 ----------------------------->>testtrygrep

+(pushd %srcdir% & echo a| %pcre2grep% -M "|a" & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 107 ----------------------------->>testtrygrep

+echo a>testtemp1grep

+echo aaaaa>>testtemp1grep

+(pushd %srcdir% & %pcre2grep%  --line-offsets "(?<=\Ka)" %builddir%\testtemp1grep & popd) >>testtrygrep 2>&1

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 108 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -lq PATTERN ./testdata/grepinput ./testdata/grepinputx & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 109 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -cq lazy ./testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 110 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --om-separator / -Mo0 -o1 -o2 "match (\d+):\n (.)\n" testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 111 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --line-offsets -M "match (\d+):\n (.)\n" testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 112 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --file-offsets -M "match (\d+):\n (.)\n" testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 113 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% --total-count "the" testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 114 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -tc "the" testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 115 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -tlc "the" testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 116 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -th "the" testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 117 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -tch "the" testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 118 ----------------------------->>testtrygrep

+(pushd %srcdir% & %pcre2grep% -tL "the" testdata/grepinput* & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 119 ----------------------------->>testtrygrep

+%printf% "123\n456\n789\n---abc\ndef\nxyz\n---\n" >testNinputgrep

+%pcre2grep% -Mo "(\n|[^-])*---" testNinputgrep >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+echo ---------------------------- Test 120 ------------------------------>>testtrygrep

+(pushd %srcdir% & %pcre2grep% -HO "$0:$2$1$3" "(\w+) binary (\w+)(\.)?" ./testdata/grepinput & popd) >>testtrygrep

+echo RC=^%ERRORLEVEL%>>testtrygrep

+

+:: Now compare the results.

+

+%cf% %srcdir%\testdata\grepoutput testtrygrep %cfout%

+if ERRORLEVEL 1 exit /b 1

+

+

+:: These tests require UTF-8 support

+

+if %utf8% neq 0 (

+  echo Testing pcre2grep UTF-8 features

+

+  echo ---------------------------- Test U1 ------------------------------>testtrygrep

+  (pushd %srcdir% & %pcre2grep% -n -u --newline=any "^X" ./testdata/grepinput8 & popd) >>testtrygrep

+  echo RC=^%ERRORLEVEL%>>testtrygrep

+

+  echo ---------------------------- Test U2 ------------------------------>>testtrygrep

+  (pushd %srcdir% & %pcre2grep% -n -u -C 3 --newline=any "Match" ./testdata/grepinput8 & popd) >>testtrygrep

+  echo RC=^%ERRORLEVEL%>>testtrygrep

+

+  echo ---------------------------- Test U3 ------------------------------>>testtrygrep

+  (pushd %srcdir% & %pcre2grep% --line-offsets -u --newline=any "(?<=\K\x{17f})" ./testdata/grepinput8 & popd) >>testtrygrep

+  echo RC=^%ERRORLEVEL%>>testtrygrep

+

+  %cf% %srcdir%\testdata\grepoutput8 testtrygrep %cfout%

+  if ERRORLEVEL 1 exit /b 1

+

+) else (

+  echo Skipping pcre2grep UTF-8 tests: no UTF-8 support in PCRE2 library

+)

+

+

+:: We go to some contortions to try to ensure that the tests for the various

+:: newline settings will work in environments where the normal newline sequence

+:: is not \n. Do not use exported files, whose line endings might be changed.

+:: Instead, create an input file so that its contents are exactly what we want.

+:: These tests are run in the build directory.

+

+echo Testing pcre2grep newline settings

+%printf% "abc\rdef\r\nghi\njkl" >testNinputgrep

+

+echo ---------------------------- Test N1 ------------------------------>testtrygrep

+%pcre2grep% -n -N CR "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep

+

+echo ---------------------------- Test N2 ------------------------------>>testtrygrep

+%pcre2grep% -n --newline=crlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep

+

+echo ---------------------------- Test N3 ------------------------------>>testtrygrep

+for /f %%a in ('%printf% "def\rjkl"') do set pattern=%%a

+%pcre2grep% -n --newline=cr -F "!pattern!" testNinputgrep >>testtrygrep

+

+echo ---------------------------- Test N4 ------------------------------>>testtrygrep

+%pcre2grep% -n --newline=crlf -F -f %srcdir%/testdata/greppatN4 testNinputgrep >>testtrygrep

+

+echo ---------------------------- Test N5 ------------------------------>>testtrygrep

+%pcre2grep% -n --newline=any "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep

+

+echo ---------------------------- Test N6 ------------------------------>>testtrygrep

+%pcre2grep% -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep

+

+%cf% %srcdir%\testdata\grepoutputN testtrygrep %cfout%

+if ERRORLEVEL 1 exit /b 1

+

+:: If pcre2grep supports script callouts, run some tests on them.

+

+%pcre2grep% --help | %pcre2grep% -q "Callout scripts in patterns are supported"

+if %ERRORLEVEL% equ 0 (

+  echo Testing pcre2grep script callouts

+  %pcre2grep% "(T)(..(.))(?C'cmd|/c echo|Arg1: [$1] [$2] [$3]|Arg2: ^$|${1}^$| ($4) ($14) ($0)')()" %srcdir%/testdata/grepinputv >testtrygrep

+  %pcre2grep% "(T)(..(.))()()()()()()()(..)(?C'cmd|/c echo|Arg1: [$11] [${11}]')" %srcdir%/testdata/grepinputv >>testtrygrep

+  %pcre2grep% "(T)(?C'|$0:$1$n')" %srcdir%/testdata/grepinputv >>testtrygrep

+  %pcre2grep% "(T)(?C'|$1$n')(*F)" %srcdir%/testdata/grepinputv >>testtrygrep

+  %cf% %srcdir%\testdata\grepoutputC testtrygrep %cfout%

+  if ERRORLEVEL 1 exit /b 1

+) else (

+  echo Script callouts are not supported

+)

+

+:: Finally, some tests to exercise code that is not tested above, just to be

+:: sure that it runs OK. Doing this improves the coverage statistics. The output

+:: is not checked.

+

+echo Testing miscellaneous pcre2grep arguments (unchecked)

+%printf% "" >testtrygrep

+call :checkspecial "-xxxxx" 2 || exit /b 1

+call :checkspecial "--help" 0 || exit /b 1

+call :checkspecial "--line-buffered --colour=auto abc nul" 1 || exit /b 1

+

+:: Clean up local working files

+del testcf printf.js testNinputgrep teststderrgrep testtrygrep testtemp1grep testtemp2grep

+

+exit /b 0

+

+:: ------ Function to run and check a special pcre2grep arguments test -------

+

+:checkspecial

+  %pcre2grep% %~1 >>testtrygrep 2>&1

+  if %ERRORLEVEL% neq %2 (

+    echo ** pcre2grep %~1 failed - check testtrygrep

+    exit /b 1

+  )

+  exit /b 0

+

+:: End

diff --git a/dist2/RunTest b/dist2/RunTest
index d0eec77..bc912da 100755
--- a/dist2/RunTest
+++ b/dist2/RunTest
@@ -78,7 +78,9 @@
 title21="Test 21: \C tests without UTF (supported for DFA matching)"
 title22="Test 22: \C tests with UTF (not supported for DFA matching)"
 title23="Test 23: \C disabled test"
-maxtest=23
+title24="Test 24: Non-UTF pattern conversion tests"
+title25="Test 25: UTF pattern conversion tests"
+maxtest=25
 
 if [ $# -eq 1 -a "$1" = "list" ]; then
   echo $title0
@@ -105,6 +107,8 @@
   echo $title21
   echo $title22
   echo $title23
+  echo $title24
+  echo $title25
   exit 0
 fi
 
@@ -232,6 +236,8 @@
 do21=no
 do22=no
 do23=no
+do24=no
+do25=no
 
 while [ $# -gt 0 ] ; do
   case $1 in
@@ -259,6 +265,8 @@
    21) do21=yes;;
    22) do22=yes;;
    23) do23=yes;;
+   24) do24=yes;;
+   25) do25=yes;;
    -8) arg8=yes;;
   -16) arg16=yes;;
   -32) arg32=yes;;
@@ -308,27 +316,14 @@
   exit 1
 fi
 
-# If it is possible to set the system stack size, arrange to set a value for
-# test 2, which needs more than the even the Linux default when PCRE2 has been
-# compiled by gcc with -fsanitize=address. If "bigstack" is on the command
-# line, set even bigger numbers. When the compiler is clang, sanitize options
-# require an even bigger stack for test 2, and an increased stack for some of
-# the other tests. Test 2 now has code to automatically try again with a 64M
-# stack if it crashes when test2stack is "-S 16" when matching with the
-# interpreter.
+# If it is possible to set the system stack size and -bigstack was given,
+# set up a large stack.
 
 $sim ./pcre2test -S 1 /dev/null /dev/null
-if [ $? -eq 0 ] ; then
-  if [ "$bigstack" = "" ] ; then
-    test2stack="-S 16"
-    defaultstack=""
-  else
-    test2stack="-S 1024"
-    defaultstack="-S 64"
-  fi
+if [ $? -eq 0 -a "$bigstack" != "" ] ; then
+  setstack="-S 64"
 else
-  test2stack=""
-  defaultstack=""
+  setstack=""
 fi
 
 # All of 8-bit, 16-bit, and 32-bit character strings may be supported, but only
@@ -420,7 +415,8 @@
      $do8  = no -a $do9  = no -a $do10 = no -a $do11 = no -a \
      $do12 = no -a $do13 = no -a $do14 = no -a $do15 = no -a \
      $do16 = no -a $do17 = no -a $do18 = no -a $do19 = no -a \
-     $do20 = no -a $do21 = no -a $do22 = no -a $do23 = no \
+     $do20 = no -a $do21 = no -a $do22 = no -a $do23 = no -a \
+     $do24 = no -a $do25 = no \
    ]; then
   do0=yes
   do1=yes
@@ -446,6 +442,8 @@
   do21=yes
   do22=yes
   do23=yes
+  do24=yes
+  do25=yes
 fi
 
 # Handle any explicit skips at this stage, so that an argument list may consist
@@ -476,7 +474,7 @@
 
   if [ $do0 = yes ] ; then
     echo $title0
-    echo '/abc/jit,memory' >testSinput
+    echo '/abc/jit,memory,framesize' >testSinput
     echo '   abc' >>testSinput
     echo '' >testtry
     checkspecial '-C'
@@ -490,7 +488,7 @@
   if [ $do1 = yes ] ; then
     echo $title1
     for opt in "" $jitopt; do
-      $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput1 testtry
+      $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput1 testtry
       checkresult $? 1 "$opt"
     done
   fi
@@ -500,34 +498,10 @@
   if [ $do2 = yes ] ; then
     echo $title2 "(excluding UTF-$bits)"
     for opt in "" $jitopt; do
-      $sim $valgrind ${opt:+$vjs} ./pcre2test -q $test2stack $bmode $opt $testdata/testinput2 testtry
+      $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput2 testtry
       if [ $? = 0 ] ; then
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $bmode $opt -error -63,-62,-2,-1,0,100,188,189 >>testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $bmode $opt -error -65,-62,-2,-1,0,100,101,191,200 >>testtry
         checkresult $? 2 "$opt"
-      else
-        echo " "
-        echo "** Test 2, when run under the interpreter, requires a lot of stack."
-        echo "** If it has crashed with a segmentation fault, it may be that you"
-        echo "** do not have enough stack available by default. Please see the"
-        echo "** 'pcre2stack' man page for a discussion of PCRE2's stack usage."
-        if [ "$test2stack" != "-S 16" -o "$opt" != "" ]; then
-          echo " "
-          exit 1
-        fi
-        echo " "
-        echo "** Trying again with an increased stack size."
-        echo " "
-        echo $title2 "(excluding UTF-$bits) (64M stack)"
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q -S 64 $bmode $opt $testdata/testinput2 testtry
-        if [ $? = 0 ] ; then
-          $sim $valgrind ${opt:+$vjs} ./pcre2test -q $bmode $opt -error -63,-62,-2,-1,0,100,188,189 >>testtry
-          checkresult $? 2 "$opt"
-        else
-          echo " "
-          echo "** Failed with an increased stack size. Tests abandoned."
-          echo " "
-          exit 1
-        fi
       fi
     done
   fi
@@ -577,7 +551,7 @@
     if [ "$locale" != "" ] ; then
       echo $title3 "(using '$locale' locale)"
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $infile testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $infile testtry
         if [ $? = 0 ] ; then
           case "$opt" in
             -jit) with=" with JIT";;
@@ -614,7 +588,7 @@
       echo "  Skipped because UTF-$bits support is not available"
     else
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput4 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput4 testtry
         checkresult $? 4 "$opt"
       done
     fi
@@ -626,7 +600,7 @@
       echo "  Skipped because UTF-$bits support is not available"
     else
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput5 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput5 testtry
         checkresult $? 5 "$opt"
       done
     fi
@@ -636,7 +610,7 @@
 
   if [ $do6 = yes ] ; then
     echo $title6
-    $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput6 testtry
+    $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput6 testtry
     checkresult $? 6 ""
   fi
 
@@ -645,7 +619,7 @@
     if [ $utf -eq 0 ] ; then
       echo "  Skipped because UTF-$bits support is not available"
     else
-      $sim $valgrind ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput7 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $opt $testdata/testinput7 testtry
       checkresult $? 7 ""
     fi
   fi
@@ -663,7 +637,7 @@
     if [ $utf -eq 0 ] ; then
       echo "  Skipped because UTF-$bits support is not available"
     else
-      $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput8 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput8 testtry
       checkresult $? 8-$bits-$link_size ""
     fi
   fi
@@ -676,7 +650,7 @@
       echo "  Skipped when running 16/32-bit tests"
     else
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput9 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput9 testtry
         checkresult $? 9 "$opt"
       done
     fi
@@ -692,7 +666,7 @@
       echo "  Skipped because UTF-$bits support is not available"
     else
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput10 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput10 testtry
         checkresult $? 10 "$opt"
       done
     fi
@@ -706,7 +680,7 @@
       echo "  Skipped when running 8-bit tests"
     else
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput11 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput11 testtry
         checkresult $? 11-$bits "$opt"
       done
     fi
@@ -723,7 +697,7 @@
       echo "  Skipped because UTF-$bits support is not available"
     else
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput12 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput12 testtry
         checkresult $? 12-$bits "$opt"
       done
     fi
@@ -736,7 +710,7 @@
     if [ "$bits" = "8" ] ; then
       echo "  Skipped when running 8-bit tests"
     else
-      $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput13 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput13 testtry
       checkresult $? 13 ""
     fi
   fi
@@ -748,7 +722,7 @@
     if [ $utf -eq 0 ] ; then
       echo "  Skipped because UTF-$bits support is not available"
     else
-      $sim $valgrind ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput14 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $opt $testdata/testinput14 testtry
       checkresult $? 14-$bits ""
     fi
   fi
@@ -757,7 +731,7 @@
 
   if [ $do15 = yes ] ; then
     echo $title15
-    $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput15 testtry
+    $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput15 testtry
     checkresult $? 15 ""
   fi
 
@@ -768,7 +742,7 @@
     if [ $jit -ne 0 ] ; then
       echo "  Skipped because JIT is available"
     else
-      $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput16 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput16 testtry
       checkresult $? 16 ""
     fi
   fi
@@ -780,7 +754,7 @@
     if [ $jit -eq 0 -o "$nojit" = "yes" ] ; then
       echo "  Skipped because JIT is not available or nojit was specified"
     else
-      $sim $valgrind $vjs ./pcre2test -q $defaultstack $bmode $testdata/testinput17 testtry
+      $sim $valgrind $vjs ./pcre2test -q $setstack $bmode $testdata/testinput17 testtry
       checkresult $? 17 ""
     fi
   fi
@@ -792,7 +766,7 @@
     if [ "$bits" = "16" -o "$bits" = "32" ] ; then
       echo "  Skipped when running 16/32-bit tests"
     else
-      $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput18 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput18 testtry
       checkresult $? 18 ""
     fi
   fi
@@ -806,7 +780,7 @@
     elif [ $utf -eq 0 ] ; then
       echo "  Skipped because UTF-$bits support is not available"
     else
-      $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput19 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput19 testtry
       checkresult $? 19 ""
     fi
   fi
@@ -815,7 +789,7 @@
 
   if [ $do20 = yes ] ; then
     echo $title20
-    $sim $valgrind ./pcre2test -q $defaultstack $bmode $testdata/testinput20 testtry
+    $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput20 testtry
     checkresult $? 20 ""
   fi
 
@@ -827,7 +801,7 @@
       echo "  Skipped because \C is disabled"
     else
       for opt in "" $jitopt -dfa; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput21 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput21 testtry
         checkresult $? 21 "$opt"
       done
     fi
@@ -843,7 +817,7 @@
       echo "  Skipped because UTF-$bits support is not available"
     else
       for opt in "" $jitopt; do
-        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput22 testtry
+        $sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput22 testtry
         checkresult $? 22-$bits "$opt"
       done
     fi
@@ -856,11 +830,31 @@
     if [ $supportBSC -ne 0 ] ; then
       echo "  Skipped because \C is not disabled"
     else
-      $sim $valgrind ${opt:+$vjs} ./pcre2test -q $defaultstack $bmode $opt $testdata/testinput23 testtry
+      $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput23 testtry
       checkresult $? 23 ""
     fi
   fi
 
+  # Non-UTF pattern conversion tests
+
+  if [ "$do24" = yes ] ; then
+    echo $title24
+    $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput24 testtry
+    checkresult $? 24 ""
+  fi
+
+  # UTF pattern converson tests
+
+  if [ "$do25" = yes ] ; then
+    echo $title25
+    if [ $utf -eq 0 ] ; then
+      echo "  Skipped because UTF-$bits support is not available"
+    else
+      $sim $valgrind ./pcre2test -q $setstack $bmode $testdata/testinput25 testtry
+      checkresult $? 25 ""
+    fi
+  fi
+
 # End of loop for 8/16/32-bit tests
 done
 
diff --git a/dist2/RunTest.bat b/dist2/RunTest.bat
index 54d9f34..0cd8bcc 100644
--- a/dist2/RunTest.bat
+++ b/dist2/RunTest.bat
@@ -245,8 +245,6 @@
 

 if %1 == 8 (

   set outnum=8-%bits%-%link_size%

-) else if %1 == 22 (

-  set outnum=22-%bits%

 ) else (

   set outnum=%1

 )

@@ -264,6 +262,8 @@
   echo.            %pcre2test% %mode% %4 %5 %6 %7 %8 %9 %srcdir%\testdata\%testinput% ^>%2%bits%\%testoutput%

   set failed="yes"

   goto :eof

+) else if [%1]==[2] (

+  %pcre2test% %mode% %4 %5 %6 %7 %8 %9 -error -63,-62,-2,-1,0,100,188,189,190,191 >>%2%bits%\%testoutput%

 )

 

 set type=

@@ -284,15 +284,6 @@
 

 if errorlevel 1 (

   echo.          failed comparison: fc /n %srcdir%\testdata\%testoutput% %2%bits%\%testoutput%

-  if [%1]==[2] (

-    echo.

-    echo ** Test 2 requires a lot of stack. PCRE2 can be configured to

-    echo ** use heap for recursion. Otherwise, to pass Test 2

-    echo ** you generally need to allocate 8 mb stack to PCRE2.

-    echo ** See the 'pcre2stack' page for a discussion of PCRE2's

-    echo ** stack usage.

-    echo.

-)

   if [%1]==[3] (

     echo.

     echo ** Test 3 failure usually means french locale is not

diff --git a/dist2/aclocal.m4 b/dist2/aclocal.m4
index d7204d9..d88a48b 100644
--- a/dist2/aclocal.m4
+++ b/dist2/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,9 +20,9 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-dnl pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
-dnl serial 11 (pkg-config-0.29.1)
-dnl
+# pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
+# serial 12 (pkg-config-0.29.2)
+
 dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
 dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
 dnl
@@ -63,7 +63,7 @@
 dnl See the "Since" comment for each macro you use to see what version
 dnl of the macros you require.
 m4_defun([PKG_PREREQ],
-[m4_define([PKG_MACROS_VERSION], [0.29.1])
+[m4_define([PKG_MACROS_VERSION], [0.29.2])
 m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
     [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
 ])dnl PKG_PREREQ
@@ -164,7 +164,7 @@
 AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
 
 pkg_failed=no
-AC_MSG_CHECKING([for $1])
+AC_MSG_CHECKING([for $2])
 
 _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
 _PKG_CONFIG([$1][_LIBS], [libs], [$2])
@@ -174,11 +174,11 @@
 See the pkg-config man page for more details.])
 
 if test $pkg_failed = yes; then
-   	AC_MSG_RESULT([no])
+        AC_MSG_RESULT([no])
         _PKG_SHORT_ERRORS_SUPPORTED
         if test $_pkg_short_errors_supported = yes; then
 	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
-        else 
+        else
 	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
@@ -195,7 +195,7 @@
 _PKG_TEXT])[]dnl
         ])
 elif test $pkg_failed = untried; then
-     	AC_MSG_RESULT([no])
+        AC_MSG_RESULT([no])
 	m4_default([$4], [AC_MSG_FAILURE(
 [The pkg-config script could not be found or is too old.  Make sure it
 is in your PATH or set the PKG_CONFIG environment variable to the full
@@ -296,7 +296,7 @@
 AS_VAR_IF([$1], [""], [$5], [$4])dnl
 ])dnl PKG_CHECK_VAR
 
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -311,7 +311,7 @@
 [am__api_version='1.15'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.15.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -327,12 +327,12 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.15.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -394,7 +394,7 @@
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -446,7 +446,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -477,7 +477,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -668,7 +668,7 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -744,7 +744,7 @@
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -941,7 +941,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -962,7 +962,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -983,7 +983,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1033,7 +1033,7 @@
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1072,7 +1072,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1101,7 +1101,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1148,7 +1148,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1167,7 +1167,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1248,7 +1248,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1308,7 +1308,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1336,7 +1336,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1355,7 +1355,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2017 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/dist2/ar-lib b/dist2/ar-lib
index 463b9ec..05094d3 100755
--- a/dist2/ar-lib
+++ b/dist2/ar-lib
@@ -4,7 +4,7 @@
 me=ar-lib
 scriptversion=2012-03-01.08; # UTC
 
-# Copyright (C) 2010-2014 Free Software Foundation, Inc.
+# Copyright (C) 2010-2017 Free Software Foundation, Inc.
 # Written by Peter Rosin <peda@lysator.liu.se>.
 #
 # This program is free software; you can redistribute it and/or modify
diff --git a/dist2/compile b/dist2/compile
index a85b723..2ab71e4 100755
--- a/dist2/compile
+++ b/dist2/compile
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand '-c -o'.
 
-scriptversion=2012-10-14.11; # UTC
+scriptversion=2016-01-11.22; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -255,7 +255,8 @@
     echo "compile $scriptversion"
     exit $?
     ;;
-  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
+  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
     func_cl_wrapper "$@"      # Doesn't return...
     ;;
 esac
@@ -342,6 +343,6 @@
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/dist2/config-cmake.h.in b/dist2/config-cmake.h.in
index 0cfd8b1..9b4f15d 100644
--- a/dist2/config-cmake.h.in
+++ b/dist2/config-cmake.h.in
@@ -25,6 +25,7 @@
 #cmakedefine SUPPORT_LIBZ 1
 
 #cmakedefine SUPPORT_JIT 1
+#cmakedefine SLJIT_PROT_EXECUTABLE_ALLOCATOR 1
 #cmakedefine SUPPORT_PCRE2GREP_JIT 1
 #cmakedefine SUPPORT_UNICODE 1
 #cmakedefine SUPPORT_VALGRIND 1
@@ -36,11 +37,13 @@
 #cmakedefine NEVER_BACKSLASH_C 1
 
 #define LINK_SIZE		@PCRE2_LINK_SIZE@
+#define HEAP_LIMIT              @PCRE2_HEAP_LIMIT@
 #define MATCH_LIMIT		@PCRE2_MATCH_LIMIT@
-#define MATCH_LIMIT_RECURSION	@PCRE2_MATCH_LIMIT_RECURSION@
+#define MATCH_LIMIT_DEPTH	@PCRE2_MATCH_LIMIT_DEPTH@
 #define NEWLINE_DEFAULT         @NEWLINE_DEFAULT@
 #define PARENS_NEST_LIMIT       @PCRE2_PARENS_NEST_LIMIT@
 #define PCRE2GREP_BUFSIZE       @PCRE2GREP_BUFSIZE@
+#define PCRE2GREP_MAX_BUFSIZE   @PCRE2GREP_MAX_BUFSIZE@
 
 #define MAX_NAME_SIZE	32
 #define MAX_NAME_COUNT	10000
diff --git a/dist2/config.guess b/dist2/config.guess
index 6c32c86..2193702 100755
--- a/dist2/config.guess
+++ b/dist2/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2014 Free Software Foundation, Inc.
+#   Copyright 1992-2017 Free Software Foundation, Inc.
 
-timestamp='2014-11-04'
+timestamp='2017-05-27'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 #
 # Please send patches to <config-patches@gnu.org>.
 
@@ -50,7 +50,7 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2017 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -168,19 +168,29 @@
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
-	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	    /sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || \
+	    echo unknown)`
 	case "${UNAME_MACHINE_ARCH}" in
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
+	    earmv*)
+		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+		machine=${arch}${endian}-unknown
+		;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
-	# to ELF recently, or will in the future.
+	# to ELF recently (or will in the future) and ABI.
 	case "${UNAME_MACHINE_ARCH}" in
+	    earm*)
+		os=netbsdelf
+		;;
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
@@ -197,6 +207,13 @@
 		os=netbsd
 		;;
 	esac
+	# Determine ABI tags.
+	case "${UNAME_MACHINE_ARCH}" in
+	    earm*)
+		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+		;;
+	esac
 	# The OS release
 	# Debian GNU/NetBSD machines have a different userland, and
 	# thus, need a distinct triplet. However, they do not need
@@ -207,13 +224,13 @@
 		release='-gnu'
 		;;
 	    *)
-		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}"
+	echo "${machine}-${os}${release}${abi}"
 	exit ;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -223,6 +240,10 @@
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
 	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
 	exit ;;
+    *:LibertyBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+	exit ;;
     *:ekkoBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
 	exit ;;
@@ -235,6 +256,9 @@
     *:MirBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
 	exit ;;
+    *:Sortix:*:*)
+	echo ${UNAME_MACHINE}-unknown-sortix
+	exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
@@ -251,42 +275,42 @@
 	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
 	case "$ALPHA_CPU_TYPE" in
 	    "EV4 (21064)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "EV4.5 (21064)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "LCA4 (21066/21068)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "EV5 (21164)")
-		UNAME_MACHINE="alphaev5" ;;
+		UNAME_MACHINE=alphaev5 ;;
 	    "EV5.6 (21164A)")
-		UNAME_MACHINE="alphaev56" ;;
+		UNAME_MACHINE=alphaev56 ;;
 	    "EV5.6 (21164PC)")
-		UNAME_MACHINE="alphapca56" ;;
+		UNAME_MACHINE=alphapca56 ;;
 	    "EV5.7 (21164PC)")
-		UNAME_MACHINE="alphapca57" ;;
+		UNAME_MACHINE=alphapca57 ;;
 	    "EV6 (21264)")
-		UNAME_MACHINE="alphaev6" ;;
+		UNAME_MACHINE=alphaev6 ;;
 	    "EV6.7 (21264A)")
-		UNAME_MACHINE="alphaev67" ;;
+		UNAME_MACHINE=alphaev67 ;;
 	    "EV6.8CB (21264C)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.8AL (21264B)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.8CX (21264D)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.9A (21264/EV69A)")
-		UNAME_MACHINE="alphaev69" ;;
+		UNAME_MACHINE=alphaev69 ;;
 	    "EV7 (21364)")
-		UNAME_MACHINE="alphaev7" ;;
+		UNAME_MACHINE=alphaev7 ;;
 	    "EV7.9 (21364A)")
-		UNAME_MACHINE="alphaev79" ;;
+		UNAME_MACHINE=alphaev79 ;;
 	esac
 	# A Pn.n version is a patched version.
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
 	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
 	exitcode=$?
 	trap '' 0
@@ -359,16 +383,16 @@
 	exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
 	eval $set_cc_for_build
-	SUN_ARCH="i386"
+	SUN_ARCH=i386
 	# If there is a compiler, see if it is configured for 64-bit objects.
 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
 		grep IS_64BIT_ARCH >/dev/null
 	    then
-		SUN_ARCH="x86_64"
+		SUN_ARCH=x86_64
 	    fi
 	fi
 	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
@@ -393,7 +417,7 @@
 	exit ;;
     sun*:*:4.2BSD:*)
 	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
 	case "`/bin/arch`" in
 	    sun3)
 		echo m68k-sun-sunos${UNAME_RELEASE}
@@ -618,13 +642,13 @@
 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
 		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
 		    case "${sc_cpu_version}" in
-		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
 		      532)                      # CPU_PA_RISC2_0
 			case "${sc_kernel_bits}" in
-			  32) HP_ARCH="hppa2.0n" ;;
-			  64) HP_ARCH="hppa2.0w" ;;
-			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			  32) HP_ARCH=hppa2.0n ;;
+			  64) HP_ARCH=hppa2.0w ;;
+			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
 			esac ;;
 		    esac
 		fi
@@ -663,11 +687,11 @@
 		    exit (0);
 		}
 EOF
-		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
-	if [ ${HP_ARCH} = "hppa2.0w" ]
+	if [ ${HP_ARCH} = hppa2.0w ]
 	then
 	    eval $set_cc_for_build
 
@@ -680,12 +704,12 @@
 	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
 	    # => hppa64-hp-hpux11.23
 
-	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
 		grep -q __LP64__
 	    then
-		HP_ARCH="hppa2.0w"
+		HP_ARCH=hppa2.0w
 	    else
-		HP_ARCH="hppa64"
+		HP_ARCH=hppa64
 	    fi
 	fi
 	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@@ -790,14 +814,14 @@
 	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
 	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
 	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     5000:UNIX_System_V:4.*:*)
-	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
 	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -813,10 +837,11 @@
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
 	case ${UNAME_PROCESSOR} in
 	    amd64)
-		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-	    *)
-		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+		UNAME_PROCESSOR=x86_64 ;;
+	    i386)
+		UNAME_PROCESSOR=i586 ;;
 	esac
+	echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
 	exit ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
@@ -879,7 +904,7 @@
 	exit ;;
     *:GNU/*:*:*)
 	# other systems with GNU libc and userland
-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
 	exit ;;
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
@@ -902,7 +927,7 @@
 	  EV68*) UNAME_MACHINE=alphaev68 ;;
 	esac
 	objdump --private-headers /bin/sh | grep -q ld.so.1
-	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     arc:Linux:*:* | arceb:Linux:*:*)
@@ -933,6 +958,9 @@
     crisv32:Linux:*:*)
 	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
 	exit ;;
+    e2k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     frv:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
@@ -945,6 +973,9 @@
     ia64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
+    k1om:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     m32r*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
@@ -970,6 +1001,9 @@
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
+    mips64el:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     openrisc*:Linux:*:*)
 	echo or1k-unknown-linux-${LIBC}
 	exit ;;
@@ -1002,6 +1036,9 @@
     ppcle:Linux:*:*)
 	echo powerpcle-unknown-linux-${LIBC}
 	exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
 	exit ;;
@@ -1021,7 +1058,7 @@
 	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
 	exit ;;
     x86_64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
 	exit ;;
     xtensa*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
@@ -1100,7 +1137,7 @@
 	# uname -m prints for DJGPP always 'pc', but it prints nothing about
 	# the processor, so we play safe by assuming i586.
 	# Note: whatever this is, it MUST be the same as what config.sub
-	# prints for the "djgpp" host, or else GDB configury will decide that
+	# prints for the "djgpp" host, or else GDB configure will decide that
 	# this is a cross-build.
 	echo i586-pc-msdosdjgpp
 	exit ;;
@@ -1249,6 +1286,9 @@
     SX-8R:SUPER-UX:*:*)
 	echo sx8r-nec-superux${UNAME_RELEASE}
 	exit ;;
+    SX-ACE:SUPER-UX:*:*)
+	echo sxace-nec-superux${UNAME_RELEASE}
+	exit ;;
     Power*:Rhapsody:*:*)
 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
 	exit ;;
@@ -1262,16 +1302,23 @@
 	    UNAME_PROCESSOR=powerpc
 	fi
 	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
 		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		    grep IS_64BIT_ARCH >/dev/null
+		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		       grep IS_64BIT_ARCH >/dev/null
 		then
 		    case $UNAME_PROCESSOR in
 			i386) UNAME_PROCESSOR=x86_64 ;;
 			powerpc) UNAME_PROCESSOR=powerpc64 ;;
 		    esac
 		fi
+		# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+		if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		       grep IS_PPC >/dev/null
+		then
+		    UNAME_PROCESSOR=powerpc
+		fi
 	    fi
 	elif test "$UNAME_PROCESSOR" = i386 ; then
 	    # Avoid executing cc on OS X 10.9, as it ships with a stub
@@ -1286,7 +1333,7 @@
 	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
 	UNAME_PROCESSOR=`uname -p`
-	if test "$UNAME_PROCESSOR" = "x86"; then
+	if test "$UNAME_PROCESSOR" = x86; then
 		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
 	fi
@@ -1295,15 +1342,18 @@
     *:QNX:*:4*)
 	echo i386-pc-qnx
 	exit ;;
-    NEO-?:NONSTOP_KERNEL:*:*)
+    NEO-*:NONSTOP_KERNEL:*:*)
 	echo neo-tandem-nsk${UNAME_RELEASE}
 	exit ;;
     NSE-*:NONSTOP_KERNEL:*:*)
 	echo nse-tandem-nsk${UNAME_RELEASE}
 	exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
+    NSR-*:NONSTOP_KERNEL:*:*)
 	echo nsr-tandem-nsk${UNAME_RELEASE}
 	exit ;;
+    NSX-*:NONSTOP_KERNEL:*:*)
+	echo nsx-tandem-nsk${UNAME_RELEASE}
+	exit ;;
     *:NonStop-UX:*:*)
 	echo mips-compaq-nonstopux
 	exit ;;
@@ -1317,7 +1367,7 @@
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
 	# operating systems.
-	if test "$cputype" = "386"; then
+	if test "$cputype" = 386; then
 	    UNAME_MACHINE=i386
 	else
 	    UNAME_MACHINE="$cputype"
@@ -1359,7 +1409,7 @@
 	echo i386-pc-xenix
 	exit ;;
     i*86:skyos:*:*)
-	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
 	exit ;;
     i*86:rdos:*:*)
 	echo ${UNAME_MACHINE}-pc-rdos
@@ -1370,23 +1420,25 @@
     x86_64:VMkernel:*:*)
 	echo ${UNAME_MACHINE}-unknown-esx
 	exit ;;
+    amd64:Isilon\ OneFS:*:*)
+	echo x86_64-unknown-onefs
+	exit ;;
 esac
 
 cat >&2 <<EOF
 $0: unable to guess system type
 
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
 
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
 
 config.guess timestamp = $timestamp
 
diff --git a/dist2/config.sub b/dist2/config.sub
index 7ffe373..40ea5df 100755
--- a/dist2/config.sub
+++ b/dist2/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2014 Free Software Foundation, Inc.
+#   Copyright 1992-2017 Free Software Foundation, Inc.
 
-timestamp='2014-12-03'
+timestamp='2017-04-02'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
 # Otherwise, we print the canonical config type on stdout and succeed.
 
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
@@ -53,8 +53,7 @@
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
 
 Canonicalize a configuration name.
 
@@ -68,7 +67,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2017 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,8 +116,8 @@
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  kopensolaris*-gnu* | cloudabi*-eabi* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -255,15 +254,16 @@
 	| arc | arceb \
 	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
 	| avr | avr32 \
+	| ba \
 	| be32 | be64 \
 	| bfin \
 	| c4x | c8051 | clipper \
 	| d10v | d30v | dlx | dsp16xx \
-	| epiphany \
-	| fido | fr30 | frv \
+	| e2k | epiphany \
+	| fido | fr30 | frv | ft32 \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| hexagon \
-	| i370 | i860 | i960 | ia64 \
+	| i370 | i860 | i960 | ia16 | ia64 \
 	| ip2k | iq2000 \
 	| k1om \
 	| le32 | le64 \
@@ -301,11 +301,12 @@
 	| open8 | or1k | or1knd | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pru \
 	| pyramid \
 	| riscv32 | riscv64 \
 	| rl78 | rx \
 	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
 	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,6 +315,7 @@
 	| ubicom32 \
 	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
 	| visium \
+	| wasm32 \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
 	| z8k | z80)
@@ -376,17 +378,18 @@
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 	| avr-* | avr32-* \
+	| ba-* \
 	| be32-* | be64-* \
 	| bfin-* | bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 	| c8051-* | clipper-* | craynv-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
-	| elxsi-* \
+	| e2k-* | elxsi-* \
 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia64-* \
+	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
 	| ip2k-* | iq2000-* \
 	| k1om-* \
 	| le32-* | le64-* \
@@ -427,13 +430,15 @@
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pru-* \
 	| pyramid-* \
+	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
 	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
 	| tahoe-* \
 	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 	| tile*-* \
@@ -442,6 +447,7 @@
 	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 	| vax-* \
 	| visium-* \
+	| wasm32-* \
 	| we32k-* \
 	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
@@ -518,6 +524,9 @@
 		basic_machine=i386-pc
 		os=-aros
 		;;
+	asmjs)
+		basic_machine=asmjs-unknown
+		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -638,6 +647,14 @@
 		basic_machine=m68k-bull
 		os=-sysv3
 		;;
+	e500v[12])
+		basic_machine=powerpc-unknown
+		os=$os"spe"
+		;;
+	e500v[12]-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=$os"spe"
+		;;
 	ebmon29k)
 		basic_machine=a29k-amd
 		os=-ebmon
@@ -933,6 +950,9 @@
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
+	nsx-tandem)
+		basic_machine=nsx-tandem
+		;;
 	op50n-* | op60c-*)
 		basic_machine=hppa1.1-oki
 		os=-proelf
@@ -1017,7 +1037,7 @@
 	ppc-* | ppcbe-*)
 		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppcle | powerpclittle | ppc-le | powerpc-little)
+	ppcle | powerpclittle)
 		basic_machine=powerpcle-unknown
 		;;
 	ppcle-* | powerpclittle-*)
@@ -1027,7 +1047,7 @@
 		;;
 	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+	ppc64le | powerpc64little)
 		basic_machine=powerpc64le-unknown
 		;;
 	ppc64le-* | powerpc64little-*)
@@ -1228,6 +1248,9 @@
 		basic_machine=a29k-wrs
 		os=-vxworks
 		;;
+	wasm32)
+		basic_machine=wasm32-unknown
+		;;
 	w65*)
 		basic_machine=w65-wdc
 		os=-none
@@ -1373,18 +1396,18 @@
 	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
 	      | -sym* | -kopensolaris* | -plan9* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* \
+	      | -aos* | -aros* | -cloudabi* | -sortix* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
@@ -1393,7 +1416,8 @@
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1525,6 +1549,8 @@
 		;;
 	-nacl*)
 		;;
+	-ios)
+		;;
 	-none)
 		;;
 	*)
@@ -1620,6 +1646,9 @@
 	sparc-* | *-sun)
 		os=-sunos4.1.1
 		;;
+	pru-*)
+		os=-elf
+		;;
 	*-be)
 		os=-beos
 		;;
diff --git a/dist2/configure b/dist2/configure
index 72b58bd..7064b11 100755
--- a/dist2/configure
+++ b/dist2/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for PCRE2 10.22.
+# Generated by GNU Autoconf 2.69 for PCRE2 10.31.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@
 # Identity of this package.
 PACKAGE_NAME='PCRE2'
 PACKAGE_TARNAME='pcre2'
-PACKAGE_VERSION='10.22'
-PACKAGE_STRING='PCRE2 10.22'
+PACKAGE_VERSION='10.31'
+PACKAGE_STRING='PCRE2 10.31'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -659,6 +659,8 @@
 ax_pthread_config
 PCRE2_STATIC_CFLAG
 LIBREADLINE
+WITH_FUZZ_SUPPORT_FALSE
+WITH_FUZZ_SUPPORT_TRUE
 WITH_VALGRIND_FALSE
 WITH_VALGRIND_TRUE
 WITH_UNICODE_FALSE
@@ -712,6 +714,8 @@
 build_vendor
 build_cpu
 build
+ac_ct_AR
+AR
 EGREP
 GREP
 CPP
@@ -732,8 +736,6 @@
 LDFLAGS
 CFLAGS
 CC
-ac_ct_AR
-AR
 AM_BACKSLASH
 AM_DEFAULT_VERBOSITY
 AM_DEFAULT_V
@@ -820,6 +822,7 @@
 enable_pcre2_32
 enable_debug
 enable_jit
+enable_jit_sealloc
 enable_pcre2grep_jit
 enable_pcre2grep_callout
 enable_rebuild_chartables
@@ -829,22 +832,27 @@
 enable_newline_is_crlf
 enable_newline_is_anycrlf
 enable_newline_is_any
+enable_newline_is_nul
 enable_bsr_anycrlf
 enable_never_backslash_C
 enable_ebcdic
 enable_ebcdic_nl25
-enable_stack_for_recursion
 enable_pcre2grep_libz
 enable_pcre2grep_libbz2
 with_pcre2grep_bufsize
+with_pcre2grep_max_bufsize
 enable_pcre2test_libedit
 enable_pcre2test_libreadline
 with_link_size
 with_parens_nest_limit
+with_heap_limit
 with_match_limit
+with_match_limit_depth
 with_match_limit_recursion
 enable_valgrind
 enable_coverage
+enable_fuzz_support
+enable_stack_for_recursion
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1403,7 +1411,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures PCRE2 10.22 to adapt to many kinds of systems.
+\`configure' configures PCRE2 10.31 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1473,7 +1481,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of PCRE2 10.22:";;
+     short | recursive ) echo "Configuration of PCRE2 10.31:";;
    esac
   cat <<\_ACEOF
 
@@ -1498,6 +1506,7 @@
   --enable-pcre2-32       enable 32 bit character support
   --enable-debug          enable debugging code
   --enable-jit            enable Just-In-Time compiling support
+  --enable-jit-sealloc    enable SELinux compatible execmem allocator in JIT
   --disable-pcre2grep-jit disable JIT support in pcre2grep
   --disable-pcre2grep-callout
                           disable callout script support in pcre2grep
@@ -1511,6 +1520,7 @@
   --enable-newline-is-anycrlf
                           use CR, LF, or CRLF as newline sequence
   --enable-newline-is-any use any valid Unicode newline sequence
+  --enable-newline-is-nul use NUL (binary zero) as newline character
   --enable-bsr-anycrlf    \R matches only CR, LF, CRLF by default
   --enable-never-backslash-C
                           use of \C causes an error
@@ -1519,8 +1529,6 @@
                           environments; it implies --enable-rebuild-chartables
   --enable-ebcdic-nl25    set EBCDIC code for NL to 0x25 instead of 0x15; it
                           implies --enable-ebcdic
-  --disable-stack-for-recursion
-                          don't use stack recursion when matching
   --enable-pcre2grep-libz link pcre2grep with libz to handle .gz files
   --enable-pcre2grep-libbz2
                           link pcre2grep with libbz2 to handle .bz2 files
@@ -1528,8 +1536,9 @@
                           link pcre2test with libedit
   --enable-pcre2test-libreadline
                           link pcre2test with libreadline
-  --enable-valgrind       valgrind support
+  --enable-valgrind       enable valgrind support
   --enable-coverage       enable code coverage reports using gcov
+  --enable-fuzz-support   enable fuzzer support
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1543,15 +1552,22 @@
   --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
                           compiler's sysroot if not specified).
   --with-pcre2grep-bufsize=N
-                          pcre2grep buffer size (default=20480, minimum=8192)
+                          pcre2grep initial buffer size (default=20480,
+                          minimum=8192)
+  --with-pcre2grep-max-bufsize=N
+                          pcre2grep maximum buffer size (default=1048576,
+                          minimum=8192)
   --with-link-size=N      internal link size (2, 3, or 4 allowed; default=2)
   --with-parens-nest-limit=N
                           nested parentheses limit (default=250)
+  --with-heap-limit=N     default limit on heap memory (kilobytes,
+                          default=20000000)
   --with-match-limit=N    default limit on internal looping (default=10000000)
-  --with-match-limit-recursion=N
-                          default limit on internal recursion
+  --with-match-limit-depth=N
+                          default limit on match tree depth
                           (default=MATCH_LIMIT)
 
+
 Some influential environment variables:
   CC          C compiler command
   CFLAGS      C compiler flags
@@ -1641,7 +1657,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-PCRE2 configure 10.22
+PCRE2 configure 10.31
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1730,6 +1746,93 @@
 
 } # ac_fn_c_try_cpp
 
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
 # ac_fn_c_try_run LINENO
 # ----------------------
 # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
@@ -1992,93 +2095,6 @@
 
 } # ac_fn_c_check_func
 
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
 # ac_fn_c_check_type LINENO TYPE VAR INCLUDES
 # -------------------------------------------
 # Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -2136,7 +2152,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by PCRE2 $as_me 10.22, which was
+It was created by PCRE2 $as_me 10.31, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3000,7 +3016,7 @@
 
 # Define the identity of the package.
  PACKAGE='pcre2'
- VERSION='10.22'
+ VERSION='10.31'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3135,69 +3151,18 @@
 ac_config_headers="$ac_config_headers src/config.h"
 
 
-# This is a new thing required to stop a warning from automake 1.12
-DEPDIR="${am__leading_dot}deps"
-
-ac_config_commands="$ac_config_commands depfiles"
+# This was added at the suggestion of libtoolize (03-Jan-10)
 
 
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
-	@echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
+# The default CFLAGS in Autoconf are "-g -O2" for gcc and just "-g" for any
+# other compiler. There doesn't seem to be a standard way of getting rid of the
+# -g (which I don't think is needed for a production library). This fudge seems
+# to achieve the necessary. First, we remember the externally set values of
+# CFLAGS. Then call the AC_PROG_CC macro to find the compiler - if CFLAGS is
+# not set, it will be set to Autoconf's defaults. Afterwards, if the original
+# values were not set, remove the -g from the Autoconf defaults.
 
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
-
-# Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then :
-  enableval=$enable_dependency_tracking;
-fi
-
-if test "x$enable_dependency_tracking" != xno; then
-  am_depcomp="$ac_aux_dir/depcomp"
-  AMDEPBACKSLASH='\'
-  am__nodep='_no'
-fi
- if test "x$enable_dependency_tracking" != xno; then
-  AMDEP_TRUE=
-  AMDEP_FALSE='#'
-else
-  AMDEP_TRUE='#'
-  AMDEP_FALSE=
-fi
-
+remember_set_CFLAGS="$CFLAGS"
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -4046,918 +4011,69 @@
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+DEPDIR="${am__leading_dot}deps"
 
-depcc="$CC"   am_compiler_list=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CC_dependencies_compiler_type+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
-  # We make a subdir and do the tests there.  Otherwise we can end up
-  # making bogus files that we don't know about and never remove.  For
-  # instance it was reported that on HP-UX the gcc test will end up
-  # making a dummy file named 'D' -- because '-MD' means "put the output
-  # in D".
-  rm -rf conftest.dir
-  mkdir conftest.dir
-  # Copy depcomp to subdir because otherwise we won't find it if we're
-  # using a relative directory.
-  cp "$am_depcomp" conftest.dir
-  cd conftest.dir
-  # We will build objects and dependencies in a subdirectory because
-  # it helps to detect inapplicable dependency modes.  For instance
-  # both Tru64's cc and ICC support -MD to output dependencies as a
-  # side effect of compilation, but ICC will put the dependencies in
-  # the current directory while Tru64 will put them in the object
-  # directory.
-  mkdir sub
-
-  am_cv_CC_dependencies_compiler_type=none
-  if test "$am_compiler_list" = ""; then
-     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
-  fi
-  am__universal=false
-  case " $depcc " in #(
-     *\ -arch\ *\ -arch\ *) am__universal=true ;;
-     esac
-
-  for depmode in $am_compiler_list; do
-    # Setup a source with many dependencies, because some compilers
-    # like to wrap large dependency lists on column 80 (with \), and
-    # we should not choose a depcomp mode which is confused by this.
-    #
-    # We need to recreate these files for each test, as the compiler may
-    # overwrite some of them when testing with obscure command lines.
-    # This happens at least with the AIX C compiler.
-    : > sub/conftest.c
-    for i in 1 2 3 4 5 6; do
-      echo '#include "conftst'$i'.h"' >> sub/conftest.c
-      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
-      # Solaris 10 /bin/sh.
-      echo '/* dummy */' > sub/conftst$i.h
-    done
-    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
-    # We check with '-c' and '-o' for the sake of the "dashmstdout"
-    # mode.  It turns out that the SunPro C++ compiler does not properly
-    # handle '-M -o', and we need to detect this.  Also, some Intel
-    # versions had trouble with output in subdirs.
-    am__obj=sub/conftest.${OBJEXT-o}
-    am__minus_obj="-o $am__obj"
-    case $depmode in
-    gcc)
-      # This depmode causes a compiler race in universal mode.
-      test "$am__universal" = false || continue
-      ;;
-    nosideeffect)
-      # After this tag, mechanisms are not by side-effect, so they'll
-      # only be used when explicitly requested.
-      if test "x$enable_dependency_tracking" = xyes; then
-	continue
-      else
-	break
-      fi
-      ;;
-    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
-      # This compiler won't grok '-c -o', but also, the minuso test has
-      # not run yet.  These depmodes are late enough in the game, and
-      # so weak that their functioning should not be impacted.
-      am__obj=conftest.${OBJEXT-o}
-      am__minus_obj=
-      ;;
-    none) break ;;
-    esac
-    if depmode=$depmode \
-       source=sub/conftest.c object=$am__obj \
-       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
-       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
-         >/dev/null 2>conftest.err &&
-       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
-       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
-       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
-       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
-      # icc doesn't choke on unknown options, it will just issue warnings
-      # or remarks (even with -Werror).  So we grep stderr for any message
-      # that says an option was ignored or not supported.
-      # When given -MP, icc 7.0 and 7.1 complain thusly:
-      #   icc: Command line warning: ignoring option '-M'; no argument required
-      # The diagnosis changed in icc 8.0:
-      #   icc: Command line remark: option '-MP' not supported
-      if (grep 'ignoring option' conftest.err ||
-          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
-        am_cv_CC_dependencies_compiler_type=$depmode
-        break
-      fi
-    fi
-  done
-
-  cd ..
-  rm -rf conftest.dir
-else
-  am_cv_CC_dependencies_compiler_type=none
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
-
- if
-  test "x$enable_dependency_tracking" != xno \
-  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
-  am__fastdepCC_TRUE=
-  am__fastdepCC_FALSE='#'
-else
-  am__fastdepCC_TRUE='#'
-  am__fastdepCC_FALSE=
-fi
+ac_config_commands="$ac_config_commands depfiles"
 
 
-
-if test -n "$ac_tool_prefix"; then
-  for ac_prog in ar lib "link -lib"
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AR+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$AR"; then
-  ac_cv_prog_AR="$AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
-$as_echo "$AR" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-    test -n "$AR" && break
-  done
-fi
-if test -z "$AR"; then
-  ac_ct_AR=$AR
-  for ac_prog in ar lib "link -lib"
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_AR+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_AR"; then
-  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_AR="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
-$as_echo "$ac_ct_AR" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ac_ct_AR" && break
-done
-
-  if test "x$ac_ct_AR" = x; then
-    AR="false"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    AR=$ac_ct_AR
-  fi
-fi
-
-: ${AR=ar}
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
-$as_echo_n "checking the archiver ($AR) interface... " >&6; }
-if ${am_cv_ar_interface+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-   am_cv_ar_interface=ar
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-int some_variable = 0;
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
-      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
-  (eval $am_ar_try) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-      if test "$ac_status" -eq 0; then
-        am_cv_ar_interface=ar
-      else
-        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
-        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
-  (eval $am_ar_try) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-        if test "$ac_status" -eq 0; then
-          am_cv_ar_interface=lib
-        else
-          am_cv_ar_interface=unknown
-        fi
-      fi
-      rm -f conftest.lib libconftest.a
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
-$as_echo "$am_cv_ar_interface" >&6; }
-
-case $am_cv_ar_interface in
-ar)
-  ;;
-lib)
-  # Microsoft lib, so override with the ar-lib wrapper script.
-  # FIXME: It is wrong to rewrite AR.
-  # But if we don't then we get into trouble of one sort or another.
-  # A longer-term fix would be to have automake use am__AR in this case,
-  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
-  # similar.
-  AR="$am_aux_dir/ar-lib $AR"
-  ;;
-unknown)
-  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
   ;;
 esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
 
 
-# This was added at the suggestion of libtoolize (03-Jan-10)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
 
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
 
-# The default CFLAGS in Autoconf are "-g -O2" for gcc and just "-g" for any
-# other compiler. There doesn't seem to be a standard way of getting rid of the
-# -g (which I don't think is needed for a production library). This fudge seems
-# to achieve the necessary. First, we remember the externally set values of
-# CFLAGS. Then call the AC_PROG_CC macro to find the compiler - if CFLAGS is
-# not set, it will be set to Autoconf's defaults. Afterwards, if the original
-# values were not set, remove the -g from the Autoconf defaults.
-
-remember_set_CFLAGS="$CFLAGS"
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
 else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
 fi
 
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-else
-  CFLAGS=""
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  ac_c_werror_flag=$ac_save_c_werror_flag
-	 CFLAGS="-g"
-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
-if ${am_cv_prog_cc_c_o+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-  # Make sure it works both with $CC and with simple cc.
-  # Following AC_PROG_CC_C_O, we do the test twice because some
-  # compilers refuse to overwrite an existing .o file with -o,
-  # though they will create one.
-  am_cv_prog_cc_c_o=yes
-  for am_i in 1 2; do
-    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
-   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
-   ac_status=$?
-   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-   (exit $ac_status); } \
-         && test -f conftest2.$ac_objext; then
-      : OK
-    else
-      am_cv_prog_cc_c_o=no
-      break
-    fi
-  done
-  rm -f core conftest*
-  unset am_i
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
-$as_echo "$am_cv_prog_cc_c_o" >&6; }
-if test "$am_cv_prog_cc_c_o" != yes; then
-   # Losing compiler, so override with the script.
-   # FIXME: It is wrong to rewrite CC.
-   # But if we don't then we get into trouble of one sort or another.
-   # A longer-term fix would be to have automake use am__CC in this case,
-   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
-   CC="$am_aux_dir/compile $CC"
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
 
 depcc="$CC"   am_compiler_list=
 
@@ -5089,18 +4205,6 @@
 
 
 
-if test "x$remember_set_CFLAGS" = "x"
-then
-  if test "$CFLAGS" = "-g -O2"
-  then
-    CFLAGS="-O2"
-  elif test "$CFLAGS" = "-g"
-  then
-    CFLAGS=""
-  fi
-fi
-
-# Check for a 64-bit integer type
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5498,6 +4602,253 @@
 done
 
 
+
+  ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+  if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_safe_to_define___extensions__=yes
+else
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+  test $ac_cv_safe_to_define___extensions__ = yes &&
+    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+if test "x$remember_set_CFLAGS" = "x"
+then
+  if test "$CFLAGS" = "-g -O2"
+  then
+    CFLAGS="-O2"
+  elif test "$CFLAGS" = "-g"
+  then
+    CFLAGS=""
+  fi
+fi
+
+# This is a new thing required to stop a warning from automake 1.12
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+   am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+# Check for a 64-bit integer type
 ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
 case $ac_cv_c_int64_t in #(
   no|yes) ;; #(
@@ -5893,8 +5244,8 @@
 
 
 
-macro_version='2.4.6'
-macro_revision='2.4.6'
+macro_version='2.4.6.40-6ca5-dirty'
+macro_revision='2.4.6.40'
 
 
 
@@ -7349,13 +6700,29 @@
 fi
 
 : ${AR=ar}
-: ${AR_FLAGS=cru}
 
 
 
 
 
 
+# Use ARFLAGS variable as AR's operation code to sync the variable naming with
+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
+# higher priority because thats what people were doing historically (setting
+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
+# variable obsoleted/removed.
+
+test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
+lt_ar_flags=$AR_FLAGS
+
+
+
+
+
+
+# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
+
 
 
 
@@ -9073,8 +8440,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
-      echo "$AR cru libconftest.a conftest.o" >&5
-      $AR cru libconftest.a conftest.o 2>&5
+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5
+      $AR $AR_FLAGS libconftest.a conftest.o 2>&5
       echo "$RANLIB libconftest.a" >&5
       $RANLIB libconftest.a 2>&5
       cat > conftest.c << _LT_EOF
@@ -10568,6 +9935,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
+      file_list_spec='@'
       ;;
 
     interix[3-9]*)
@@ -10785,7 +10153,7 @@
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
 	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
 	else
-	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
@@ -11422,6 +10790,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
+      file_list_spec='@'
       ;;
 
     osf3*)
@@ -13365,30 +12734,41 @@
 old_striplib=
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
 $as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if test -z "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-  darwin*)
-    if test -n "$STRIP"; then
+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+    old_striplib="$STRIP --strip-debug"
+    striplib="$STRIP --strip-unneeded"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  else
+    case $host_os in
+    darwin*)
+      # FIXME - insert some real tests, host_os isn't really good enough
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-    else
+      ;;
+    freebsd*)
+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
+        old_striplib="$STRIP --strip-debug"
+        striplib="$STRIP --strip-unneeded"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+      fi
+      ;;
+    *)
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-    fi
-    ;;
-  *)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-    ;;
-  esac
+      ;;
+    esac
+  fi
 fi
 
 
@@ -13596,9 +12976,9 @@
 # Versioning
 
 PCRE2_MAJOR="10"
-PCRE2_MINOR="22"
+PCRE2_MINOR="31"
 PCRE2_PRERELEASE=""
-PCRE2_DATE="2016-07-29"
+PCRE2_DATE="2018-02-12"
 
 if test "$PCRE2_MINOR" = "08" -o "$PCRE2_MINOR" = "09"
 then
@@ -13697,6 +13077,15 @@
 fi
 
 
+# Handle --enable-jit-sealloc (disabled by default)
+# Check whether --enable-jit-sealloc was given.
+if test "${enable_jit_sealloc+set}" = set; then :
+  enableval=$enable_jit_sealloc;
+else
+  enable_jit_sealloc=no
+fi
+
+
 # Handle --disable-pcre2grep-jit (enabled by default)
 # Check whether --enable-pcre2grep-jit was given.
 if test "${enable_pcre2grep_jit+set}" = set; then :
@@ -13706,19 +13095,14 @@
 fi
 
 
-# Handle --disable-pcre2grep-callout (enabled by default) but not supported
-# for Windows.
-if test "$HAVE_WINDOWS_H" != "1"; then
-  # Check whether --enable-pcre2grep-callout was given.
+# Handle --disable-pcre2grep-callout (enabled by default)
+# Check whether --enable-pcre2grep-callout was given.
 if test "${enable_pcre2grep_callout+set}" = set; then :
   enableval=$enable_pcre2grep_callout;
 else
   enable_pcre2grep_callout=yes
 fi
 
-else
-  enable_pcre2grep_callout=no
-fi
 
 # Handle --enable-rebuild-chartables
 # Check whether --enable-rebuild-chartables was given.
@@ -13765,6 +13149,11 @@
   enableval=$enable_newline_is_any; ac_pcre2_newline=any
 fi
 
+# Check whether --enable-newline-is-nul was given.
+if test "${enable_newline_is_nul+set}" = set; then :
+  enableval=$enable_newline_is_nul; ac_pcre2_newline=nul
+fi
+
 enable_newline="$ac_pcre2_newline"
 
 # Handle --enable-bsr-anycrlf
@@ -13803,15 +13192,6 @@
 fi
 
 
-# Handle --disable-stack-for-recursion
-# Check whether --enable-stack-for-recursion was given.
-if test "${enable_stack_for_recursion+set}" = set; then :
-  enableval=$enable_stack_for_recursion;
-else
-  enable_stack_for_recursion=yes
-fi
-
-
 # Handle --enable-pcre2grep-libz
 # Check whether --enable-pcre2grep-libz was given.
 if test "${enable_pcre2grep_libz+set}" = set; then :
@@ -13840,6 +13220,16 @@
 fi
 
 
+# Handle --with-pcre2grep-max-bufsize=N
+
+# Check whether --with-pcre2grep-max-bufsize was given.
+if test "${with_pcre2grep_max_bufsize+set}" = set; then :
+  withval=$with_pcre2grep_max_bufsize;
+else
+  with_pcre2grep_max_bufsize=1048576
+fi
+
+
 # Handle --enable-pcre2test-libedit
 # Check whether --enable-pcre2test-libedit was given.
 if test "${enable_pcre2test_libedit+set}" = set; then :
@@ -13878,6 +13268,16 @@
 fi
 
 
+# Handle --with-heap-limit
+
+# Check whether --with-heap-limit was given.
+if test "${with_heap_limit+set}" = set; then :
+  withval=$with_heap_limit;
+else
+  with_heap_limit=20000000
+fi
+
+
 # Handle --with-match-limit=N
 
 # Check whether --with-match-limit was given.
@@ -13888,20 +13288,30 @@
 fi
 
 
-# Handle --with-match-limit_recursion=N
+# Handle --with-match-limit-depth=N
+# Recognize old synonym --with-match-limit-recursion
 #
-# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION
-# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric
-# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some
-# different numeric value (or even the same numeric value as MATCH_LIMIT,
-# though no longer defined in terms of the latter).
+# Note: In config.h, the default is to define MATCH_LIMIT_DEPTH symbolically as
+# MATCH_LIMIT, which in turn is defined to be some numeric value (e.g.
+# 10000000). MATCH_LIMIT_DEPTH can otherwise be set to some different numeric
+# value (or even the same numeric value as MATCH_LIMIT, though no longer
+# defined in terms of the latter).
 #
 
+# Check whether --with-match-limit-depth was given.
+if test "${with_match_limit_depth+set}" = set; then :
+  withval=$with_match_limit_depth;
+else
+  with_match_limit_depth=MATCH_LIMIT
+fi
+
+
+
 # Check whether --with-match-limit-recursion was given.
 if test "${with_match_limit_recursion+set}" = set; then :
   withval=$with_match_limit_recursion;
 else
-  with_match_limit_recursion=MATCH_LIMIT
+  with_match_limit_recursion=UNSET
 fi
 
 
@@ -13923,6 +13333,31 @@
 fi
 
 
+# Handle --enable-fuzz-support
+# Check whether --enable-fuzz_support was given.
+if test "${enable_fuzz_support+set}" = set; then :
+  enableval=$enable_fuzz_support;
+else
+  enable_fuzz_support=no
+fi
+
+
+# Handle --disable-stack-for-recursion
+# This option became obsolete at release 10.30.
+# Check whether --enable-stack-for-recursion was given.
+if test "${enable_stack_for_recursion+set}" = set; then :
+  enableval=$enable_stack_for_recursion;
+else
+  enable_stack_for_recursion=yes
+fi
+
+
+# Original code
+# AC_ARG_ENABLE(stack-for-recursion,
+#               AS_HELP_STRING([--disable-stack-for-recursion],
+#                              [don't use stack recursion when matching]),
+#               , enable_stack_for_recursion=yes)
+
 # Set the default value for pcre2-8
 if test "x$enable_pcre2_8" = "xunset"
 then
@@ -13962,6 +13397,7 @@
   crlf)    ac_pcre2_newline_value=3 ;;
   any)     ac_pcre2_newline_value=4 ;;
   anycrlf) ac_pcre2_newline_value=5 ;;
+  nul)     ac_pcre2_newline_value=6 ;;
   *)
   as_fn_error $? "invalid argument \"$enable_newline\" to --enable-newline option" "$LINENO" 5
   ;;
@@ -14214,6 +13650,19 @@
   WITH_VALGRIND_FALSE=
 fi
 
+ if test "x$enable_fuzz_support" = "xyes"; then
+  WITH_FUZZ_SUPPORT_TRUE=
+  WITH_FUZZ_SUPPORT_FALSE='#'
+else
+  WITH_FUZZ_SUPPORT_TRUE='#'
+  WITH_FUZZ_SUPPORT_FALSE=
+fi
+
+
+if test "$enable_fuzz_support" = "yes" -a "$enable_pcre2_8" = "no"; then
+  echo "** ERROR: Fuzzer support requires the 8-bit library"
+  exit 1
+fi
 
 # Checks for typedefs, structures, and compiler characteristics.
 
@@ -14312,7 +13761,7 @@
 
 # Checks for library functions.
 
-for ac_func in bcopy memmove strerror
+for ac_func in bcopy memmove strerror mkostemp secure_getenv
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -14815,8 +14264,6 @@
 
 fi
 
-# This facilitates -ansi builds under Linux
-
 PCRE2_STATIC_CFLAG=""
 if test "x$enable_shared" = "xno" ; then
 
@@ -15263,27 +14710,27 @@
   enable_pcre2grep_jit="no"
 fi
 
+if test "$enable_jit_sealloc" = "yes"; then
+
+$as_echo "#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 1" >>confdefs.h
+
+fi
+
 if test "$enable_pcre2grep_jit" = "yes"; then
 
 $as_echo "#define SUPPORT_PCRE2GREP_JIT /**/" >>confdefs.h
 
 fi
 
-# Currently pcre2grep callout string is not supported under Windows.
-
 if test "$enable_pcre2grep_callout" = "yes"; then
   if test "$HAVE_WINDOWS_H" != "1"; then
     if test "$HAVE_SYS_WAIT_H" != "1"; then
       as_fn_error $? "Callout script support needs sys/wait.h." "$LINENO" 5
     fi
+  fi
 
 $as_echo "#define SUPPORT_PCRE2GREP_CALLOUT /**/" >>confdefs.h
 
-  else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Callout script support is not available for Windows: disabled" >&5
-$as_echo "$as_me: WARNING: Callout script support is not available for Windows: disabled" >&2;}
-    enable_pcre2grep_callout=no
-  fi
 fi
 
 if test "$enable_unicode" = "yes"; then
@@ -15292,12 +14739,6 @@
 
 fi
 
-if test "$enable_stack_for_recursion" = "no"; then
-
-$as_echo "#define HEAP_MATCH_RECURSE /**/" >>confdefs.h
-
-fi
-
 if test "$enable_pcre2grep_libz" = "yes"; then
 
 $as_echo "#define SUPPORT_LIBZ /**/" >>confdefs.h
@@ -15316,7 +14757,15 @@
   with_pcre2grep_bufsize="8192"
 else
   if test $? -gt 1 ; then
-  as_fn_error $? "Bad value for  --with-pcre2grep-bufsize" "$LINENO" 5
+  as_fn_error $? "Bad value for --with-pcre2grep-bufsize" "$LINENO" 5
+  fi
+fi
+
+if test $with_pcre2grep_max_bufsize -lt $with_pcre2grep_bufsize ; then
+  with_pcre2grep_max_bufsize="$with_pcre2grep_bufsize"
+else
+  if test $? -gt 1 ; then
+  as_fn_error $? "Bad value for --with-pcre2grep-max-bufsize" "$LINENO" 5
   fi
 fi
 
@@ -15326,6 +14775,12 @@
 _ACEOF
 
 
+
+cat >>confdefs.h <<_ACEOF
+#define PCRE2GREP_MAX_BUFSIZE $with_pcre2grep_max_bufsize
+_ACEOF
+
+
 if test "$enable_pcre2test_libedit" = "yes"; then
 
 $as_echo "#define SUPPORT_LIBEDIT /**/" >>confdefs.h
@@ -15373,9 +14828,30 @@
 _ACEOF
 
 
+# --with-match-limit-recursion is an obsolete synonym for --with-match-limit-depth
+
+if test "$with_match_limit_recursion" != "UNSET"; then
+cat <<EOF
+
+WARNING: --with-match-limit-recursion is an obsolete option. Please use
+  --with-match-limit-depth in future. If both are set, --with-match-limit-depth
+  will be used. See also --with-heap-limit.
+
+EOF
+if test "$with_match_limit_depth" = "MATCH_LIMIT"; then
+  with_match_limit_depth=$with_match_limit_recursion
+fi
+fi
+
 
 cat >>confdefs.h <<_ACEOF
-#define MATCH_LIMIT_RECURSION $with_match_limit_recursion
+#define MATCH_LIMIT_DEPTH $with_match_limit_depth
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define HEAP_LIMIT $with_heap_limit
 _ACEOF
 
 
@@ -15429,16 +14905,16 @@
 # are m4 variables, assigned above.
 
 EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \
-  $NO_UNDEFINED -version-info 4:0:4"
+  $NO_UNDEFINED -version-info 7:0:7"
 
 EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \
-  $NO_UNDEFINED -version-info 4:0:4"
+  $NO_UNDEFINED -version-info 7:0:7"
 
 EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \
-  $NO_UNDEFINED -version-info 4:0:4"
+  $NO_UNDEFINED -version-info 7:0:7"
 
 EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \
-  $NO_UNDEFINED -version-info 1:0:0"
+  $NO_UNDEFINED -version-info 2:0:0"
 
 
 
@@ -15638,8 +15114,8 @@
 fi
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND" >&5
-$as_echo_n "checking for VALGRIND... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for valgrind" >&5
+$as_echo_n "checking for valgrind... " >&6; }
 
 if test -n "$VALGRIND_CFLAGS"; then
     pkg_cv_VALGRIND_CFLAGS="$VALGRIND_CFLAGS"
@@ -15679,7 +15155,7 @@
 
 
 if test $pkg_failed = yes; then
-   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -15706,7 +15182,7 @@
 and VALGRIND_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details." "$LINENO" 5
 elif test $pkg_failed = untried; then
-     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
@@ -16044,10 +15520,6 @@
   as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
-  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${WITH_PCRE2_8_TRUE}" && test -z "${WITH_PCRE2_8_FALSE}"; then
   as_fn_error $? "conditional \"WITH_PCRE2_8\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -16080,6 +15552,10 @@
   as_fn_error $? "conditional \"WITH_VALGRIND\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${WITH_FUZZ_SUPPORT_TRUE}" && test -z "${WITH_FUZZ_SUPPORT_FALSE}"; then
+  as_fn_error $? "conditional \"WITH_FUZZ_SUPPORT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${WITH_GCOV_TRUE}" && test -z "${WITH_GCOV_FALSE}"; then
   as_fn_error $? "conditional \"WITH_GCOV\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -16481,7 +15957,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by PCRE2 $as_me 10.22, which was
+This file was extended by PCRE2 $as_me 10.31, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16547,7 +16023,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-PCRE2 config.status 10.22
+PCRE2 config.status 10.31
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -16719,6 +16195,7 @@
 want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
 sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
 AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`'
 AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
 archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
 STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
@@ -16848,7 +16325,6 @@
 want_nocaseglob \
 sharedlib_from_linklib_cmd \
 AR \
-AR_FLAGS \
 archiver_list_spec \
 STRIP \
 RANLIB \
@@ -17823,8 +17299,11 @@
 # The archiver.
 AR=$lt_AR
 
+# Flags to create an archive (by configure).
+lt_ar_flags=$lt_ar_flags
+
 # Flags to create an archive.
-AR_FLAGS=$lt_AR_FLAGS
+AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"}
 
 # How to feed a file listing to the archiver.
 archiver_list_spec=$lt_archiver_list_spec
@@ -18248,6 +17727,15 @@
 fi
 
 
+# --disable-stack-for-recursion is obsolete and has no effect.
+
+if test "$enable_stack_for_recursion" = "no"; then
+cat <<EOF
+
+WARNING: --disable-stack-for-recursion is obsolete and has no effect.
+EOF
+fi
+
 # Print out a nice little message after configure is run displaying the
 # chosen options.
 
@@ -18262,43 +17750,46 @@
 
 $PACKAGE-$VERSION configuration summary:
 
-    Install prefix .................. : ${prefix}
-    C preprocessor .................. : ${CPP}
-    C compiler ...................... : ${CC}
-    Linker .......................... : ${LD}
-    C preprocessor flags ............ : ${CPPFLAGS}
-    C compiler flags ................ : ${CFLAGS} ${VISIBILITY_CFLAGS}
-    Linker flags .................... : ${LDFLAGS}
-    Extra libraries ................. : ${LIBS}
+    Install prefix ..................... : ${prefix}
+    C preprocessor ..................... : ${CPP}
+    C compiler ......................... : ${CC}
+    Linker ............................. : ${LD}
+    C preprocessor flags ............... : ${CPPFLAGS}
+    C compiler flags ................... : ${CFLAGS} ${VISIBILITY_CFLAGS}
+    Linker flags ....................... : ${LDFLAGS}
+    Extra libraries .................... : ${LIBS}
 
-    Build 8-bit pcre2 library ....... : ${enable_pcre2_8}
-    Build 16-bit pcre2 library ...... : ${enable_pcre2_16}
-    Build 32-bit pcre2 library ...... : ${enable_pcre2_32}
-    Include debugging code .......... : ${enable_debug}
-    Enable JIT compiling support .... : ${enable_jit}
-    Enable Unicode support .......... : ${enable_unicode}
-    Newline char/sequence ........... : ${enable_newline}
-    \R matches only ANYCRLF ......... : ${enable_bsr_anycrlf}
-    \C is disabled .................. : ${enable_never_backslash_C}
-    EBCDIC coding ................... : ${enable_ebcdic}
-    EBCDIC code for NL .............. : ${ebcdic_nl_code}
-    Rebuild char tables ............. : ${enable_rebuild_chartables}
-    Use stack recursion ............. : ${enable_stack_for_recursion}
-    Internal link size .............. : ${with_link_size}
-    Nested parentheses limit ........ : ${with_parens_nest_limit}
-    Match limit ..................... : ${with_match_limit}
-    Match limit recursion ........... : ${with_match_limit_recursion}
-    Build shared libs ............... : ${enable_shared}
-    Build static libs ............... : ${enable_static}
-    Use JIT in pcre2grep ............ : ${enable_pcre2grep_jit}
-    Enable callouts in pcre2grep .... : ${enable_pcre2grep_callout}
-    Buffer size for pcre2grep ....... : ${with_pcre2grep_bufsize}
-    Link pcre2grep with libz ........ : ${enable_pcre2grep_libz}
-    Link pcre2grep with libbz2 ...... : ${enable_pcre2grep_libbz2}
-    Link pcre2test with libedit ..... : ${enable_pcre2test_libedit}
-    Link pcre2test with libreadline . : ${enable_pcre2test_libreadline}
-    Valgrind support ................ : ${enable_valgrind}
-    Code coverage ................... : ${enable_coverage}
+    Build 8-bit pcre2 library .......... : ${enable_pcre2_8}
+    Build 16-bit pcre2 library ......... : ${enable_pcre2_16}
+    Build 32-bit pcre2 library ......... : ${enable_pcre2_32}
+    Include debugging code ............. : ${enable_debug}
+    Enable JIT compiling support ....... : ${enable_jit}
+    Use SELinux allocator in JIT ....... : ${enable_jit_sealloc}
+    Enable Unicode support ............. : ${enable_unicode}
+    Newline char/sequence .............. : ${enable_newline}
+    \R matches only ANYCRLF ............ : ${enable_bsr_anycrlf}
+    \C is disabled ..................... : ${enable_never_backslash_C}
+    EBCDIC coding ...................... : ${enable_ebcdic}
+    EBCDIC code for NL ................. : ${ebcdic_nl_code}
+    Rebuild char tables ................ : ${enable_rebuild_chartables}
+    Internal link size ................. : ${with_link_size}
+    Nested parentheses limit ........... : ${with_parens_nest_limit}
+    Heap limit ......................... : ${with_heap_limit} kilobytes
+    Match limit ........................ : ${with_match_limit}
+    Match depth limit .................. : ${with_match_limit_depth}
+    Build shared libs .................. : ${enable_shared}
+    Build static libs .................. : ${enable_static}
+    Use JIT in pcre2grep ............... : ${enable_pcre2grep_jit}
+    Enable callouts in pcre2grep ....... : ${enable_pcre2grep_callout}
+    Initial buffer size for pcre2grep .. : ${with_pcre2grep_bufsize}
+    Maximum buffer size for pcre2grep .. : ${with_pcre2grep_max_bufsize}
+    Link pcre2grep with libz ........... : ${enable_pcre2grep_libz}
+    Link pcre2grep with libbz2 ......... : ${enable_pcre2grep_libbz2}
+    Link pcre2test with libedit ........ : ${enable_pcre2test_libedit}
+    Link pcre2test with libreadline .... : ${enable_pcre2test_libreadline}
+    Valgrind support ................... : ${enable_valgrind}
+    Code coverage ...................... : ${enable_coverage}
+    Fuzzer support ..................... : ${enable_fuzz_support}
 
 EOF
 
diff --git a/dist2/configure.ac b/dist2/configure.ac
index d7c57aa..2164e4c 100644
--- a/dist2/configure.ac
+++ b/dist2/configure.ac
@@ -9,18 +9,18 @@
 dnl be defined as -RC2, for example. For real releases, it should be empty.
 
 m4_define(pcre2_major, [10])
-m4_define(pcre2_minor, [22])
+m4_define(pcre2_minor, [31])
 m4_define(pcre2_prerelease, [])
-m4_define(pcre2_date, [2016-07-29])
+m4_define(pcre2_date, [2018-02-12])
 
 # NOTE: The CMakeLists.txt file searches for the above variables in the first
 # 50 lines of this file. Please update that if the variables above are moved.
 
 # Libtool shared library interface versions (current:revision:age)
-m4_define(libpcre2_8_version,     [4:0:4])
-m4_define(libpcre2_16_version,    [4:0:4])
-m4_define(libpcre2_32_version,    [4:0:4])
-m4_define(libpcre2_posix_version, [1:0:0])
+m4_define(libpcre2_8_version,     [7:0:7])
+m4_define(libpcre2_16_version,    [7:0:7])
+m4_define(libpcre2_32_version,    [7:0:7])
+m4_define(libpcre2_posix_version, [2:0:0])
 
 AC_PREREQ(2.57)
 AC_INIT(PCRE2, pcre2_major.pcre2_minor[]pcre2_prerelease, , pcre2)
@@ -29,9 +29,6 @@
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 AC_CONFIG_HEADERS(src/config.h)
 
-# This is a new thing required to stop a warning from automake 1.12
-m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
-
 # This was added at the suggestion of libtoolize (03-Jan-10)
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -47,6 +44,7 @@
 
 AC_PROG_CC
 AM_PROG_CC_C_O
+AC_USE_SYSTEM_EXTENSIONS
 
 if test "x$remember_set_CFLAGS" = "x"
 then
@@ -59,6 +57,9 @@
   fi
 fi
 
+# This is a new thing required to stop a warning from automake 1.12
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
 # Check for a 64-bit integer type
 AC_TYPE_INT64_T
 
@@ -142,22 +143,23 @@
                              [enable Just-In-Time compiling support]),
               , enable_jit=no)
 
+# Handle --enable-jit-sealloc (disabled by default)
+AC_ARG_ENABLE(jit-sealloc,
+              AS_HELP_STRING([--enable-jit-sealloc],
+                             [enable SELinux compatible execmem allocator in JIT]),
+              , enable_jit_sealloc=no)
+
 # Handle --disable-pcre2grep-jit (enabled by default)
 AC_ARG_ENABLE(pcre2grep-jit,
               AS_HELP_STRING([--disable-pcre2grep-jit],
                              [disable JIT support in pcre2grep]),
               , enable_pcre2grep_jit=yes)
 
-# Handle --disable-pcre2grep-callout (enabled by default) but not supported
-# for Windows.
-if test "$HAVE_WINDOWS_H" != "1"; then
-  AC_ARG_ENABLE(pcre2grep-callout,
-                AS_HELP_STRING([--disable-pcre2grep-callout],
-                               [disable callout script support in pcre2grep]),
-                , enable_pcre2grep_callout=yes)
-else
-  enable_pcre2grep_callout=no
-fi
+# Handle --disable-pcre2grep-callout (enabled by default)
+AC_ARG_ENABLE(pcre2grep-callout,
+              AS_HELP_STRING([--disable-pcre2grep-callout],
+                             [disable callout script support in pcre2grep]),
+              , enable_pcre2grep_callout=yes)
 
 # Handle --enable-rebuild-chartables
 AC_ARG_ENABLE(rebuild-chartables,
@@ -193,6 +195,10 @@
               AS_HELP_STRING([--enable-newline-is-any],
                              [use any valid Unicode newline sequence]),
               ac_pcre2_newline=any)
+AC_ARG_ENABLE(newline-is-nul,
+              AS_HELP_STRING([--enable-newline-is-nul],
+                             [use NUL (binary zero) as newline character]),
+              ac_pcre2_newline=nul)
 enable_newline="$ac_pcre2_newline"
 
 # Handle --enable-bsr-anycrlf
@@ -219,12 +225,6 @@
                              [set EBCDIC code for NL to 0x25 instead of 0x15; it implies --enable-ebcdic]),
               , enable_ebcdic_nl25=no)
 
-# Handle --disable-stack-for-recursion
-AC_ARG_ENABLE(stack-for-recursion,
-              AS_HELP_STRING([--disable-stack-for-recursion],
-                             [don't use stack recursion when matching]),
-              , enable_stack_for_recursion=yes)
-
 # Handle --enable-pcre2grep-libz
 AC_ARG_ENABLE(pcre2grep-libz,
               AS_HELP_STRING([--enable-pcre2grep-libz],
@@ -240,9 +240,15 @@
 # Handle --with-pcre2grep-bufsize=N
 AC_ARG_WITH(pcre2grep-bufsize,
               AS_HELP_STRING([--with-pcre2grep-bufsize=N],
-                             [pcre2grep buffer size (default=20480, minimum=8192)]),
+                             [pcre2grep initial buffer size (default=20480, minimum=8192)]),
               , with_pcre2grep_bufsize=20480)
 
+# Handle --with-pcre2grep-max-bufsize=N
+AC_ARG_WITH(pcre2grep-max-bufsize,
+              AS_HELP_STRING([--with-pcre2grep-max-bufsize=N],
+                             [pcre2grep maximum buffer size (default=1048576, minimum=8192)]),
+              , with_pcre2grep_max_bufsize=1048576)
+
 # Handle --enable-pcre2test-libedit
 AC_ARG_ENABLE(pcre2test-libedit,
               AS_HELP_STRING([--enable-pcre2test-libedit],
@@ -267,29 +273,39 @@
                            [nested parentheses limit (default=250)]),
             , with_parens_nest_limit=250)
 
+# Handle --with-heap-limit
+AC_ARG_WITH(heap-limit,
+            AS_HELP_STRING([--with-heap-limit=N],
+                           [default limit on heap memory (kilobytes, default=20000000)]),
+            , with_heap_limit=20000000)
+
 # Handle --with-match-limit=N
 AC_ARG_WITH(match-limit,
             AS_HELP_STRING([--with-match-limit=N],
                            [default limit on internal looping (default=10000000)]),
             , with_match_limit=10000000)
 
-# Handle --with-match-limit_recursion=N
+# Handle --with-match-limit-depth=N
+# Recognize old synonym --with-match-limit-recursion
 #
-# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION
-# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric
-# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some
-# different numeric value (or even the same numeric value as MATCH_LIMIT,
-# though no longer defined in terms of the latter).
+# Note: In config.h, the default is to define MATCH_LIMIT_DEPTH symbolically as
+# MATCH_LIMIT, which in turn is defined to be some numeric value (e.g.
+# 10000000). MATCH_LIMIT_DEPTH can otherwise be set to some different numeric
+# value (or even the same numeric value as MATCH_LIMIT, though no longer
+# defined in terms of the latter).
 #
-AC_ARG_WITH(match-limit-recursion,
-            AS_HELP_STRING([--with-match-limit-recursion=N],
-                           [default limit on internal recursion (default=MATCH_LIMIT)]),
-            , with_match_limit_recursion=MATCH_LIMIT)
+AC_ARG_WITH(match-limit-depth,
+            AS_HELP_STRING([--with-match-limit-depth=N],
+                           [default limit on match tree depth (default=MATCH_LIMIT)]),
+            , with_match_limit_depth=MATCH_LIMIT)
+
+AC_ARG_WITH(match-limit-recursion,,
+            , with_match_limit_recursion=UNSET)
 
 # Handle --enable-valgrind
 AC_ARG_ENABLE(valgrind,
               AS_HELP_STRING([--enable-valgrind],
-                             [valgrind support]),
+                             [enable valgrind support]),
               , enable_valgrind=no)
 
 # Enable code coverage reports using gcov
@@ -298,6 +314,23 @@
                              [enable code coverage reports using gcov]),
               , enable_coverage=no)
 
+# Handle --enable-fuzz-support
+AC_ARG_ENABLE(fuzz_support,
+              AS_HELP_STRING([--enable-fuzz-support],
+                             [enable fuzzer support]),
+              , enable_fuzz_support=no)
+
+# Handle --disable-stack-for-recursion
+# This option became obsolete at release 10.30.
+AC_ARG_ENABLE(stack-for-recursion,,
+              , enable_stack_for_recursion=yes)
+
+# Original code
+# AC_ARG_ENABLE(stack-for-recursion,
+#               AS_HELP_STRING([--disable-stack-for-recursion],
+#                              [don't use stack recursion when matching]),
+#               , enable_stack_for_recursion=yes)
+
 # Set the default value for pcre2-8
 if test "x$enable_pcre2_8" = "xunset"
 then
@@ -337,6 +370,7 @@
   crlf)    ac_pcre2_newline_value=3 ;;
   any)     ac_pcre2_newline_value=4 ;;
   anycrlf) ac_pcre2_newline_value=5 ;;
+  nul)     ac_pcre2_newline_value=6 ;;
   *)
   AC_MSG_ERROR([invalid argument \"$enable_newline\" to --enable-newline option])
   ;;
@@ -414,6 +448,12 @@
 AM_CONDITIONAL(WITH_JIT, test "x$enable_jit" = "xyes")
 AM_CONDITIONAL(WITH_UNICODE, test "x$enable_unicode" = "xyes")
 AM_CONDITIONAL(WITH_VALGRIND, test "x$enable_valgrind" = "xyes")
+AM_CONDITIONAL(WITH_FUZZ_SUPPORT, test "x$enable_fuzz_support" = "xyes")
+
+if test "$enable_fuzz_support" = "yes" -a "$enable_pcre2_8" = "no"; then
+  echo "** ERROR: Fuzzer support requires the 8-bit library"
+  exit 1
+fi
 
 # Checks for typedefs, structures, and compiler characteristics.
 
@@ -422,7 +462,7 @@
 
 # Checks for library functions.
 
-AC_CHECK_FUNCS(bcopy memmove strerror)
+AC_CHECK_FUNCS(bcopy memmove strerror mkostemp secure_getenv)
 
 # Check for the availability of libz (aka zlib)
 
@@ -505,9 +545,6 @@
   AC_CHECK_LIB([edit], [readline], [LIBEDIT="-ledit"])
 fi
 
-# This facilitates -ansi builds under Linux
-dnl AC_DEFINE([_GNU_SOURCE], [], [Enable GNU extensions in glibc])
-
 PCRE2_STATIC_CFLAG=""
 if test "x$enable_shared" = "xno" ; then
   AC_DEFINE([PCRE2_STATIC], [1], [
@@ -553,24 +590,27 @@
   enable_pcre2grep_jit="no"
 fi
 
-if test "$enable_pcre2grep_jit" = "yes"; then
-  AC_DEFINE([SUPPORT_PCRE2GREP_JIT], [], [
-    Define to any value to enable JIT support in pcre2grep.])
+if test "$enable_jit_sealloc" = "yes"; then
+  AC_DEFINE([SLJIT_PROT_EXECUTABLE_ALLOCATOR], [1], [
+    Define to any non-zero number to enable support for SELinux
+    compatible executable memory allocator in JIT. Note that this
+    will have no effect unless SUPPORT_JIT is also defined.])
 fi
 
-# Currently pcre2grep callout string is not supported under Windows.
+if test "$enable_pcre2grep_jit" = "yes"; then
+  AC_DEFINE([SUPPORT_PCRE2GREP_JIT], [], [
+    Define to any value to enable JIT support in pcre2grep. Note that this will
+    have no effect unless SUPPORT_JIT is also defined.])
+fi
 
 if test "$enable_pcre2grep_callout" = "yes"; then
   if test "$HAVE_WINDOWS_H" != "1"; then
     if test "$HAVE_SYS_WAIT_H" != "1"; then
       AC_MSG_ERROR([Callout script support needs sys/wait.h.])
     fi
-    AC_DEFINE([SUPPORT_PCRE2GREP_CALLOUT], [], [
-      Define to any value to enable callout script support in pcre2grep.])
-  else
-    AC_MSG_WARN([Callout script support is not available for Windows: disabled])
-    enable_pcre2grep_callout=no
   fi
+  AC_DEFINE([SUPPORT_PCRE2GREP_CALLOUT], [], [
+    Define to any value to enable callout script support in pcre2grep.])
 fi
 
 if test "$enable_unicode" = "yes"; then
@@ -581,16 +621,6 @@
     code *or* ASCII/Unicode, but not both at once.])
 fi
 
-if test "$enable_stack_for_recursion" = "no"; then
-  AC_DEFINE([HEAP_MATCH_RECURSE], [], [
-    PCRE2 uses recursive function calls to handle backtracking while
-    matching. This can sometimes be a problem on systems that have
-    stacks of limited size. Define HEAP_MATCH_RECURSE to any value to get a
-    version that doesn't use recursion in the match() function; instead
-    it creates its own stack by steam using memory from the heap. For more
-    detail, see the comments and other stuff just above the match() function.])
-fi
-
 if test "$enable_pcre2grep_libz" = "yes"; then
   AC_DEFINE([SUPPORT_LIBZ], [], [
     Define to any value to allow pcre2grep to be linked with libz, so that it is
@@ -608,15 +638,30 @@
   with_pcre2grep_bufsize="8192"
 else
   if test $? -gt 1 ; then
-  AC_MSG_ERROR([Bad value for  --with-pcre2grep-bufsize])
+  AC_MSG_ERROR([Bad value for --with-pcre2grep-bufsize])
+  fi
+fi
+
+if test $with_pcre2grep_max_bufsize -lt $with_pcre2grep_bufsize ; then
+  with_pcre2grep_max_bufsize="$with_pcre2grep_bufsize"
+else
+  if test $? -gt 1 ; then
+  AC_MSG_ERROR([Bad value for --with-pcre2grep-max-bufsize])
   fi
 fi
 
 AC_DEFINE_UNQUOTED([PCRE2GREP_BUFSIZE], [$with_pcre2grep_bufsize], [
-  The value of PCRE2GREP_BUFSIZE determines the size of buffer used by pcre2grep
-  to hold parts of the file it is searching. This is also the minimum value.
-  The actual amount of memory used by pcre2grep is three times this number,
-  because it allows for the buffering of "before" and "after" lines.])
+  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.])
+
+AC_DEFINE_UNQUOTED([PCRE2GREP_MAX_BUFSIZE], [$with_pcre2grep_max_bufsize], [
+  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.])
 
 if test "$enable_pcre2test_libedit" = "yes"; then
   AC_DEFINE([SUPPORT_LIBEDIT], [], [
@@ -631,7 +676,7 @@
   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),
-  and 5 (ANYCRLF).])
+  5 (ANYCRLF), and 6 (NUL).])
 
 if test "$enable_bsr_anycrlf" = "yes"; then
   AC_DEFINE([BSR_ANYCRLF], [], [
@@ -660,23 +705,39 @@
 
 AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [
   The value of MATCH_LIMIT determines the default number of times the
-  internal match() function can be called during a single execution of
-  pcre2_match(). There is a runtime interface for setting a different
-  limit. The limit exists in order to catch runaway regular
-  expressions that take for ever to determine that they do not match.
-  The default is set very large so that it does not accidentally catch
-  legitimate cases.])
+  pcre2_match() function can record a backtrack position during a single
+  matching attempt. There is a runtime interface for setting a different limit.
+  The limit exists in order to catch runaway regular expressions that take for
+  ever to determine that they do not match. The default is set very large so
+  that it does not accidentally catch legitimate cases.])
 
-AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [
-  The above limit applies to all calls of match(), whether or not they
-  increase the recursion depth. In some environments it is desirable
-  to limit the depth of recursive calls of match() more strictly, in
-  order to restrict the maximum amount of stack (or heap, if
-  HEAP_MATCH_RECURSE is defined) that is used. The value of
-  MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To
-  have any useful effect, it must be less than the value of
-  MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT.
-  There is a runtime method for setting a different limit.])
+# --with-match-limit-recursion is an obsolete synonym for --with-match-limit-depth
+
+if test "$with_match_limit_recursion" != "UNSET"; then
+cat <<EOF
+
+WARNING: --with-match-limit-recursion is an obsolete option. Please use
+  --with-match-limit-depth in future. If both are set, --with-match-limit-depth
+  will be used. See also --with-heap-limit.
+
+EOF
+if test "$with_match_limit_depth" = "MATCH_LIMIT"; then
+  with_match_limit_depth=$with_match_limit_recursion
+fi
+fi
+
+AC_DEFINE_UNQUOTED([MATCH_LIMIT_DEPTH], [$with_match_limit_depth], [
+  The above limit applies to all backtracks, whether or not they are nested. In
+  some environments it is desirable to limit the nesting of backtracking (that
+  is, the depth of tree that is searched) more strictly, in order to restrict
+  the maximum amount of heap memory that is used. The value of
+  MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it must
+  be less than the value of MATCH_LIMIT. The default is to use the same value
+  as MATCH_LIMIT. There is a runtime method for setting a different limit.])
+
+AC_DEFINE_UNQUOTED([HEAP_LIMIT], [$with_heap_limit], [
+  This limits the amount of memory that pcre2_match() may use while matching
+  a pattern. The value is in kilobytes.])
 
 AC_DEFINE([MAX_NAME_SIZE], [32], [
   This limit is parameterized just in case anybody ever wants to
@@ -892,6 +953,15 @@
 
 AC_OUTPUT
 
+# --disable-stack-for-recursion is obsolete and has no effect.
+
+if test "$enable_stack_for_recursion" = "no"; then
+cat <<EOF
+
+WARNING: --disable-stack-for-recursion is obsolete and has no effect.
+EOF
+fi
+
 # Print out a nice little message after configure is run displaying the
 # chosen options.
 
@@ -906,43 +976,46 @@
 
 $PACKAGE-$VERSION configuration summary:
 
-    Install prefix .................. : ${prefix}
-    C preprocessor .................. : ${CPP}
-    C compiler ...................... : ${CC}
-    Linker .......................... : ${LD}
-    C preprocessor flags ............ : ${CPPFLAGS}
-    C compiler flags ................ : ${CFLAGS} ${VISIBILITY_CFLAGS}
-    Linker flags .................... : ${LDFLAGS}
-    Extra libraries ................. : ${LIBS}
+    Install prefix ..................... : ${prefix}
+    C preprocessor ..................... : ${CPP}
+    C compiler ......................... : ${CC}
+    Linker ............................. : ${LD}
+    C preprocessor flags ............... : ${CPPFLAGS}
+    C compiler flags ................... : ${CFLAGS} ${VISIBILITY_CFLAGS}
+    Linker flags ....................... : ${LDFLAGS}
+    Extra libraries .................... : ${LIBS}
 
-    Build 8-bit pcre2 library ....... : ${enable_pcre2_8}
-    Build 16-bit pcre2 library ...... : ${enable_pcre2_16}
-    Build 32-bit pcre2 library ...... : ${enable_pcre2_32}
-    Include debugging code .......... : ${enable_debug}
-    Enable JIT compiling support .... : ${enable_jit}
-    Enable Unicode support .......... : ${enable_unicode}
-    Newline char/sequence ........... : ${enable_newline}
-    \R matches only ANYCRLF ......... : ${enable_bsr_anycrlf}
-    \C is disabled .................. : ${enable_never_backslash_C}
-    EBCDIC coding ................... : ${enable_ebcdic}
-    EBCDIC code for NL .............. : ${ebcdic_nl_code}
-    Rebuild char tables ............. : ${enable_rebuild_chartables}
-    Use stack recursion ............. : ${enable_stack_for_recursion}
-    Internal link size .............. : ${with_link_size}
-    Nested parentheses limit ........ : ${with_parens_nest_limit}
-    Match limit ..................... : ${with_match_limit}
-    Match limit recursion ........... : ${with_match_limit_recursion}
-    Build shared libs ............... : ${enable_shared}
-    Build static libs ............... : ${enable_static}
-    Use JIT in pcre2grep ............ : ${enable_pcre2grep_jit}
-    Enable callouts in pcre2grep .... : ${enable_pcre2grep_callout}
-    Buffer size for pcre2grep ....... : ${with_pcre2grep_bufsize}
-    Link pcre2grep with libz ........ : ${enable_pcre2grep_libz}
-    Link pcre2grep with libbz2 ...... : ${enable_pcre2grep_libbz2}
-    Link pcre2test with libedit ..... : ${enable_pcre2test_libedit}
-    Link pcre2test with libreadline . : ${enable_pcre2test_libreadline}
-    Valgrind support ................ : ${enable_valgrind}
-    Code coverage ................... : ${enable_coverage}
+    Build 8-bit pcre2 library .......... : ${enable_pcre2_8}
+    Build 16-bit pcre2 library ......... : ${enable_pcre2_16}
+    Build 32-bit pcre2 library ......... : ${enable_pcre2_32}
+    Include debugging code ............. : ${enable_debug}
+    Enable JIT compiling support ....... : ${enable_jit}
+    Use SELinux allocator in JIT ....... : ${enable_jit_sealloc}
+    Enable Unicode support ............. : ${enable_unicode}
+    Newline char/sequence .............. : ${enable_newline}
+    \R matches only ANYCRLF ............ : ${enable_bsr_anycrlf}
+    \C is disabled ..................... : ${enable_never_backslash_C}
+    EBCDIC coding ...................... : ${enable_ebcdic}
+    EBCDIC code for NL ................. : ${ebcdic_nl_code}
+    Rebuild char tables ................ : ${enable_rebuild_chartables}
+    Internal link size ................. : ${with_link_size}
+    Nested parentheses limit ........... : ${with_parens_nest_limit}
+    Heap limit ......................... : ${with_heap_limit} kilobytes
+    Match limit ........................ : ${with_match_limit}
+    Match depth limit .................. : ${with_match_limit_depth}
+    Build shared libs .................. : ${enable_shared}
+    Build static libs .................. : ${enable_static}
+    Use JIT in pcre2grep ............... : ${enable_pcre2grep_jit}
+    Enable callouts in pcre2grep ....... : ${enable_pcre2grep_callout}
+    Initial buffer size for pcre2grep .. : ${with_pcre2grep_bufsize}
+    Maximum buffer size for pcre2grep .. : ${with_pcre2grep_max_bufsize}
+    Link pcre2grep with libz ........... : ${enable_pcre2grep_libz}
+    Link pcre2grep with libbz2 ......... : ${enable_pcre2grep_libbz2}
+    Link pcre2test with libedit ........ : ${enable_pcre2test_libedit}
+    Link pcre2test with libreadline .... : ${enable_pcre2test_libreadline}
+    Valgrind support ................... : ${enable_valgrind}
+    Code coverage ...................... : ${enable_coverage}
+    Fuzzer support ..................... : ${enable_fuzz_support}
 
 EOF
 
diff --git a/dist2/depcomp b/dist2/depcomp
index fc98710..b39f98f 100755
--- a/dist2/depcomp
+++ b/dist2/depcomp
@@ -1,9 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2013-05-30.07; # UTC
+scriptversion=2016-01-11.22; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -786,6 +786,6 @@
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/dist2/doc/html/NON-AUTOTOOLS-BUILD.txt b/dist2/doc/html/NON-AUTOTOOLS-BUILD.txt
index ceb9245..0775794 100644
--- a/dist2/doc/html/NON-AUTOTOOLS-BUILD.txt
+++ b/dist2/doc/html/NON-AUTOTOOLS-BUILD.txt
@@ -1,10 +1,6 @@
 Building PCRE2 without using autotools
 --------------------------------------
 
-This document has been converted from the PCRE1 document. I have removed a
-number of sections about building in various environments, as they applied only
-to PCRE1 and are probably out of date.
-
 This document contains the following sections:
 
   General
@@ -49,7 +45,7 @@
      macro settings that it contains to whatever is appropriate for your
      environment. In particular, you can alter the definition of the NEWLINE
      macro to specify what character(s) you want to be interpreted as line
-     terminators.
+     terminators by default.
 
      When you compile any of the PCRE2 modules, you must specify
      -DHAVE_CONFIG_H to your compiler so that src/config.h is included in the
@@ -95,8 +91,10 @@
        pcre2_compile.c
        pcre2_config.c
        pcre2_context.c
+       pcre2_convert.c
        pcre2_dfa_match.c
        pcre2_error.c
+       pcre2_extuni.c
        pcre2_find_bracket.c
        pcre2_jit_compile.c
        pcre2_maketables.c
@@ -123,10 +121,14 @@
      Note that you must compile pcre2_jit_compile.c, even if you have not
      defined SUPPORT_JIT in src/config.h, because when JIT support is not
      configured, dummy functions are compiled. When JIT support IS configured,
-     pcre2_compile.c #includes other files from the sljit subdirectory, where
-     there should be 16 files, all of whose names begin with "sljit". It also
-     #includes src/pcre2_jit_match.c and src/pcre2_jit_misc.c, so you should
-     not compile these yourself.
+     pcre2_jit_compile.c #includes other files from the sljit subdirectory,
+     all of whose names begin with "sljit". It also #includes
+     src/pcre2_jit_match.c and src/pcre2_jit_misc.c, so you should not compile
+     these yourself.
+
+     Not also that the pcre2_fuzzsupport.c file contains special code that is
+     useful to those who want to run fuzzing tests on the PCRE2 library. Unless
+     you are doing that, you can ignore it.
 
  (5) Now link all the compiled code into an object library in whichever form
      your system keeps such libraries. This is the basic PCRE2 C 8-bit library.
@@ -174,26 +176,18 @@
 
 (11) If you want to use the pcre2grep command, compile and link
      src/pcre2grep.c; it uses only the basic 8-bit PCRE2 library (it does not
-     need the pcre2posix library).
+     need the pcre2posix library). If you have built the PCRE2 library with JIT
+     support by defining SUPPORT_JIT in src/config.h, you can also define
+     SUPPORT_PCRE2GREP_JIT, which causes pcre2grep to make use of JIT (unless
+     it is run with --no-jit). If you define SUPPORT_PCRE2GREP_JIT without
+     defining SUPPORT_JIT, pcre2grep does not try to make use of JIT.
 
 
 STACK SIZE IN WINDOWS ENVIRONMENTS
 
-The default processor stack size of 1Mb in some Windows environments is too
-small for matching patterns that need much recursion. In particular, test 2 may
-fail because of this. Normally, running out of stack causes a crash, but there
-have been cases where the test program has just died silently. See your linker
-documentation for how to increase stack size if you experience problems. If you
-are using CMake (see "BUILDING PCRE2 ON WINDOWS WITH CMAKE" below) and the gcc
-compiler, you can increase the stack size for pcre2test and pcre2grep by
-setting the CMAKE_EXE_LINKER_FLAGS variable to "-Wl,--stack,8388608" (for
-example). The Linux default of 8Mb is a reasonable choice for the stack, though
-even that can be too small for some pattern/subject combinations.
-
-PCRE2 has a compile configuration option to disable the use of stack for
-recursion so that heap is used instead. However, pattern matching is
-significantly slower when this is done. There is more about stack usage in the
-"pcre2stack" documentation.
+Prior to release 10.30 the default system stack size of 1Mb in some Windows
+environments caused issues with some tests. This should no longer be the case
+for 10.30 and later releases.
 
 
 LINKING PROGRAMS IN WINDOWS ENVIRONMENTS
@@ -375,18 +369,19 @@
 z/OS and z/VM are operating systems for mainframe computers, produced by IBM.
 The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and
 applications can be supported through UNIX System Services, and in such an
-environment PCRE2 can be built in the same way as in other systems. However, in
-native z/OS (without UNIX System Services) and in z/VM, special ports are
-required. For details, please see this web site:
+environment it should be possible to build PCRE2 in the same way as in other
+systems, with the EBCDIC related configuration settings, but it is not known if
+anybody has tried this.
 
-  http://www.zaconsultants.net
+In native z/OS (without UNIX System Services) and in z/VM, special ports are
+required. For details, please see file 939 on this web site:
 
-The site currently has ports for PCRE1 releases, but PCRE2 should follow in due
-course.
+  http://www.cbttape.org
 
-You may also download PCRE1 from WWW.CBTTAPE.ORG, file 882. Everything, source
-and executable, is in EBCDIC and native z/OS file formats and this is the
-recommended download site.
+Everything in that location, source and executable, is in EBCDIC and native
+z/OS file formats. The port provides an API for LE languages such as COBOL and
+for the z/OS and z/VM versions of the Rexx languages.
 
-=============================
-Last Updated: 16 July 2015
+===============================
+Last Updated: 13 September 2017
+===============================
diff --git a/dist2/doc/html/README.txt b/dist2/doc/html/README.txt
index 03d67f6..52859a9 100644
--- a/dist2/doc/html/README.txt
+++ b/dist2/doc/html/README.txt
@@ -15,8 +15,8 @@
 
    https://lists.exim.org/mailman/listinfo/pcre-dev
 
-Please read the NEWS file if you are upgrading from a previous release.
-The contents of this README file are:
+Please read the NEWS file if you are upgrading from a previous release. The
+contents of this README file are:
 
   The PCRE2 APIs
   Documentation for PCRE2
@@ -44,8 +44,8 @@
 
 The distribution does contain a set of C wrapper functions for the 8-bit
 library that are based on the POSIX regular expression API (see the pcre2posix
-man page). These can be found in a library called libpcre2posix. Note that this
-just provides a POSIX calling interface to PCRE2; the regular expressions
+man page). These can be found in a library called libpcre2-posix. Note that
+this just provides a POSIX calling interface to PCRE2; the regular expressions
 themselves still follow Perl syntax and semantics. The POSIX API is restricted,
 and does not give full access to all of PCRE2's facilities.
 
@@ -58,8 +58,8 @@
 If you are using the POSIX interface to PCRE2 and there is already a POSIX
 regex library installed on your system, as well as worrying about the regex.h
 header file (as mentioned above), you must also take care when linking programs
-to ensure that they link with PCRE2's libpcre2posix library. Otherwise they may
-pick up the POSIX functions of the same name from the other library.
+to ensure that they link with PCRE2's libpcre2-posix library. Otherwise they
+may pick up the POSIX functions of the same name from the other library.
 
 One way of avoiding this confusion is to compile PCRE2 with the addition of
 -Dregcomp=PCRE2regcomp (and similarly for the other POSIX functions) to the
@@ -95,10 +95,9 @@
 Building PCRE2 on non-Unix-like systems
 ---------------------------------------
 
-For a non-Unix-like system, please read the comments in the file
-NON-AUTOTOOLS-BUILD, though if your system supports the use of "configure" and
-"make" you may be able to build PCRE2 using autotools in the same way as for
-many Unix-like systems.
+For a non-Unix-like system, please read the file NON-AUTOTOOLS-BUILD, though if
+your system supports the use of "configure" and "make" you may be able to build
+PCRE2 using autotools in the same way as for many Unix-like systems.
 
 PCRE2 can also be configured using CMake, which can be run in various ways
 (command line, GUI, etc). This creates Makefiles, solution files, etc. The file
@@ -172,21 +171,24 @@
   give large performance improvements on certain platforms, add --enable-jit to
   the "configure" command. This support is available only for certain hardware
   architectures. If you try to enable it on an unsupported architecture, there
-  will be a compile time error.
+  will be a compile time error. If you are running under SELinux you may also
+  want to add --enable-jit-sealloc, which enables the use of an execmem
+  allocator in JIT that is compatible with SELinux. This has no effect if JIT
+  is not enabled.
 
-. If you do not want to make use of the support for UTF-8 Unicode character
-  strings in the 8-bit library, UTF-16 Unicode character strings in the 16-bit
-  library, or UTF-32 Unicode character strings in the 32-bit library, you can
-  add --disable-unicode to the "configure" command. This reduces the size of
-  the libraries. It is not possible to configure one library with Unicode
-  support, and another without, in the same configuration.
+. If you do not want to make use of the default support for UTF-8 Unicode
+  character strings in the 8-bit library, UTF-16 Unicode character strings in
+  the 16-bit library, or UTF-32 Unicode character strings in the 32-bit
+  library, you can add --disable-unicode to the "configure" command. This
+  reduces the size of the libraries. It is not possible to configure one
+  library with Unicode support, and another without, in the same configuration.
+  It is also not possible to use --enable-ebcdic (see below) with Unicode
+  support, so if this option is set, you must also use --disable-unicode.
 
   When Unicode support is available, the use of a UTF encoding still has to be
   enabled by setting the PCRE2_UTF option at run time or starting a pattern
   with (*UTF). When PCRE2 is compiled with Unicode support, its input can only
-  either be ASCII or UTF-8/16/32, even when running on EBCDIC platforms. It is
-  not possible to use both --enable-unicode and --enable-ebcdic at the same
-  time.
+  either be ASCII or UTF-8/16/32, even when running on EBCDIC platforms.
 
   As well as supporting UTF strings, Unicode support includes support for the
   \P, \p, and \X sequences that recognize Unicode character properties.
@@ -196,20 +198,14 @@
   or starting a pattern with (*UCP).
 
 . You can build PCRE2 to recognize either CR or LF or the sequence CRLF, or any
-  of the preceding, or any of the Unicode newline sequences, as indicating the
-  end of a line. Whatever you specify at build time is the default; the caller
-  of PCRE2 can change the selection at run time. The default newline indicator
-  is a single LF character (the Unix standard). You can specify the default
-  newline indicator by adding --enable-newline-is-cr, --enable-newline-is-lf,
-  --enable-newline-is-crlf, --enable-newline-is-anycrlf, or
-  --enable-newline-is-any to the "configure" command, respectively.
-
-  If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of
-  the standard tests will fail, because the lines in the test files end with
-  LF. Even if the files are edited to change the line endings, there are likely
-  to be some failures. With --enable-newline-is-anycrlf or
-  --enable-newline-is-any, many tests should succeed, but there may be some
-  failures.
+  of the preceding, or any of the Unicode newline sequences, or the NUL (zero)
+  character as indicating the end of a line. Whatever you specify at build time
+  is the default; the caller of PCRE2 can change the selection at run time. The
+  default newline indicator is a single LF character (the Unix standard). You
+  can specify the default newline indicator by adding --enable-newline-is-cr,
+  --enable-newline-is-lf, --enable-newline-is-crlf,
+  --enable-newline-is-anycrlf, --enable-newline-is-any, or
+  --enable-newline-is-nul to the "configure" command, respectively.
 
 . By default, the sequence \R in a pattern matches any Unicode line ending
   sequence. This is independent of the option specifying what PCRE2 considers
@@ -231,49 +227,44 @@
 
   --with-parens-nest-limit=500
 
-. PCRE2 has a counter that can be set to limit the amount of resources it uses
-  when matching a pattern. If the limit is exceeded during a match, the match
-  fails. The default is ten million. You can change the default by setting, for
-  example,
+. PCRE2 has a counter that can be set to limit the amount of computing resource
+  it uses when matching a pattern. If the limit is exceeded during a match, the
+  match fails. The default is ten million. You can change the default by
+  setting, for example,
 
   --with-match-limit=500000
 
   on the "configure" command. This is just the default; individual calls to
-  pcre2_match() can supply their own value. There is more discussion on the
-  pcre2api man page.
+  pcre2_match() or pcre2_dfa_match() can supply their own value. There is more
+  discussion in the pcre2api man page (search for pcre2_set_match_limit).
 
-. There is a separate counter that limits the depth of recursive function calls
-  during a matching process. This also has a default of ten million, which is
-  essentially "unlimited". You can change the default by setting, for example,
+. There is a separate counter that limits the depth of nested backtracking
+  during a matching process, which indirectly limits the amount of heap memory
+  that is used. This also has a default of ten million, which is essentially
+  "unlimited". You can change the default by setting, for example,
 
-  --with-match-limit-recursion=500000
+  --with-match-limit-depth=5000
 
-  Recursive function calls use up the runtime stack; running out of stack can
-  cause programs to crash in strange ways. There is a discussion about stack
-  sizes in the pcre2stack man page.
+  There is more discussion in the pcre2api man page (search for
+  pcre2_set_depth_limit).
+
+. You can also set an explicit limit on the amount of heap memory used by
+  the pcre2_match() interpreter:
+
+  --with-heap-limit=500
+
+  The units are kilobytes. This limit does not apply when the JIT optimization
+  (which has its own memory control features) is used. There is more discussion
+  on the pcre2api man page (search for pcre2_set_heap_limit).
 
 . In the 8-bit library, the default maximum compiled pattern size is around
-  64K. You can increase this by adding --with-link-size=3 to the "configure"
-  command. PCRE2 then uses three bytes instead of two for offsets to different
-  parts of the compiled pattern. In the 16-bit library, --with-link-size=3 is
-  the same as --with-link-size=4, which (in both libraries) uses four-byte
-  offsets. Increasing the internal link size reduces performance in the 8-bit
-  and 16-bit libraries. In the 32-bit library, the link size setting is
-  ignored, as 4-byte offsets are always used.
-
-. You can build PCRE2 so that its internal match() function that is called from
-  pcre2_match() does not call itself recursively. Instead, it uses memory
-  blocks obtained from the heap to save data that would otherwise be saved on
-  the stack. To build PCRE2 like this, use
-
-  --disable-stack-for-recursion
-
-  on the "configure" command. PCRE2 runs more slowly in this mode, but it may
-  be necessary in environments with limited stack sizes. This applies only to
-  the normal execution of the pcre2_match() function; if JIT support is being
-  successfully used, it is not relevant. Equally, it does not apply to
-  pcre2_dfa_match(), which does not use deeply nested recursion. There is a
-  discussion about stack sizes in the pcre2stack man page.
+  64K bytes. You can increase this by adding --with-link-size=3 to the
+  "configure" command. PCRE2 then uses three bytes instead of two for offsets
+  to different parts of the compiled pattern. In the 16-bit library,
+  --with-link-size=3 is the same as --with-link-size=4, which (in both
+  libraries) uses four-byte offsets. Increasing the internal link size reduces
+  performance in the 8-bit and 16-bit libraries. In the 32-bit library, the
+  link size setting is ignored, as 4-byte offsets are always used.
 
 . For speed, PCRE2 uses four tables for manipulating and identifying characters
   whose code point values are less than 256. By default, it uses a set of
@@ -339,12 +330,23 @@
 
   Of course, the relevant libraries must be installed on your system.
 
-. The default size (in bytes) of the internal buffer used by pcre2grep can be
-  set by, for example:
+. The default starting size (in bytes) of the internal buffer used by pcre2grep
+  can be set by, for example:
 
   --with-pcre2grep-bufsize=51200
 
-  The value must be a plain integer. The default is 20480.
+  The value must be a plain integer. The default is 20480. The amount of memory
+  used by pcre2grep is actually three times this number, to allow for "before"
+  and "after" lines. If very long lines are encountered, the buffer is
+  automatically enlarged, up to a fixed maximum size.
+
+. The default maximum size of pcre2grep's internal buffer can be set by, for
+  example:
+
+  --with-pcre2grep-max-bufsize=2097152
+
+  The default is either 1048576 or the value of --with-pcre2grep-bufsize,
+  whichever is the larger.
 
 . It is possible to compile pcre2test so that it links with the libreadline
   or libedit libraries, by specifying, respectively,
@@ -369,6 +371,29 @@
   tgetflag, or tgoto, this is the problem, and linking with the ncurses library
   should fix it.
 
+. There is a special option called --enable-fuzz-support for use by people who
+  want to run fuzzing tests on PCRE2. At present this applies only to the 8-bit
+  library. If set, it causes an extra library called libpcre2-fuzzsupport.a to
+  be built, but not installed. This contains a single function called
+  LLVMFuzzerTestOneInput() whose arguments are a pointer to a string and the
+  length of the string. When called, this function tries to compile the string
+  as a pattern, and if that succeeds, to match it. This is done both with no
+  options and with some random options bits that are generated from the string.
+  Setting --enable-fuzz-support also causes a binary called pcre2fuzzcheck to
+  be created. This is normally run under valgrind or used when PCRE2 is
+  compiled with address sanitizing enabled. It calls the fuzzing function and
+  outputs information about it is doing. The input strings are specified by
+  arguments: if an argument starts with "=" the rest of it is a literal input
+  string. Otherwise, it is assumed to be a file name, and the contents of the
+  file are the test string.
+
+. Releases before 10.30 could be compiled with --disable-stack-for-recursion,
+  which caused pcre2_match() to use individual blocks on the heap for
+  backtracking instead of recursive function calls (which use the stack). This
+  is now obsolete since pcre2_match() was refactored always to use the heap (in
+  a much more efficient way than before). This option is retained for backwards
+  compatibility, but has no effect other than to output a warning.
+
 The "configure" script builds the following files for the basic C library:
 
 . Makefile             the makefile that builds the library
@@ -543,7 +568,7 @@
 
 
 Testing PCRE2
-------------
+-------------
 
 To test the basic PCRE2 library on a Unix-like system, run the RunTest script.
 There is another script called RunGrepTest that tests the pcre2grep command.
@@ -635,32 +660,43 @@
 Tests 6 and 7 check the pcre2_dfa_match() alternative matching function, in
 non-UTF mode and UTF-mode with Unicode property support, respectively.
 
-Test 8 checks some internal offsets and code size features; it is run only when
-the default "link size" of 2 is set (in other cases the sizes change) and when
-Unicode support is enabled.
+Test 8 checks some internal offsets and code size features, but it is run only
+when Unicode support is enabled. The output is different in 8-bit, 16-bit, and
+32-bit modes and for different link sizes, so there are different output files
+for each mode and link size.
 
 Tests 9 and 10 are run only in 8-bit mode, and tests 11 and 12 are run only in
 16-bit and 32-bit modes. These are tests that generate different output in
 8-bit mode. Each pair are for general cases and Unicode support, respectively.
+
 Test 13 checks the handling of non-UTF characters greater than 255 by
 pcre2_dfa_match() in 16-bit and 32-bit modes.
 
-Test 14 contains a number of tests that must not be run with JIT. They check,
+Test 14 contains some special UTF and UCP tests that give different output for
+different code unit widths.
+
+Test 15 contains a number of tests that must not be run with JIT. They check,
 among other non-JIT things, the match-limiting features of the intepretive
 matcher.
 
-Test 15 is run only when JIT support is not available. It checks that an
+Test 16 is run only when JIT support is not available. It checks that an
 attempt to use JIT has the expected behaviour.
 
-Test 16 is run only when JIT support is available. It checks JIT complete and
+Test 17 is run only when JIT support is available. It checks JIT complete and
 partial modes, match-limiting under JIT, and other JIT-specific features.
 
-Tests 17 and 18 are run only in 8-bit mode. They check the POSIX interface to
+Tests 18 and 19 are run only in 8-bit mode. They check the POSIX interface to
 the 8-bit library, without and with Unicode support, respectively.
 
-Test 19 checks the serialization functions by writing a set of compiled
+Test 20 checks the serialization functions by writing a set of compiled
 patterns to a file, and then reloading and checking them.
 
+Tests 21 and 22 test \C support when the use of \C is not locked out, without
+and with UTF support, respectively. Test 23 tests \C when it is locked out.
+
+Tests 24 and 25 test the experimental pattern conversion functions, without and
+with UTF support, respectively.
+
 
 Character tables
 ----------------
@@ -679,7 +715,7 @@
 by the program dftables (compiled from dftables.c), which uses the ANSI C
 character handling functions such as isalnum(), isalpha(), isupper(),
 islower(), etc. to build the table sources. This means that the default C
-locale which is set for your system will control the contents of these default
+locale that is set for your system will control the contents of these default
 tables. You can change the default tables by editing pcre2_chartables.c and
 then re-building PCRE2. If you do this, you should take care to ensure that the
 file does not get automatically re-generated. The best way to do this is to
@@ -734,8 +770,10 @@
   src/pcre2_compile.c      )
   src/pcre2_config.c       )
   src/pcre2_context.c      )
+  src/pcre2_convert.c      )
   src/pcre2_dfa_match.c    )
   src/pcre2_error.c        )
+  src/pcre2_extuni.c       )
   src/pcre2_find_bracket.c )
   src/pcre2_jit_compile.c  )
   src/pcre2_jit_match.c    ) sources for the functions in the library,
@@ -757,6 +795,7 @@
   src/pcre2_xclass.c       )
 
   src/pcre2_printint.c     debugging function that is used by pcre2test,
+  src/pcre2_fuzzsupport.c  function for (optional) fuzzing support
 
   src/config.h.in          template for config.h, when built by "configure"
   src/pcre2.h.in           template for pcre2.h when built by "configure"
@@ -772,7 +811,6 @@
   src/pcre2demo.c          simple demonstration of coding calls to PCRE2
   src/pcre2grep.c          source of a grep utility that uses PCRE2
   src/pcre2test.c          comprehensive test program
-  src/pcre2_printint.c     part of pcre2test
   src/pcre2_jit_test.c     JIT test program
 
 (C) Auxiliary files:
@@ -814,7 +852,7 @@
   libpcre2-8.pc.in         template for libpcre2-8.pc for pkg-config
   libpcre2-16.pc.in        template for libpcre2-16.pc for pkg-config
   libpcre2-32.pc.in        template for libpcre2-32.pc for pkg-config
-  libpcre2posix.pc.in      template for libpcre2posix.pc for pkg-config
+  libpcre2-posix.pc.in     template for libpcre2-posix.pc for pkg-config
   ltmain.sh                file used to build a libtool script
   missing                  ) common stub for a few missing GNU programs while
                            )   installing, generated by automake
@@ -837,12 +875,12 @@
 
 (E) Auxiliary files for building PCRE2 "by hand"
 
-  pcre2.h.generic         ) a version of the public PCRE2 header file
+  src/pcre2.h.generic     ) a version of the public PCRE2 header file
                           )   for use in non-"configure" environments
-  config.h.generic        ) a version of config.h for use in non-"configure"
+  src/config.h.generic    ) a version of config.h for use in non-"configure"
                           )   environments
 
 Philip Hazel
 Email local part: ph10
 Email domain: cam.ac.uk
-Last updated: 01 April 2016
+Last updated: 12 September 2017
diff --git a/dist2/doc/html/index.html b/dist2/doc/html/index.html
index 703c298..b9393d9 100644
--- a/dist2/doc/html/index.html
+++ b/dist2/doc/html/index.html
@@ -35,6 +35,9 @@
 <tr><td><a href="pcre2compat.html">pcre2compat</a></td>
     <td>&nbsp;&nbsp;Compability with Perl</td></tr>
 
+<tr><td><a href="pcre2convert.html">pcre2convert</a></td>
+    <td>&nbsp;&nbsp;Experimental foreign pattern conversion functions</td></tr>
+
 <tr><td><a href="pcre2demo.html">pcre2demo</a></td>
     <td>&nbsp;&nbsp;A demonstration C program that uses the PCRE2 library</td></tr>
 
@@ -68,9 +71,6 @@
 <tr><td><a href="pcre2serialize.html">pcre2serialize</a></td>
     <td>&nbsp;&nbsp;Serializing functions for saving precompiled patterns</td></tr>
 
-<tr><td><a href="pcre2stack.html">pcre2stack</a></td>
-    <td>&nbsp;&nbsp;Discussion of PCRE2's stack usage</td></tr>
-
 <tr><td><a href="pcre2syntax.html">pcre2syntax</a></td>
     <td>&nbsp;&nbsp;Syntax quick-reference summary</td></tr>
 
@@ -94,6 +94,9 @@
 <tr><td><a href="pcre2_code_copy.html">pcre2_code_copy</a></td>
     <td>&nbsp;&nbsp;Copy a compiled pattern</td></tr>
 
+<tr><td><a href="pcre2_code_copy_with_tables.html">pcre2_code_copy_with_tables</a></td>
+    <td>&nbsp;&nbsp;Copy a compiled pattern and its character tables</td></tr>
+
 <tr><td><a href="pcre2_code_free.html">pcre2_code_free</a></td>
     <td>&nbsp;&nbsp;Free a compiled pattern</td></tr>
 
@@ -112,6 +115,18 @@
 <tr><td><a href="pcre2_config.html">pcre2_config</a></td>
     <td>&nbsp;&nbsp;Show build-time configuration options</td></tr>
 
+<tr><td><a href="pcre2_convert_context_copy.html">pcre2_convert_context_copy</a></td>
+    <td>&nbsp;&nbsp;Copy a convert context</td></tr>
+
+<tr><td><a href="pcre2_convert_context_create.html">pcre2_convert_context_create</a></td>
+    <td>&nbsp;&nbsp;Create a convert context</td></tr>
+
+<tr><td><a href="pcre2_convert_context_free.html">pcre2_convert_context_free</a></td>
+    <td>&nbsp;&nbsp;Free a convert context</td></tr>
+
+<tr><td><a href="pcre2_converted_pattern_free.html">pcre2_converted_pattern_free</a></td>
+    <td>&nbsp;&nbsp;Free converted foreign pattern</td></tr>
+
 <tr><td><a href="pcre2_dfa_match.html">pcre2_dfa_match</a></td>
     <td>&nbsp;&nbsp;Match a compiled pattern to a subject string
     (DFA algorithm; <i>not</i> Perl compatible)</td></tr>
@@ -183,6 +198,9 @@
 <tr><td><a href="pcre2_match_data_free.html">pcre2_match_data_free</a></td>
     <td>&nbsp;&nbsp;Free a match data block</td></tr>
 
+<tr><td><a href="pcre2_pattern_convert.html">pcre2_pattern_convert</a></td>
+    <td>&nbsp;&nbsp;Experimental foreign pattern converter</td></tr>
+
 <tr><td><a href="pcre2_pattern_info.html">pcre2_pattern_info</a></td>
     <td>&nbsp;&nbsp;Extract information about a pattern</td></tr>
 
@@ -207,9 +225,24 @@
 <tr><td><a href="pcre2_set_character_tables.html">pcre2_set_character_tables</a></td>
     <td>&nbsp;&nbsp;Set character tables</td></tr>
 
+<tr><td><a href="pcre2_set_compile_extra_options.html">pcre2_set_compile_extra_options</a></td>
+    <td>&nbsp;&nbsp;Set compile time extra options</td></tr>
+
 <tr><td><a href="pcre2_set_compile_recursion_guard.html">pcre2_set_compile_recursion_guard</a></td>
     <td>&nbsp;&nbsp;Set up a compile recursion guard function</td></tr>
 
+<tr><td><a href="pcre2_set_depth_limit.html">pcre2_set_depth_limit</a></td>
+    <td>&nbsp;&nbsp;Set the match backtracking depth limit</td></tr>
+
+<tr><td><a href="pcre2_set_glob_escape.html">pcre2_set_glob_escape</a></td>
+    <td>&nbsp;&nbsp;Set glob escape character</td></tr>
+
+<tr><td><a href="pcre2_set_glob_separator.html">pcre2_set_glob_separator</a></td>
+    <td>&nbsp;&nbsp;Set glob separator character</td></tr>
+
+<tr><td><a href="pcre2_set_heap_limit.html">pcre2_set_heap_limit</a></td>
+    <td>&nbsp;&nbsp;Set the match backtracking heap limit</td></tr>
+
 <tr><td><a href="pcre2_set_match_limit.html">pcre2_set_match_limit</a></td>
     <td>&nbsp;&nbsp;Set the match limit</td></tr>
 
@@ -226,10 +259,10 @@
     <td>&nbsp;&nbsp;Set the parentheses nesting limit</td></tr>
 
 <tr><td><a href="pcre2_set_recursion_limit.html">pcre2_set_recursion_limit</a></td>
-    <td>&nbsp;&nbsp;Set the match recursion limit</td></tr>
+    <td>&nbsp;&nbsp;Obsolete: use pcre2_set_depth_limit</td></tr>
 
 <tr><td><a href="pcre2_set_recursion_memory_management.html">pcre2_set_recursion_memory_management</a></td>
-    <td>&nbsp;&nbsp;Set match recursion memory management</td></tr>
+    <td>&nbsp;&nbsp;Obsolete function that (from 10.30 onwards) does nothing</td></tr>
 
 <tr><td><a href="pcre2_substitute.html">pcre2_substitute</a></td>
     <td>&nbsp;&nbsp;Match a compiled pattern to a subject string and do
diff --git a/dist2/doc/html/pcre2.html b/dist2/doc/html/pcre2.html
index 07ab8e9..b61c579 100644
--- a/dist2/doc/html/pcre2.html
+++ b/dist2/doc/html/pcre2.html
@@ -109,7 +109,7 @@
 One way of guarding against this possibility is to use the
 <b>pcre2_pattern_info()</b> function to check the compiled pattern's options for
 PCRE2_UTF. Alternatively, you can set the PCRE2_NEVER_UTF option when calling
-<b>pcre2_compile()</b>. This causes an compile time error if a pattern contains
+<b>pcre2_compile()</b>. This causes a compile time error if the pattern contains
 a UTF-setting sequence.
 </P>
 <P>
@@ -137,7 +137,8 @@
 repeats in a pattern are a common example. PCRE2 provides some protection
 against this: see the <b>pcre2_set_match_limit()</b> function in the
 <a href="pcre2api.html"><b>pcre2api</b></a>
-page.
+page. There is a similar function called <b>pcre2_set_depth_limit()</b> that can
+be used to restrict the amount of memory that is used.
 </P>
 <br><a name="SEC3" href="#TOC1">USER DOCUMENTATION</a><br>
 <P>
@@ -166,7 +167,6 @@
   pcre2perform       discussion of performance issues
   pcre2posix         the POSIX-compatible C API for the 8-bit library
   pcre2sample        discussion of the pcre2demo program
-  pcre2stack         discussion of stack usage
   pcre2syntax        quick syntax reference
   pcre2test          description of the <b>pcre2test</b> command
   pcre2unicode       discussion of Unicode and UTF support
@@ -189,9 +189,9 @@
 </P>
 <br><a name="SEC5" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 16 October 2015
+Last updated: 01 April 2017
 <br>
-Copyright &copy; 1997-2015 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2_callout_enumerate.html b/dist2/doc/html/pcre2_callout_enumerate.html
index 6c2cdb8..505ea7b 100644
--- a/dist2/doc/html/pcre2_callout_enumerate.html
+++ b/dist2/doc/html/pcre2_callout_enumerate.html
@@ -36,20 +36,21 @@
   <i>callout_data</i>   User data that is passed to the callback
 </pre>
 The <i>callback()</i> function is passed a pointer to a data block containing
-the following fields:
+the following fields (not necessarily in this order):
 <pre>
-  <i>version</i>                Block version number
-  <i>pattern_position</i>       Offset to next item in pattern
-  <i>next_item_length</i>       Length of next item in pattern
-  <i>callout_number</i>         Number for numbered callouts
-  <i>callout_string_offset</i>  Offset to string within pattern
-  <i>callout_string_length</i>  Length of callout string
-  <i>callout_string</i>         Points to callout string or is NULL
+  uint32_t   <i>version</i>                Block version number
+  uint32_t   <i>callout_number</i>         Number for numbered callouts
+  PCRE2_SIZE <i>pattern_position</i>       Offset to next item in pattern
+  PCRE2_SIZE <i>next_item_length</i>       Length of next item in pattern
+  PCRE2_SIZE <i>callout_string_offset</i>  Offset to string within pattern
+  PCRE2_SIZE <i>callout_string_length</i>  Length of callout string
+  PCRE2_SPTR <i>callout_string</i>         Points to callout string or is NULL
 </pre>
-The second argument is the callout data that was passed to
-<b>pcre2_callout_enumerate()</b>. The <b>callback()</b> function must return zero
-for success. Any other value causes the pattern scan to stop, with the value
-being passed back as the result of <b>pcre2_callout_enumerate()</b>.
+The second argument passed to the <b>callback()</b> function is the callout data
+that was passed to <b>pcre2_callout_enumerate()</b>. The <b>callback()</b>
+function must return zero for success. Any other value causes the pattern scan
+to stop, with the value being passed back as the result of
+<b>pcre2_callout_enumerate()</b>.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_code_copy.html b/dist2/doc/html/pcre2_code_copy.html
index 5b68282..667d7b7 100644
--- a/dist2/doc/html/pcre2_code_copy.html
+++ b/dist2/doc/html/pcre2_code_copy.html
@@ -28,8 +28,9 @@
 This function makes a copy of the memory used for a compiled pattern, excluding
 any memory used by the JIT compiler. Without a subsequent call to
 <b>pcre2_jit_compile()</b>, the copy can be used only for non-JIT matching. The
-yield of the function is NULL if <i>code</i> is NULL or if sufficient memory
-cannot be obtained.
+pointer to the character tables is copied, not the tables themselves (see
+<b>pcre2_code_copy_with_tables()</b>). The yield of the function is NULL if
+<i>code</i> is NULL or if sufficient memory cannot be obtained.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_code_copy_with_tables.html b/dist2/doc/html/pcre2_code_copy_with_tables.html
new file mode 100644
index 0000000..67b2e1f
--- /dev/null
+++ b/dist2/doc/html/pcre2_code_copy_with_tables.html
@@ -0,0 +1,44 @@
+<html>
+<head>
+<title>pcre2_code_copy_with_tables specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_code_copy_with_tables man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *<i>code</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function makes a copy of the memory used for a compiled pattern, excluding
+any memory used by the JIT compiler. Without a subsequent call to
+<b>pcre2_jit_compile()</b>, the copy can be used only for non-JIT matching.
+Unlike <b>pcre2_code_copy()</b>, a separate copy of the character tables is also
+made, with the new code pointing to it. This memory will be automatically freed
+when <b>pcre2_code_free()</b> is called. The yield of the function is NULL if
+<i>code</i> is NULL or if sufficient memory cannot be obtained.
+</P>
+<P>
+There is a complete description of the PCRE2 native API in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+page and a description of the POSIX API in the
+<a href="pcre2posix.html"><b>pcre2posix</b></a>
+page.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_code_free.html b/dist2/doc/html/pcre2_code_free.html
index 0477abe..5fce3c5 100644
--- a/dist2/doc/html/pcre2_code_free.html
+++ b/dist2/doc/html/pcre2_code_free.html
@@ -26,7 +26,9 @@
 </b><br>
 <P>
 This function frees the memory used for a compiled pattern, including any
-memory used by the JIT compiler.
+memory used by the JIT compiler. If the compiled pattern was created by a call
+to <b>pcre2_code_copy_with_tables()</b>, the memory for the character tables is
+also freed.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_compile.html b/dist2/doc/html/pcre2_compile.html
index 544f4fe..0a9eafa 100644
--- a/dist2/doc/html/pcre2_compile.html
+++ b/dist2/doc/html/pcre2_compile.html
@@ -37,26 +37,34 @@
   <i>erroffset</i>     Where to put an error offset
   <i>ccontext</i>      Pointer to a compile context or NULL
 </pre>
-The length of the string and any error offset that is returned are in code
-units, not characters. A compile context is needed only if you want to change
+The length of the pattern and any error offset that is returned are in code
+units, not characters. A compile context is needed only if you want to provide
+custom memory allocation functions, or to provide an external function for
+system stack size checking, or to change one or more of these parameters:
 <pre>
-  What \R matches (Unicode newlines or CR, LF, CRLF only)
-  PCRE2's character tables
-  The newline character sequence
-  The compile time nested parentheses limit
+  What \R matches (Unicode newlines, or CR, LF, CRLF only);
+  PCRE2's character tables;
+  The newline character sequence;
+  The compile time nested parentheses limit;
+  The maximum pattern length (in code units) that is allowed.
+  The additional options bits (see pcre2_set_compile_extra_options())
 </pre>
-or provide an external function for stack size checking. The option bits are:
+The option bits are:
 <pre>
   PCRE2_ANCHORED           Force pattern anchoring
+  PCRE2_ALLOW_EMPTY_CLASS  Allow empty classes
   PCRE2_ALT_BSUX           Alternative handling of \u, \U, and \x
   PCRE2_ALT_CIRCUMFLEX     Alternative handling of ^ in multiline mode
+  PCRE2_ALT_VERBNAMES      Process backslashes in verb names
   PCRE2_AUTO_CALLOUT       Compile automatic callouts
   PCRE2_CASELESS           Do caseless matching
   PCRE2_DOLLAR_ENDONLY     $ not to match newline at end
   PCRE2_DOTALL             . matches anything including NL
   PCRE2_DUPNAMES           Allow duplicate names for subpatterns
+  PCRE2_ENDANCHORED        Pattern can match only at end of subject
   PCRE2_EXTENDED           Ignore white space and # comments
   PCRE2_FIRSTLINE          Force matching to be before newline
+  PCRE2_LITERAL            Pattern characters are all literal
   PCRE2_MATCH_UNSET_BACKREF  Match unset back references
   PCRE2_MULTILINE          ^ and $ match newlines within data
   PCRE2_NEVER_BACKSLASH_C  Lock out the use of \C in patterns
@@ -71,19 +79,21 @@
                              (only relevant if PCRE2_UTF is set)
   PCRE2_UCP                Use Unicode properties for \d, \w, etc.
   PCRE2_UNGREEDY           Invert greediness of quantifiers
+  PCRE2_USE_OFFSET_LIMIT   Enable offset limit for unanchored matching
   PCRE2_UTF                Treat pattern and subjects as UTF strings
 </pre>
-PCRE2 must be built with Unicode support in order to use PCRE2_UTF, PCRE2_UCP
-and related options.
+PCRE2 must be built with Unicode support (the default) in order to use
+PCRE2_UTF, PCRE2_UCP and related options.
 </P>
 <P>
 The yield of the function is a pointer to a private data structure that
 contains the compiled pattern, or NULL if an error was detected.
 </P>
 <P>
-There is a complete description of the PCRE2 native API in the
+There is a complete description of the PCRE2 native API, with more detail on
+each option, in the
 <a href="pcre2api.html"><b>pcre2api</b></a>
-page and a description of the POSIX API in the
+page, and a description of the POSIX API in the
 <a href="pcre2posix.html"><b>pcre2posix</b></a>
 page.
 <p>
diff --git a/dist2/doc/html/pcre2_config.html b/dist2/doc/html/pcre2_config.html
index a51b0c7..f05bd06 100644
--- a/dist2/doc/html/pcre2_config.html
+++ b/dist2/doc/html/pcre2_config.html
@@ -45,24 +45,25 @@
   PCRE2_CONFIG_BSR             Indicates what \R matches by default:
                                  PCRE2_BSR_UNICODE
                                  PCRE2_BSR_ANYCRLF
-  PCRE2_CONFIG_JIT             Availability of just-in-time compiler
-                                support (1=yes 0=no)
-  PCRE2_CONFIG_JITTARGET       Information about the target archi-
-                                 tecture for the JIT compiler
+  PCRE2_CONFIG_COMPILED_WIDTHS Which of 8/16/32 support was compiled
+  PCRE2_CONFIG_DEPTHLIMIT      Default backtracking depth limit
+  PCRE2_CONFIG_HEAPLIMIT       Default heap memory limit
+  PCRE2_CONFIG_JIT             Availability of just-in-time compiler support (1=yes 0=no)
+  PCRE2_CONFIG_JITTARGET       Information (a string) about the target architecture for the JIT compiler
   PCRE2_CONFIG_LINKSIZE        Configured internal link size (2, 3, 4)
   PCRE2_CONFIG_MATCHLIMIT      Default internal resource limit
+  PCRE2_CONFIG_NEVER_BACKSLASH_C  Whether or not \C is disabled
   PCRE2_CONFIG_NEWLINE         Code for the default newline sequence:
                                  PCRE2_NEWLINE_CR
                                  PCRE2_NEWLINE_LF
                                  PCRE2_NEWLINE_CRLF
                                  PCRE2_NEWLINE_ANY
                                  PCRE2_NEWLINE_ANYCRLF
+                                 PCRE2_NEWLINE_NUL
   PCRE2_CONFIG_PARENSLIMIT     Default parentheses nesting limit
-  PCRE2_CONFIG_RECURSIONLIMIT  Internal recursion depth limit
-  PCRE2_CONFIG_STACKRECURSE    Recursion implementation (1=stack
-                                 0=heap)
-  PCRE2_CONFIG_UNICODE         Availability of Unicode support (1=yes
-                                 0=no)
+  PCRE2_CONFIG_RECURSIONLIMIT  Obsolete: use PCRE2_CONFIG_DEPTHLIMIT
+  PCRE2_CONFIG_STACKRECURSE    Obsolete: always returns 0
+  PCRE2_CONFIG_UNICODE         Availability of Unicode support (1=yes 0=no)
   PCRE2_CONFIG_UNICODE_VERSION The Unicode version (a string)
   PCRE2_CONFIG_VERSION         The PCRE2 version (a string)
 </pre>
diff --git a/dist2/doc/html/pcre2_convert_context_copy.html b/dist2/doc/html/pcre2_convert_context_copy.html
new file mode 100644
index 0000000..3c44ac6
--- /dev/null
+++ b/dist2/doc/html/pcre2_convert_context_copy.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+<title>pcre2_convert_context_copy specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_convert_context_copy man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>pcre2_convert_context *pcre2_convert_context_copy(</b>
+<b>  pcre2_convert_context *<i>cvcontext</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function is part of an experimental set of pattern conversion functions.
+It makes a new copy of a convert context, using the memory allocation function
+that was used for the original context. The result is NULL if the memory cannot
+be obtained.
+</P>
+<P>
+The pattern conversion functions are described in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_convert_context_create.html b/dist2/doc/html/pcre2_convert_context_create.html
new file mode 100644
index 0000000..2564780
--- /dev/null
+++ b/dist2/doc/html/pcre2_convert_context_create.html
@@ -0,0 +1,41 @@
+<html>
+<head>
+<title>pcre2_convert_context_create specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_convert_context_create man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>pcre2_convert_context *pcre2_convert_context_create(</b>
+<b>  pcre2_general_context *<i>gcontext</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function is part of an experimental set of pattern conversion functions.
+It creates and initializes a new convert context. If its argument is
+NULL, <b>malloc()</b> is used to get the necessary memory; otherwise the memory
+allocation function within the general context is used. The result is NULL if
+the memory could not be obtained.
+</P>
+<P>
+The pattern conversion functions are described in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_convert_context_free.html b/dist2/doc/html/pcre2_convert_context_free.html
new file mode 100644
index 0000000..ab6db6c
--- /dev/null
+++ b/dist2/doc/html/pcre2_convert_context_free.html
@@ -0,0 +1,39 @@
+<html>
+<head>
+<title>pcre2_convert_context_free specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_convert_context_free man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>void pcre2_convert_context_free(pcre2_convert_context *<i>cvcontext</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function is part of an experimental set of pattern conversion functions.
+It frees the memory occupied by a convert context, using the memory
+freeing function from the general context with which it was created, or
+<b>free()</b> if that was not set.
+</P>
+<P>
+The pattern conversion functions are described in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_converted_pattern_free.html b/dist2/doc/html/pcre2_converted_pattern_free.html
new file mode 100644
index 0000000..11adefd
--- /dev/null
+++ b/dist2/doc/html/pcre2_converted_pattern_free.html
@@ -0,0 +1,39 @@
+<html>
+<head>
+<title>pcre2_converted_pattern_free specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_converted_pattern_free man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>void pcre2_converted_pattern_free(PCRE2_UCHAR *<i>converted_pattern</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function is part of an experimental set of pattern conversion functions.
+It frees the memory occupied by a converted pattern that was obtained by
+calling <b>pcre2_pattern_convert()</b> with arguments that caused it to place
+the converted pattern into newly obtained heap memory.
+</P>
+<P>
+The pattern conversion functions are described in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_dfa_match.html b/dist2/doc/html/pcre2_dfa_match.html
index e137a14..36d7976 100644
--- a/dist2/doc/html/pcre2_dfa_match.html
+++ b/dist2/doc/html/pcre2_dfa_match.html
@@ -31,8 +31,9 @@
 <P>
 This function matches a compiled regular expression against a given subject
 string, using an alternative matching algorithm that scans the subject string
-just once (<i>not</i> Perl-compatible). (The Perl-compatible matching function
-is <b>pcre2_match()</b>.) The arguments for this function are:
+just once (except when processing lookaround assertions). This function is
+<i>not</i> Perl-compatible (the Perl-compatible matching function is
+<b>pcre2_match()</b>). The arguments for this function are:
 <pre>
   <i>code</i>         Points to the compiled pattern
   <i>subject</i>      Points to the subject string
@@ -45,22 +46,20 @@
   <i>wscount</i>      Number of elements in the vector
 </pre>
 For <b>pcre2_dfa_match()</b>, a match context is needed only if you want to set
-up a callout function. The <i>length</i> and <i>startoffset</i> values are code
-units, not characters. The options are:
+up a callout function or specify the match and/or the recursion depth limits.
+The <i>length</i> and <i>startoffset</i> values are code units, not characters.
+The options are:
 <pre>
   PCRE2_ANCHORED          Match only at the first position
+  PCRE2_ENDANCHORED       Pattern can match only at end of subject
   PCRE2_NOTBOL            Subject is not the beginning of a line
   PCRE2_NOTEOL            Subject is not the end of a line
   PCRE2_NOTEMPTY          An empty string is not a valid match
-  PCRE2_NOTEMPTY_ATSTART  An empty string at the start of the subject
-                           is not a valid match
-  PCRE2_NO_UTF_CHECK      Do not check the subject for UTF
-                           validity (only relevant if PCRE2_UTF
+  PCRE2_NOTEMPTY_ATSTART  An empty string at the start of the subject is not a valid match
+  PCRE2_NO_UTF_CHECK      Do not check the subject for UTF validity (only relevant if PCRE2_UTF
                            was set at compile time)
-  PCRE2_PARTIAL_SOFT      Return PCRE2_ERROR_PARTIAL for a partial
-                            match if no full matches are found
-  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial match
-                           even if there is a full match as well
+  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial match even if there is a full match
+  PCRE2_PARTIAL_SOFT      Return PCRE2_ERROR_PARTIAL for a partial match if no full matches are found
   PCRE2_DFA_RESTART       Restart after a partial match
   PCRE2_DFA_SHORTEST      Return only the shortest match
 </pre>
diff --git a/dist2/doc/html/pcre2_get_error_message.html b/dist2/doc/html/pcre2_get_error_message.html
index 26c80fe..7005760 100644
--- a/dist2/doc/html/pcre2_get_error_message.html
+++ b/dist2/doc/html/pcre2_get_error_message.html
@@ -34,11 +34,11 @@
   <i>buffer</i>      where to put the message
   <i>bufflen</i>     the length of the buffer (code units)
 </pre>
-The function returns the length of the message, excluding the trailing zero, or
-the negative error code PCRE2_ERROR_NOMEMORY if the buffer is too small. In
-this case, the returned message is truncated (but still with a trailing zero).
-If <i>errorcode</i> does not contain a recognized error code number, the
-negative value PCRE2_ERROR_BADDATA is returned.
+The function returns the length of the message in code units, excluding the
+trailing zero, or the negative error code PCRE2_ERROR_NOMEMORY if the buffer is
+too small. In this case, the returned message is truncated (but still with a
+trailing zero). If <i>errorcode</i> does not contain a recognized error code
+number, the negative value PCRE2_ERROR_BADDATA is returned.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_get_mark.html b/dist2/doc/html/pcre2_get_mark.html
index f8e50e3..88e6326 100644
--- a/dist2/doc/html/pcre2_get_mark.html
+++ b/dist2/doc/html/pcre2_get_mark.html
@@ -26,11 +26,15 @@
 </b><br>
 <P>
 After a call of <b>pcre2_match()</b> that was passed the match block that is
-this function's argument, this function returns a pointer to the last (*MARK)
-name that was encountered. The name is zero-terminated, and is within the
-compiled pattern. If no (*MARK) name is available, NULL is returned. A (*MARK)
-name may be available after a failed match or a partial match, as well as after
-a successful one.
+this function's argument, this function returns a pointer to the last (*MARK),
+(*PRUNE), or (*THEN) name that was encountered during the matching process. The
+name is zero-terminated, and is within the compiled pattern. The length of the
+name is in the preceding code unit. If no name is available, NULL is returned.
+</P>
+<P>
+After a successful match, the name that is returned is the last one on the
+matching path. After a failed match or a partial match, the last encountered
+name is returned.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_jit_stack_create.html b/dist2/doc/html/pcre2_jit_stack_create.html
index a668e34..7c89c31 100644
--- a/dist2/doc/html/pcre2_jit_stack_create.html
+++ b/dist2/doc/html/pcre2_jit_stack_create.html
@@ -32,10 +32,9 @@
 context, for memory allocation functions, or NULL for standard memory
 allocation. The result can be passed to the JIT run-time code by calling
 <b>pcre2_jit_stack_assign()</b> to associate the stack with a compiled pattern,
-which can then be processed by <b>pcre2_match()</b>. If the "fast path" JIT
-matcher, <b>pcre2_jit_match()</b> is used, the stack can be passed directly as
-an argument. A maximum stack size of 512K to 1M should be more than enough for
-any pattern. For more details, see the
+which can then be processed by <b>pcre2_match()</b> or <b>pcre2_jit_match()</b>.
+A maximum stack size of 512K to 1M should be more than enough for any pattern.
+For more details, see the
 <a href="pcre2jit.html"><b>pcre2jit</b></a>
 page.
 </P>
diff --git a/dist2/doc/html/pcre2_maketables.html b/dist2/doc/html/pcre2_maketables.html
index 068e6d4..6d240e3 100644
--- a/dist2/doc/html/pcre2_maketables.html
+++ b/dist2/doc/html/pcre2_maketables.html
@@ -19,16 +19,16 @@
 <b>#include &#60;pcre2.h&#62;</b>
 </P>
 <P>
-<b>const unsigned char *pcre2_maketables(pcre22_general_context *<i>gcontext</i>);</b>
+<b>const unsigned char *pcre2_maketables(pcre2_general_context *<i>gcontext</i>);</b>
 </P>
 <br><b>
 DESCRIPTION
 </b><br>
 <P>
-This function builds a set of character tables for character values less than
-256. These can be passed to <b>pcre2_compile()</b> in a compile context in order
-to override the internal, built-in tables (which were either defaulted or made
-by <b>pcre2_maketables()</b> when PCRE2 was compiled). See the
+This function builds a set of character tables for character code points that
+are less than 256. These can be passed to <b>pcre2_compile()</b> in a compile
+context in order to override the internal, built-in tables (which were either
+defaulted or made by <b>pcre2_maketables()</b> when PCRE2 was compiled). See the
 <a href="pcre2_set_character_tables.html"><b>pcre2_set_character_tables()</b></a>
 page. You might want to do this if you are using a non-standard locale.
 </P>
diff --git a/dist2/doc/html/pcre2_match.html b/dist2/doc/html/pcre2_match.html
index 0e389eb..ced70bb 100644
--- a/dist2/doc/html/pcre2_match.html
+++ b/dist2/doc/html/pcre2_match.html
@@ -30,7 +30,13 @@
 <P>
 This function matches a compiled regular expression against a given subject
 string, using a matching algorithm that is similar to Perl's. It returns
-offsets to captured substrings. Its arguments are:
+offsets to what it has matched and to captured substrings via the
+<b>match_data</b> block, which can be processed by functions with names that
+start with <b>pcre2_get_ovector_...()</b> or <b>pcre2_substring_...()</b>. The
+return from <b>pcre2_match()</b> is one more than the highest numbered capturing
+pair that has been set (for example, 1 if there are no captures), zero if the
+vector of offsets is too small, or a negative error code for no match and other
+errors. The function arguments are:
 <pre>
   <i>code</i>         Points to the compiled pattern
   <i>subject</i>      Points to the subject string
@@ -43,26 +49,27 @@
 A match context is needed only if you want to:
 <pre>
   Set up a callout function
-  Change the limit for calling the internal function <i>match()</i>
-  Change the limit for calling <i>match()</i> recursively
-  Set custom memory management when the heap is used for recursion
+  Set a matching offset limit
+  Change the heap memory limit
+  Change the backtracking match limit
+  Change the backtracking depth limit
+  Set custom memory management specifically for the match
 </pre>
 The <i>length</i> and <i>startoffset</i> values are code
-units, not characters. The options are:
+units, not characters. The length may be given as PCRE2_ZERO_TERMINATE for a
+subject that is terminated by a binary zero code unit. The options are:
 <pre>
   PCRE2_ANCHORED          Match only at the first position
+  PCRE2_ENDANCHORED       Pattern can match only at end of subject
   PCRE2_NOTBOL            Subject string is not the beginning of a line
   PCRE2_NOTEOL            Subject string is not the end of a line
   PCRE2_NOTEMPTY          An empty string is not a valid match
-  PCRE2_NOTEMPTY_ATSTART  An empty string at the start of the subject
-                           is not a valid match
-  PCRE2_NO_UTF_CHECK      Do not check the subject for UTF
-                           validity (only relevant if PCRE2_UTF
+  PCRE2_NOTEMPTY_ATSTART  An empty string at the start of the subject is not a valid match
+  PCRE2_NO_JIT            Do not use JIT matching
+  PCRE2_NO_UTF_CHECK      Do not check the subject for UTF validity (only relevant if PCRE2_UTF
                            was set at compile time)
-  PCRE2_PARTIAL_SOFT      Return PCRE2_ERROR_PARTIAL for a partial
-                            match if no full matches are found
-  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial match
-                           if that is found before a full match
+  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial match even if there is a full match
+  PCRE2_PARTIAL_SOFT      Return PCRE2_ERROR_PARTIAL for a partial match if no full matches are found
 </pre>
 For details of partial matching, see the
 <a href="pcre2partial.html"><b>pcre2partial</b></a>
diff --git a/dist2/doc/html/pcre2_match_data_free.html b/dist2/doc/html/pcre2_match_data_free.html
index 70e107e..840067f 100644
--- a/dist2/doc/html/pcre2_match_data_free.html
+++ b/dist2/doc/html/pcre2_match_data_free.html
@@ -26,8 +26,8 @@
 </b><br>
 <P>
 This function frees the memory occupied by a match data block, using the memory
-freeing function from the general context with which it was created, or
-<b>free()</b> if that was not set.
+freeing function from the general context or compiled pattern with which it was
+created, or <b>free()</b> if that was not set.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_pattern_convert.html b/dist2/doc/html/pcre2_pattern_convert.html
new file mode 100644
index 0000000..2fcd7cc
--- /dev/null
+++ b/dist2/doc/html/pcre2_pattern_convert.html
@@ -0,0 +1,70 @@
+<html>
+<head>
+<title>pcre2_pattern_convert specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_pattern_convert man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_pattern_convert(PCRE2_SPTR <i>pattern</i>, PCRE2_SIZE <i>length</i>,</b>
+<b>  uint32_t <i>options</i>, PCRE2_UCHAR **<i>buffer</i>,</b>
+<b>  PCRE2_SIZE *<i>blength</i>, pcre2_convert_context *<i>cvcontext</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function is part of an experimental set of pattern conversion functions.
+It converts a foreign pattern (for example, a glob) into a PCRE2 regular
+expression pattern. Its arguments are:
+<pre>
+  <i>pattern</i>     The foreign pattern
+  <i>length</i>      The length of the input pattern or PCRE2_ZERO_TERMINATED
+  <i>options</i>     Option bits
+  <i>buffer</i>      Pointer to pointer to output buffer, or NULL
+  <i>blength</i>     Pointer to output length field
+  <i>cvcontext</i>   Pointer to a convert context or NULL
+</pre>
+The length of the converted pattern (excluding the terminating zero) is
+returned via <i>blength</i>. If <i>buffer</i> is NULL, the function just returns
+the output length. If <i>buffer</i> points to a NULL pointer, heap memory is
+obtained for the converted pattern, using the allocator in the context if
+present (or else <b>malloc()</b>), and the field pointed to by <i>buffer</i> is
+updated. If <i>buffer</i> points to a non-NULL field, that must point to a
+buffer whose size is in the variable pointed to by <i>blength</i>. This value is
+updated.
+</P>
+<P>
+The option bits are:
+<pre>
+  PCRE2_CONVERT_UTF                     Input is UTF
+  PCRE2_CONVERT_NO_UTF_CHECK            Do not check UTF validity
+  PCRE2_CONVERT_POSIX_BASIC             Convert POSIX basic pattern
+  PCRE2_CONVERT_POSIX_EXTENDED          Convert POSIX extended pattern
+  PCRE2_CONVERT_GLOB                    ) Convert
+  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR  )   various types
+  PCRE2_CONVERT_GLOB_NO_STARSTAR        )     of glob
+</pre>
+The return value from <b>pcre2_pattern_convert()</b> is zero on success or a
+non-zero PCRE2 error code.
+</P>
+<P>
+The pattern conversion functions are described in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_pattern_info.html b/dist2/doc/html/pcre2_pattern_info.html
index b4cd6f5..1ebf90b 100644
--- a/dist2/doc/html/pcre2_pattern_info.html
+++ b/dist2/doc/html/pcre2_pattern_info.html
@@ -27,7 +27,7 @@
 <P>
 This function returns information about a compiled pattern. Its arguments are:
 <pre>
-  <i>code</i>     Pointer to a compiled regular expression
+  <i>code</i>     Pointer to a compiled regular expression pattern
   <i>what</i>     What information is required
   <i>where</i>    Where to put the information
 </pre>
@@ -41,27 +41,28 @@
                                PCRE2_BSR_UNICODE: Unicode line endings
                                PCRE2_BSR_ANYCRLF: CR, LF, or CRLF only
   PCRE2_INFO_CAPTURECOUNT    Number of capturing subpatterns
+  PCRE2_INFO_DEPTHLIMIT      Backtracking depth limit if set, otherwise PCRE2_ERROR_UNSET
+  PCRE2_INFO_EXTRAOPTIONS    Extra options that were passed in the
+                               compile context
   PCRE2_INFO_FIRSTBITMAP     Bitmap of first code units, or NULL
   PCRE2_INFO_FIRSTCODETYPE   Type of start-of-match information
                                0 nothing set
                                1 first code unit is set
                                2 start of string or after newline
   PCRE2_INFO_FIRSTCODEUNIT   First code unit when type is 1
+  PCRE2_INFO_FRAMESIZE       Size of backtracking frame
   PCRE2_INFO_HASBACKSLASHC   Return 1 if pattern contains \C
-  PCRE2_INFO_HASCRORLF       Return 1 if explicit CR or LF matches
-                               exist in the pattern
+  PCRE2_INFO_HASCRORLF       Return 1 if explicit CR or LF matches exist in the pattern
+  PCRE2_INFO_HEAPLIMIT       Heap memory limit if set, otherwise PCRE2_ERROR_UNSET
   PCRE2_INFO_JCHANGED        Return 1 if (?J) or (?-J) was used
   PCRE2_INFO_JITSIZE         Size of JIT compiled code, or 0
   PCRE2_INFO_LASTCODETYPE    Type of must-be-present information
                                0 nothing set
                                1 code unit is set
   PCRE2_INFO_LASTCODEUNIT    Last code unit when type is 1
-  PCRE2_INFO_MATCHEMPTY      1 if the pattern can match an
-                               empty string, 0 otherwise
-  PCRE2_INFO_MATCHLIMIT      Match limit if set,
-                               otherwise PCRE2_ERROR_UNSET
-  PCRE2_INFO_MAXLOOKBEHIND   Length (in characters) of the longest
-                               lookbehind assertion
+  PCRE2_INFO_MATCHEMPTY      1 if the pattern can match an empty string, 0 otherwise
+  PCRE2_INFO_MATCHLIMIT      Match limit if set, otherwise PCRE2_ERROR_UNSET
+  PCRE2_INFO_MAXLOOKBEHIND   Length (in characters) of the longest lookbehind assertion
   PCRE2_INFO_MINLENGTH       Lower bound length of matching strings
   PCRE2_INFO_NAMECOUNT       Number of named subpatterns
   PCRE2_INFO_NAMEENTRYSIZE   Size of name table entries
@@ -72,8 +73,8 @@
                                PCRE2_NEWLINE_CRLF
                                PCRE2_NEWLINE_ANY
                                PCRE2_NEWLINE_ANYCRLF
-  PCRE2_INFO_RECURSIONLIMIT  Recursion limit if set,
-                               otherwise PCRE2_ERROR_UNSET
+                               PCRE2_NEWLINE_NUL
+  PCRE2_INFO_RECURSIONLIMIT  Obsolete synonym for PCRE2_INFO_DEPTHLIMIT
   PCRE2_INFO_SIZE            Size of compiled pattern
 </pre>
 If <i>where</i> is NULL, the function returns the amount of memory needed for
diff --git a/dist2/doc/html/pcre2_set_callout.html b/dist2/doc/html/pcre2_set_callout.html
index 635e0c2..4e7aca6 100644
--- a/dist2/doc/html/pcre2_set_callout.html
+++ b/dist2/doc/html/pcre2_set_callout.html
@@ -29,7 +29,7 @@
 <P>
 This function sets the callout fields in a match context (the first argument).
 The second argument specifies a callout function, and the third argument is an
-opaque data time that is passed to it. The result of this function is always
+opaque data item that is passed to it. The result of this function is always
 zero.
 </P>
 <P>
diff --git a/dist2/doc/html/pcre2_set_compile_extra_options.html b/dist2/doc/html/pcre2_set_compile_extra_options.html
new file mode 100644
index 0000000..7374931
--- /dev/null
+++ b/dist2/doc/html/pcre2_set_compile_extra_options.html
@@ -0,0 +1,45 @@
+<html>
+<head>
+<title>pcre2_set_compile_extra_options specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_set_compile_extra_options man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_set_compile_extra_options(pcre2_compile_context *<i>ccontext</i>,</b>
+<b>  PCRE2_SIZE <i>extra_options</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function sets additional option bits for <b>pcre2_compile()</b> that are
+housed in a compile context. It completely replaces all the bits. The extra
+options are:
+<pre>
+  PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES  Allow \x{df800} to \x{dfff} in UTF-8 and UTF-32 modes
+  PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL    Treat all invalid escapes as a literal following character
+  PCRE2_EXTRA_MATCH_LINE               Pattern matches whole lines
+  PCRE2_EXTRA_MATCH_WORD               Pattern matches "words"
+</pre>
+There is a complete description of the PCRE2 native API in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+page and a description of the POSIX API in the
+<a href="pcre2posix.html"><b>pcre2posix</b></a>
+page.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_set_depth_limit.html b/dist2/doc/html/pcre2_set_depth_limit.html
new file mode 100644
index 0000000..a1cf706
--- /dev/null
+++ b/dist2/doc/html/pcre2_set_depth_limit.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+<title>pcre2_set_depth_limit specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_set_depth_limit man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_set_depth_limit(pcre2_match_context *<i>mcontext</i>,</b>
+<b>  uint32_t <i>value</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function sets the backtracking depth limit field in a match context. The
+result is always zero.
+</P>
+<P>
+There is a complete description of the PCRE2 native API in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+page and a description of the POSIX API in the
+<a href="pcre2posix.html"><b>pcre2posix</b></a>
+page.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_set_glob_escape.html b/dist2/doc/html/pcre2_set_glob_escape.html
new file mode 100644
index 0000000..2b55627
--- /dev/null
+++ b/dist2/doc/html/pcre2_set_glob_escape.html
@@ -0,0 +1,43 @@
+<html>
+<head>
+<title>pcre2_set_glob_escape specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_set_glob_escape man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_set_glob_escape(pcre2_convert_context *<i>cvcontext</i>,</b>
+<b>  uint32_t <i>escape_char</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function is part of an experimental set of pattern conversion functions.
+It sets the escape character that is used when converting globs. The second
+argument must either be zero (meaning there is no escape character) or a
+punctuation character whose code point is less than 256. The default is grave
+accent if running under Windows, otherwise backslash. The result of the
+function is zero for success or PCRE2_ERROR_BADDATA if the second argument is
+invalid.
+</P>
+<P>
+The pattern conversion functions are described in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_set_glob_separator.html b/dist2/doc/html/pcre2_set_glob_separator.html
new file mode 100644
index 0000000..538748d
--- /dev/null
+++ b/dist2/doc/html/pcre2_set_glob_separator.html
@@ -0,0 +1,42 @@
+<html>
+<head>
+<title>pcre2_set_glob_separator specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_set_glob_separator man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_set_glob_separator(pcre2_convert_context *<i>cvcontext</i>,</b>
+<b>  uint32_t <i>separator_char</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function is part of an experimental set of pattern conversion functions.
+It sets the component separator character that is used when converting globs.
+The second argument must one of the characters forward slash, backslash, or
+dot. The default is backslash when running under Windows, otherwise forward
+slash. The result of the function is zero for success or PCRE2_ERROR_BADDATA if
+the second argument is invalid.
+</P>
+<P>
+The pattern conversion functions are described in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_set_heap_limit.html b/dist2/doc/html/pcre2_set_heap_limit.html
new file mode 100644
index 0000000..3631ef6
--- /dev/null
+++ b/dist2/doc/html/pcre2_set_heap_limit.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+<title>pcre2_set_heap_limit specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_set_heap_limit man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_set_heap_limit(pcre2_match_context *<i>mcontext</i>,</b>
+<b>  uint32_t <i>value</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function sets the backtracking heap limit field in a match context. The
+result is always zero.
+</P>
+<P>
+There is a complete description of the PCRE2 native API in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+page and a description of the POSIX API in the
+<a href="pcre2posix.html"><b>pcre2posix</b></a>
+page.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_set_max_pattern_length.html b/dist2/doc/html/pcre2_set_max_pattern_length.html
new file mode 100644
index 0000000..f6e422a
--- /dev/null
+++ b/dist2/doc/html/pcre2_set_max_pattern_length.html
@@ -0,0 +1,43 @@
+<html>
+<head>
+<title>pcre2_set_max_pattern_length specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_set_max_pattern_length man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_set_max_pattern_length(pcre2_compile_context *<i>ccontext</i>,</b>
+<b>  PCRE2_SIZE <i>value</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function sets, in a compile context, the maximum text length (in code
+units) of the pattern that can be compiled. The result is always zero. If a
+longer pattern is passed to <b>pcre2_compile()</b> there is an immediate error
+return. The default is effectively unlimited, being the largest value a
+PCRE2_SIZE variable can hold.
+</P>
+<P>
+There is a complete description of the PCRE2 native API in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+page and a description of the POSIX API in the
+<a href="pcre2posix.html"><b>pcre2posix</b></a>
+page.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2_set_newline.html b/dist2/doc/html/pcre2_set_newline.html
index ae6332a..ba81300 100644
--- a/dist2/doc/html/pcre2_set_newline.html
+++ b/dist2/doc/html/pcre2_set_newline.html
@@ -35,6 +35,7 @@
   PCRE2_NEWLINE_CRLF      CR followed by LF only
   PCRE2_NEWLINE_ANYCRLF   Any of the above
   PCRE2_NEWLINE_ANY       Any Unicode newline sequence
+  PCRE2_NEWLINE_NUL       The NUL character (binary zero)
 </pre>
 The result is zero for success or PCRE2_ERROR_BADDATA if the second argument is
 invalid.
diff --git a/dist2/doc/html/pcre2_set_recursion_limit.html b/dist2/doc/html/pcre2_set_recursion_limit.html
index 5adcc99..9ff68c2 100644
--- a/dist2/doc/html/pcre2_set_recursion_limit.html
+++ b/dist2/doc/html/pcre2_set_recursion_limit.html
@@ -26,8 +26,8 @@
 DESCRIPTION
 </b><br>
 <P>
-This function sets the recursion limit field in a match context. The result is
-always zero.
+This function is obsolete and should not be used in new code. Use
+<b>pcre2_set_depth_limit()</b> instead.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_set_recursion_memory_management.html b/dist2/doc/html/pcre2_set_recursion_memory_management.html
index ec18947..1e057b9 100644
--- a/dist2/doc/html/pcre2_set_recursion_memory_management.html
+++ b/dist2/doc/html/pcre2_set_recursion_memory_management.html
@@ -28,13 +28,8 @@
 DESCRIPTION
 </b><br>
 <P>
-This function sets the match context fields for custom memory management when
-PCRE2 is compiled to use the heap instead of the system stack for recursive
-function calls while matching. When PCRE2 is compiled to use the stack (the
-default) this function does nothing. The first argument is a match context, the
-second and third specify the memory allocation and freeing functions, and the
-final argument is an opaque value that is passed to them whenever they are
-called. The result of this function is always zero.
+From release 10.30 onwards, this function is obsolete and does nothing. The
+result is always zero.
 </P>
 <P>
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/html/pcre2_substitute.html b/dist2/doc/html/pcre2_substitute.html
index 2dfd094..2215ce9 100644
--- a/dist2/doc/html/pcre2_substitute.html
+++ b/dist2/doc/html/pcre2_substitute.html
@@ -47,26 +47,30 @@
   <i>outputbuffer</i>  Points to the output buffer
   <i>outlengthptr</i>  Points to the length of the output buffer
 </pre>
-A match context is needed only if you want to:
+A match data block is needed only if you want to inspect the data from the
+match that is returned in that block. A match context is needed only if you
+want to:
 <pre>
   Set up a callout function
-  Change the limit for calling the internal function <i>match()</i>
-  Change the limit for calling <i>match()</i> recursively
-  Set custom memory management when the heap is used for recursion
+  Set a matching offset limit
+  Change the backtracking match limit
+  Change the backtracking depth limit
+  Set custom memory management in the match context
 </pre>
 The <i>length</i>, <i>startoffset</i> and <i>rlength</i> values are code
 units, not characters, as is the contents of the variable pointed at by
 <i>outlengthptr</i>, which is updated to the actual length of the new string.
-The options are:
+The subject and replacement lengths can be given as PCRE2_ZERO_TERMINATED for
+zero-terminated strings. The options are:
 <pre>
   PCRE2_ANCHORED             Match only at the first position
+  PCRE2_ENDANCHORED          Pattern can match only at end of subject
   PCRE2_NOTBOL               Subject is not the beginning of a line
   PCRE2_NOTEOL               Subject is not the end of a line
   PCRE2_NOTEMPTY             An empty string is not a valid match
-  PCRE2_NOTEMPTY_ATSTART     An empty string at the start of the
-                              subject is not a valid match
-  PCRE2_NO_UTF_CHECK         Do not check the subject or replacement
-                              for UTF validity (only relevant if
+  PCRE2_NOTEMPTY_ATSTART     An empty string at the start of the subject is not a valid match
+  PCRE2_NO_JIT               Do not use JIT matching
+  PCRE2_NO_UTF_CHECK         Do not check the subject or replacement for UTF validity (only relevant if
                               PCRE2_UTF was set at compile time)
   PCRE2_SUBSTITUTE_EXTENDED  Do extended replacement processing
   PCRE2_SUBSTITUTE_GLOBAL    Replace all occurrences in the subject
diff --git a/dist2/doc/html/pcre2api.html b/dist2/doc/html/pcre2api.html
index fa9f342..ba3b2ca 100644
--- a/dist2/doc/html/pcre2api.html
+++ b/dist2/doc/html/pcre2api.html
@@ -23,44 +23,45 @@
 <li><a name="TOC8" href="#SEC8">PCRE2 NATIVE API JIT FUNCTIONS</a>
 <li><a name="TOC9" href="#SEC9">PCRE2 NATIVE API SERIALIZATION FUNCTIONS</a>
 <li><a name="TOC10" href="#SEC10">PCRE2 NATIVE API AUXILIARY FUNCTIONS</a>
-<li><a name="TOC11" href="#SEC11">PCRE2 8-BIT, 16-BIT, AND 32-BIT LIBRARIES</a>
-<li><a name="TOC12" href="#SEC12">PCRE2 API OVERVIEW</a>
-<li><a name="TOC13" href="#SEC13">STRING LENGTHS AND OFFSETS</a>
-<li><a name="TOC14" href="#SEC14">NEWLINES</a>
-<li><a name="TOC15" href="#SEC15">MULTITHREADING</a>
-<li><a name="TOC16" href="#SEC16">PCRE2 CONTEXTS</a>
-<li><a name="TOC17" href="#SEC17">CHECKING BUILD-TIME OPTIONS</a>
-<li><a name="TOC18" href="#SEC18">COMPILING A PATTERN</a>
-<li><a name="TOC19" href="#SEC19">COMPILATION ERROR CODES</a>
-<li><a name="TOC20" href="#SEC20">JUST-IN-TIME (JIT) COMPILATION</a>
-<li><a name="TOC21" href="#SEC21">LOCALE SUPPORT</a>
-<li><a name="TOC22" href="#SEC22">INFORMATION ABOUT A COMPILED PATTERN</a>
-<li><a name="TOC23" href="#SEC23">INFORMATION ABOUT A PATTERN'S CALLOUTS</a>
-<li><a name="TOC24" href="#SEC24">SERIALIZATION AND PRECOMPILING</a>
-<li><a name="TOC25" href="#SEC25">THE MATCH DATA BLOCK</a>
-<li><a name="TOC26" href="#SEC26">MATCHING A PATTERN: THE TRADITIONAL FUNCTION</a>
-<li><a name="TOC27" href="#SEC27">NEWLINE HANDLING WHEN MATCHING</a>
-<li><a name="TOC28" href="#SEC28">HOW PCRE2_MATCH() RETURNS A STRING AND CAPTURED SUBSTRINGS</a>
-<li><a name="TOC29" href="#SEC29">OTHER INFORMATION ABOUT A MATCH</a>
-<li><a name="TOC30" href="#SEC30">ERROR RETURNS FROM <b>pcre2_match()</b></a>
-<li><a name="TOC31" href="#SEC31">OBTAINING A TEXTUAL ERROR MESSAGE</a>
-<li><a name="TOC32" href="#SEC32">EXTRACTING CAPTURED SUBSTRINGS BY NUMBER</a>
-<li><a name="TOC33" href="#SEC33">EXTRACTING A LIST OF ALL CAPTURED SUBSTRINGS</a>
-<li><a name="TOC34" href="#SEC34">EXTRACTING CAPTURED SUBSTRINGS BY NAME</a>
-<li><a name="TOC35" href="#SEC35">CREATING A NEW STRING WITH SUBSTITUTIONS</a>
-<li><a name="TOC36" href="#SEC36">DUPLICATE SUBPATTERN NAMES</a>
-<li><a name="TOC37" href="#SEC37">FINDING ALL POSSIBLE MATCHES AT ONE POSITION</a>
-<li><a name="TOC38" href="#SEC38">MATCHING A PATTERN: THE ALTERNATIVE FUNCTION</a>
-<li><a name="TOC39" href="#SEC39">SEE ALSO</a>
-<li><a name="TOC40" href="#SEC40">AUTHOR</a>
-<li><a name="TOC41" href="#SEC41">REVISION</a>
+<li><a name="TOC11" href="#SEC11">PCRE2 NATIVE API OBSOLETE FUNCTIONS</a>
+<li><a name="TOC12" href="#SEC12">PCRE2 EXPERIMENTAL PATTERN CONVERSION FUNCTIONS</a>
+<li><a name="TOC13" href="#SEC13">PCRE2 8-BIT, 16-BIT, AND 32-BIT LIBRARIES</a>
+<li><a name="TOC14" href="#SEC14">PCRE2 API OVERVIEW</a>
+<li><a name="TOC15" href="#SEC15">STRING LENGTHS AND OFFSETS</a>
+<li><a name="TOC16" href="#SEC16">NEWLINES</a>
+<li><a name="TOC17" href="#SEC17">MULTITHREADING</a>
+<li><a name="TOC18" href="#SEC18">PCRE2 CONTEXTS</a>
+<li><a name="TOC19" href="#SEC19">CHECKING BUILD-TIME OPTIONS</a>
+<li><a name="TOC20" href="#SEC20">COMPILING A PATTERN</a>
+<li><a name="TOC21" href="#SEC21">JUST-IN-TIME (JIT) COMPILATION</a>
+<li><a name="TOC22" href="#SEC22">LOCALE SUPPORT</a>
+<li><a name="TOC23" href="#SEC23">INFORMATION ABOUT A COMPILED PATTERN</a>
+<li><a name="TOC24" href="#SEC24">INFORMATION ABOUT A PATTERN'S CALLOUTS</a>
+<li><a name="TOC25" href="#SEC25">SERIALIZATION AND PRECOMPILING</a>
+<li><a name="TOC26" href="#SEC26">THE MATCH DATA BLOCK</a>
+<li><a name="TOC27" href="#SEC27">MATCHING A PATTERN: THE TRADITIONAL FUNCTION</a>
+<li><a name="TOC28" href="#SEC28">NEWLINE HANDLING WHEN MATCHING</a>
+<li><a name="TOC29" href="#SEC29">HOW PCRE2_MATCH() RETURNS A STRING AND CAPTURED SUBSTRINGS</a>
+<li><a name="TOC30" href="#SEC30">OTHER INFORMATION ABOUT A MATCH</a>
+<li><a name="TOC31" href="#SEC31">ERROR RETURNS FROM <b>pcre2_match()</b></a>
+<li><a name="TOC32" href="#SEC32">OBTAINING A TEXTUAL ERROR MESSAGE</a>
+<li><a name="TOC33" href="#SEC33">EXTRACTING CAPTURED SUBSTRINGS BY NUMBER</a>
+<li><a name="TOC34" href="#SEC34">EXTRACTING A LIST OF ALL CAPTURED SUBSTRINGS</a>
+<li><a name="TOC35" href="#SEC35">EXTRACTING CAPTURED SUBSTRINGS BY NAME</a>
+<li><a name="TOC36" href="#SEC36">CREATING A NEW STRING WITH SUBSTITUTIONS</a>
+<li><a name="TOC37" href="#SEC37">DUPLICATE SUBPATTERN NAMES</a>
+<li><a name="TOC38" href="#SEC38">FINDING ALL POSSIBLE MATCHES AT ONE POSITION</a>
+<li><a name="TOC39" href="#SEC39">MATCHING A PATTERN: THE ALTERNATIVE FUNCTION</a>
+<li><a name="TOC40" href="#SEC40">SEE ALSO</a>
+<li><a name="TOC41" href="#SEC41">AUTHOR</a>
+<li><a name="TOC42" href="#SEC42">REVISION</a>
 </ul>
 <P>
 <b>#include &#60;pcre2.h&#62;</b>
 <br>
 <br>
-PCRE2 is a new API for PCRE. This document contains a description of all its
-functions. See the
+PCRE2 is a new API for PCRE, starting at release 10.0. This document contains a
+description of all its native functions. See the
 <a href="pcre2.html"><b>pcre2</b></a>
 document for an overview of all the PCRE2 documentation.
 </P>
@@ -144,6 +145,10 @@
 <b>  const unsigned char *<i>tables</i>);</b>
 <br>
 <br>
+<b>int pcre2_set_compile_extra_options(pcre2_compile_context *<i>ccontext</i>,</b>
+<b>  uint32_t <i>extra_options</i>);</b>
+<br>
+<br>
 <b>int pcre2_set_max_pattern_length(pcre2_compile_context *<i>ccontext</i>,</b>
 <b>  PCRE2_SIZE <i>value</i>);</b>
 <br>
@@ -177,22 +182,20 @@
 <b>  void *<i>callout_data</i>);</b>
 <br>
 <br>
-<b>int pcre2_set_match_limit(pcre2_match_context *<i>mcontext</i>,</b>
-<b>  uint32_t <i>value</i>);</b>
-<br>
-<br>
 <b>int pcre2_set_offset_limit(pcre2_match_context *<i>mcontext</i>,</b>
 <b>  PCRE2_SIZE <i>value</i>);</b>
 <br>
 <br>
-<b>int pcre2_set_recursion_limit(pcre2_match_context *<i>mcontext</i>,</b>
+<b>int pcre2_set_heap_limit(pcre2_match_context *<i>mcontext</i>,</b>
 <b>  uint32_t <i>value</i>);</b>
 <br>
 <br>
-<b>int pcre2_set_recursion_memory_management(</b>
-<b>  pcre2_match_context *<i>mcontext</i>,</b>
-<b>  void *(*<i>private_malloc</i>)(PCRE2_SIZE, void *),</b>
-<b>  void (*<i>private_free</i>)(void *, void *), void *<i>memory_data</i>);</b>
+<b>int pcre2_set_match_limit(pcre2_match_context *<i>mcontext</i>,</b>
+<b>  uint32_t <i>value</i>);</b>
+<br>
+<br>
+<b>int pcre2_set_depth_limit(pcre2_match_context *<i>mcontext</i>,</b>
+<b>  uint32_t <i>value</i>);</b>
 </P>
 <br><a name="SEC6" href="#TOC1">PCRE2 NATIVE API STRING EXTRACTION FUNCTIONS</a><br>
 <P>
@@ -294,6 +297,9 @@
 <b>pcre2_code *pcre2_code_copy(const pcre2_code *<i>code</i>);</b>
 <br>
 <br>
+<b>pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *<i>code</i>);</b>
+<br>
+<br>
 <b>int pcre2_get_error_message(int <i>errorcode</i>, PCRE2_UCHAR *<i>buffer</i>,</b>
 <b>  PCRE2_SIZE <i>bufflen</i>);</b>
 <br>
@@ -311,7 +317,60 @@
 <br>
 <b>int pcre2_config(uint32_t <i>what</i>, void *<i>where</i>);</b>
 </P>
-<br><a name="SEC11" href="#TOC1">PCRE2 8-BIT, 16-BIT, AND 32-BIT LIBRARIES</a><br>
+<br><a name="SEC11" href="#TOC1">PCRE2 NATIVE API OBSOLETE FUNCTIONS</a><br>
+<P>
+<b>int pcre2_set_recursion_limit(pcre2_match_context *<i>mcontext</i>,</b>
+<b>  uint32_t <i>value</i>);</b>
+<br>
+<br>
+<b>int pcre2_set_recursion_memory_management(</b>
+<b>  pcre2_match_context *<i>mcontext</i>,</b>
+<b>  void *(*<i>private_malloc</i>)(PCRE2_SIZE, void *),</b>
+<b>  void (*<i>private_free</i>)(void *, void *), void *<i>memory_data</i>);</b>
+<br>
+<br>
+These functions became obsolete at release 10.30 and are retained only for
+backward compatibility. They should not be used in new code. The first is
+replaced by <b>pcre2_set_depth_limit()</b>; the second is no longer needed and
+has no effect (it always returns zero).
+</P>
+<br><a name="SEC12" href="#TOC1">PCRE2 EXPERIMENTAL PATTERN CONVERSION FUNCTIONS</a><br>
+<P>
+<b>pcre2_convert_context *pcre2_convert_context_create(</b>
+<b>  pcre2_general_context *<i>gcontext</i>);</b>
+<br>
+<br>
+<b>pcre2_convert_context *pcre2_convert_context_copy(</b>
+<b>  pcre2_convert_context *<i>cvcontext</i>);</b>
+<br>
+<br>
+<b>void pcre2_convert_context_free(pcre2_convert_context *<i>cvcontext</i>);</b>
+<br>
+<br>
+<b>int pcre2_set_glob_escape(pcre2_convert_context *<i>cvcontext</i>,</b>
+<b>  uint32_t <i>escape_char</i>);</b>
+<br>
+<br>
+<b>int pcre2_set_glob_separator(pcre2_convert_context *<i>cvcontext</i>,</b>
+<b>  uint32_t <i>separator_char</i>);</b>
+<br>
+<br>
+<b>int pcre2_pattern_convert(PCRE2_SPTR <i>pattern</i>, PCRE2_SIZE <i>length</i>,</b>
+<b>  uint32_t <i>options</i>, PCRE2_UCHAR **<i>buffer</i>,</b>
+<b>  PCRE2_SIZE *<i>blength</i>, pcre2_convert_context *<i>cvcontext</i>);</b>
+<br>
+<br>
+<b>void pcre2_converted_pattern_free(PCRE2_UCHAR *<i>converted_pattern</i>);</b>
+<br>
+<br>
+These functions provide a way of converting non-PCRE2 patterns into
+patterns that can be processed by <b>pcre2_compile()</b>. This facility is
+experimental and may be changed in future releases. At present, "globs" and
+POSIX basic and extended patterns can be converted. Details are given in the
+<a href="pcre2convert.html"><b>pcre2convert</b></a>
+documentation.
+</P>
+<br><a name="SEC13" href="#TOC1">PCRE2 8-BIT, 16-BIT, AND 32-BIT LIBRARIES</a><br>
 <P>
 There are three PCRE2 libraries, supporting 8-bit, 16-bit, and 32-bit code
 units, respectively. However, there is just one header file, <b>pcre2.h</b>.
@@ -365,28 +424,28 @@
 processing any particular pattern to use only functions from a single library.
 For example, if you want to run a match using a pattern that was compiled with
 <b>pcre2_compile_16()</b>, you must do so with <b>pcre2_match_16()</b>, not
-<b>pcre2_match_8()</b>.
+<b>pcre2_match_8()</b> or <b>pcre2_match_32()</b>.
 </P>
 <P>
 In the function summaries above, and in the rest of this document and other
 PCRE2 documents, functions and data types are described using their generic
-names, without the 8, 16, or 32 suffix.
+names, without the _8, _16, or _32 suffix.
 </P>
-<br><a name="SEC12" href="#TOC1">PCRE2 API OVERVIEW</a><br>
+<br><a name="SEC14" href="#TOC1">PCRE2 API OVERVIEW</a><br>
 <P>
 PCRE2 has its own native API, which is described in this document. There are
 also some wrapper functions for the 8-bit library that correspond to the
 POSIX regular expression API, but they do not give access to all the
-functionality. They are described in the
+functionality of PCRE2. They are described in the
 <a href="pcre2posix.html"><b>pcre2posix</b></a>
 documentation. Both these APIs define a set of C function calls.
 </P>
 <P>
 The native API C data types, function prototypes, option values, and error
-codes are defined in the header file <b>pcre2.h</b>, which contains definitions
-of PCRE2_MAJOR and PCRE2_MINOR, the major and minor release numbers for the
-library. Applications can use these to include support for different releases
-of PCRE2.
+codes are defined in the header file <b>pcre2.h</b>, which also contains
+definitions of PCRE2_MAJOR and PCRE2_MINOR, the major and minor release numbers
+for the library. Applications can use these to include support for different
+releases of PCRE2.
 </P>
 <P>
 In a Windows environment, if you want to statically link an application program
@@ -394,7 +453,7 @@
 <b>pcre2.h</b>.
 </P>
 <P>
-The functions <b>pcre2_compile()</b>, and <b>pcre2_match()</b> are used for
+The functions <b>pcre2_compile()</b> and <b>pcre2_match()</b> are used for
 compiling and matching regular expressions in a Perl-compatible manner. A
 sample program that demonstrates the simplest way of using them is provided in
 the file called <i>pcre2demo.c</i> in the PCRE2 source distribution. A listing
@@ -405,10 +464,17 @@
 documentation describes how to compile and run it.
 </P>
 <P>
-Just-in-time compiler support is an optional feature of PCRE2 that can be built
-in appropriate hardware environments. It greatly speeds up the matching
+The compiling and matching functions recognize various options that are passed
+as bits in an options argument. There are also some more complicated parameters
+such as custom memory management functions and resource limits that are passed
+in "contexts" (which are just memory blocks, described below). Simple
+applications do not need to make use of contexts.
+</P>
+<P>
+Just-in-time (JIT) compiler support is an optional feature of PCRE2 that can be
+built in appropriate hardware environments. It greatly speeds up the matching
 performance of many patterns. Programs can request that it be used if
-available, by calling <b>pcre2_jit_compile()</b> after a pattern has been
+available by calling <b>pcre2_jit_compile()</b> after a pattern has been
 successfully compiled by <b>pcre2_compile()</b>. This does nothing if JIT
 support is not available.
 </P>
@@ -420,8 +486,8 @@
 <P>
 JIT matching is automatically used by <b>pcre2_match()</b> if it is available,
 unless the PCRE2_NO_JIT option is set. There is also a direct interface for JIT
-matching, which gives improved performance. The JIT-specific functions are
-discussed in the
+matching, which gives improved performance at the expense of less sanity
+checking. The JIT-specific functions are discussed in the
 <a href="pcre2jit.html"><b>pcre2jit</b></a>
 documentation.
 </P>
@@ -430,7 +496,7 @@
 Perl-compatible, is also provided. This uses a different algorithm for the
 matching. The alternative algorithm finds all possible matches (at a given
 point in the subject), and scans the subject just once (unless there are
-lookbehind assertions). However, this algorithm does not return captured
+lookaround assertions). However, this algorithm does not return captured
 substrings. A description of the two matching algorithms and their advantages
 and disadvantages is given in the
 <a href="pcre2matching.html"><b>pcre2matching</b></a>
@@ -452,7 +518,7 @@
   <b>pcre2_substring_number_from_name()</b>
 </pre>
 <b>pcre2_substring_free()</b> and <b>pcre2_substring_list_free()</b> are also
-provided, to free the memory used for extracted strings.
+provided, to free memory used for extracted strings.
 </P>
 <P>
 The function <b>pcre2_substitute()</b> can be called to match a pattern and
@@ -473,7 +539,7 @@
 blocks of various sorts. In all cases, if one of these functions is called with
 a NULL argument, it does nothing.
 </P>
-<br><a name="SEC13" href="#TOC1">STRING LENGTHS AND OFFSETS</a><br>
+<br><a name="SEC15" href="#TOC1">STRING LENGTHS AND OFFSETS</a><br>
 <P>
 The PCRE2 API uses string lengths and offsets into strings of code units in
 several places. These values are always of type PCRE2_SIZE, which is an
@@ -483,7 +549,7 @@
 Therefore, the longest string that can be handled is one less than this
 maximum.
 <a name="newlines"></a></P>
-<br><a name="SEC14" href="#TOC1">NEWLINES</a><br>
+<br><a name="SEC16" href="#TOC1">NEWLINES</a><br>
 <P>
 PCRE2 supports five different conventions for indicating line breaks in
 strings: a single CR (carriage return) character, a single LF (linefeed)
@@ -518,7 +584,7 @@
 the \n or \r escape sequences, nor does it affect what \R matches; this has
 its own separate convention.
 </P>
-<br><a name="SEC15" href="#TOC1">MULTITHREADING</a><br>
+<br><a name="SEC17" href="#TOC1">MULTITHREADING</a><br>
 <P>
 In a multithreaded application it is important to keep thread-specific data
 separate from data that can be shared between threads. The PCRE2 library code
@@ -540,8 +606,8 @@
 that is, the same compiled pattern can be used by more than one thread
 simultaneously. For example, an application can compile all its patterns at the
 start, before forking off multiple threads that use them. However, if the
-just-in-time optimization feature is being used, it needs separate memory stack
-areas for each thread. See the
+just-in-time (JIT) optimization feature is being used, it needs separate memory
+stack areas for each thread. See the
 <a href="pcre2jit.html"><b>pcre2jit</b></a>
 documentation for more details.
 </P>
@@ -567,8 +633,9 @@
 (perhaps waiting to see if the pattern is used often enough) similar logic is
 required. JIT compilation updates a pointer within the compiled code block, so
 a thread must gain unique write access to the pointer before calling
-<b>pcre2_jit_compile()</b>. Alternatively, <b>pcre2_code_copy()</b> can be used
-to obtain a private copy of the compiled code.
+<b>pcre2_jit_compile()</b>. Alternatively, <b>pcre2_code_copy()</b> or
+<b>pcre2_code_copy_with_tables()</b> can be used to obtain a private copy of the
+compiled code before calling the JIT compiler.
 </P>
 <br><b>
 Context blocks
@@ -592,12 +659,12 @@
 Match blocks
 </b><br>
 <P>
-The matching functions need a block of memory for working space and for storing
-the results of a match. This includes details of what was matched, as well as
-additional information such as the name of a (*MARK) setting. Each thread must
-provide its own copy of this memory.
+The matching functions need a block of memory for storing the results of a
+match. This includes details of what was matched, as well as additional
+information such as the name of a (*MARK) setting. Each thread must provide its
+own copy of this memory.
 </P>
-<br><a name="SEC16" href="#TOC1">PCRE2 CONTEXTS</a><br>
+<br><a name="SEC18" href="#TOC1">PCRE2 CONTEXTS</a><br>
 <P>
 Some PCRE2 functions have a lot of parameters, many of which are used only by
 specialist applications, for example, those that use custom memory management
@@ -622,6 +689,8 @@
 because in future other fields may be added. If you do not want to supply your
 own custom memory management functions, you do not need to bother with a
 general context. A general context is created by:
+<br>
+<br>
 <b>pcre2_general_context *pcre2_general_context_create(</b>
 <b>  void *(*<i>private_malloc</i>)(PCRE2_SIZE, void *),</b>
 <b>  void (*<i>private_free</i>)(void *, void *), void *<i>memory_data</i>);</b>
@@ -648,26 +717,31 @@
 </P>
 <P>
 A general context can be copied by calling:
+<br>
+<br>
 <b>pcre2_general_context *pcre2_general_context_copy(</b>
 <b>  pcre2_general_context *<i>gcontext</i>);</b>
 <br>
 <br>
 The memory used for a general context should be freed by calling:
+<br>
+<br>
 <b>void pcre2_general_context_free(pcre2_general_context *<i>gcontext</i>);</b>
 <a name="compilecontext"></a></P>
 <br><b>
 The compile context
 </b><br>
 <P>
-A compile context is required if you want to change the default values of any
-of the following compile-time parameters:
+A compile context is required if you want to provide an external function for
+stack checking during compilation or to change the default values of any of the
+following compile-time parameters:
 <pre>
   What \R matches (Unicode newlines or CR, LF, CRLF only)
   PCRE2's character tables
   The newline character sequence
   The compile time nested parentheses limit
   The maximum length of the pattern string
-  An external function for stack checking
+  The extra options bits (none set by default)
 </pre>
 A compile context is also required if you are using custom memory management.
 If none of these apply, just pass NULL as the context argument of
@@ -675,6 +749,8 @@
 </P>
 <P>
 A compile context is created, copied, and freed by the following functions:
+<br>
+<br>
 <b>pcre2_compile_context *pcre2_compile_context_create(</b>
 <b>  pcre2_general_context *<i>gcontext</i>);</b>
 <br>
@@ -689,6 +765,8 @@
 A compile context is created with default values for its parameters. These can
 be changed by calling the following functions, which return 0 on success, or
 PCRE2_ERROR_BADDATA if invalid data is detected.
+<br>
+<br>
 <b>int pcre2_set_bsr(pcre2_compile_context *<i>ccontext</i>,</b>
 <b>  uint32_t <i>value</i>);</b>
 <br>
@@ -698,6 +776,8 @@
 ending sequence. The value is used by the JIT compiler and by the two
 interpreted matching functions, <i>pcre2_match()</i> and
 <i>pcre2_dfa_match()</i>.
+<br>
+<br>
 <b>int pcre2_set_character_tables(pcre2_compile_context *<i>ccontext</i>,</b>
 <b>  const unsigned char *<i>tables</i>);</b>
 <br>
@@ -705,15 +785,33 @@
 The value must be the result of a call to <i>pcre2_maketables()</i>, whose only
 argument is a general context. This function builds a set of character tables
 in the current locale.
+<br>
+<br>
+<b>int pcre2_set_compile_extra_options(pcre2_compile_context *<i>ccontext</i>,</b>
+<b>  uint32_t <i>extra_options</i>);</b>
+<br>
+<br>
+As PCRE2 has developed, almost all the 32 option bits that are available in
+the <i>options</i> argument of <b>pcre2_compile()</b> have been used up. To avoid
+running out, the compile context contains a set of extra option bits which are
+used for some newer, assumed rarer, options. This function sets those bits. It
+always sets all the bits (either on or off). It does not modify any existing
+setting. The available options are defined in the section entitled "Extra
+compile options"
+<a href="#extracompileoptions">below.</a>
+<br>
+<br>
 <b>int pcre2_set_max_pattern_length(pcre2_compile_context *<i>ccontext</i>,</b>
 <b>  PCRE2_SIZE <i>value</i>);</b>
 <br>
 <br>
-This sets a maximum length, in code units, for the pattern string that is to be
-compiled. If the pattern is longer, an error is generated. This facility is
-provided so that applications that accept patterns from external sources can
-limit their size. The default is the largest number that a PCRE2_SIZE variable
-can hold, which is effectively unlimited.
+This sets a maximum length, in code units, for any pattern string that is
+compiled with this context. If the pattern is longer, an error is generated.
+This facility is provided so that applications that accept patterns from
+external sources can limit their size. The default is the largest number that a
+PCRE2_SIZE variable can hold, which is effectively unlimited.
+<br>
+<br>
 <b>int pcre2_set_newline(pcre2_compile_context *<i>ccontext</i>,</b>
 <b>  uint32_t <i>value</i>);</b>
 <br>
@@ -721,22 +819,34 @@
 This specifies which characters or character sequences are to be recognized as
 newlines. The value must be one of PCRE2_NEWLINE_CR (carriage return only),
 PCRE2_NEWLINE_LF (linefeed only), PCRE2_NEWLINE_CRLF (the two-character
-sequence CR followed by LF), PCRE2_NEWLINE_ANYCRLF (any of the above), or
-PCRE2_NEWLINE_ANY (any Unicode newline sequence).
+sequence CR followed by LF), PCRE2_NEWLINE_ANYCRLF (any of the above),
+PCRE2_NEWLINE_ANY (any Unicode newline sequence), or PCRE2_NEWLINE_NUL (the
+NUL character, that is a binary zero).
 </P>
 <P>
-When a pattern is compiled with the PCRE2_EXTENDED option, the value of this
-parameter affects the recognition of white space and the end of internal
-comments starting with #. The value is saved with the compiled pattern for
-subsequent use by the JIT compiler and by the two interpreted matching
-functions, <i>pcre2_match()</i> and <i>pcre2_dfa_match()</i>.
+A pattern can override the value set in the compile context by starting with a
+sequence such as (*CRLF). See the
+<a href="pcre2pattern.html"><b>pcre2pattern</b></a>
+page for details.
+</P>
+<P>
+When a pattern is compiled with the PCRE2_EXTENDED or PCRE2_EXTENDED_MORE
+option, the newline convention affects the recognition of white space and the
+end of internal comments starting with #. The value is saved with the compiled
+pattern for subsequent use by the JIT compiler and by the two interpreted
+matching functions, <i>pcre2_match()</i> and <i>pcre2_dfa_match()</i>.
+<br>
+<br>
 <b>int pcre2_set_parens_nest_limit(pcre2_compile_context *<i>ccontext</i>,</b>
 <b>  uint32_t <i>value</i>);</b>
 <br>
 <br>
 This parameter ajusts the limit, set when PCRE2 is built (default 250), on the
 depth of parenthesis nesting in a pattern. This limit stops rogue patterns
-using up too much system stack when being compiled.
+using up too much system stack when being compiled. The limit applies to
+parentheses of all kinds, not just capturing parentheses.
+<br>
+<br>
 <b>int pcre2_set_compile_recursion_guard(pcre2_compile_context *<i>ccontext</i>,</b>
 <b>  int (*<i>guard_function</i>)(uint32_t, void *), void *<i>user_data</i>);</b>
 <br>
@@ -744,10 +854,10 @@
 There is at least one application that runs PCRE2 in threads with very limited
 system stack, where running out of stack is to be avoided at all costs. The
 parenthesis limit above cannot take account of how much stack is actually
-available. For a finer control, you can supply a function that is called
-whenever <b>pcre2_compile()</b> starts to compile a parenthesized part of a
-pattern. This function can check the actual stack size (or anything else that
-it wants to, of course).
+available during compilation. For a finer control, you can supply a function
+that is called whenever <b>pcre2_compile()</b> starts to compile a parenthesized
+part of a pattern. This function can check the actual stack size (or anything
+else that it wants to, of course).
 </P>
 <P>
 The first argument to the callout function gives the current depth of
@@ -759,20 +869,22 @@
 The match context
 </b><br>
 <P>
-A match context is required if you want to change the default values of any
-of the following match-time parameters:
+A match context is required if you want to:
 <pre>
-  A callout function
-  The offset limit for matching an unanchored pattern
-  The limit for calling <b>match()</b> (see below)
-  The limit for calling <b>match()</b> recursively
+  Set up a callout function
+  Set an offset limit for matching an unanchored pattern
+  Change the limit on the amount of heap used when matching
+  Change the backtracking match limit
+  Change the backtracking depth limit
+  Set custom memory management specifically for the match
 </pre>
-A match context is also required if you are using custom memory management.
 If none of these apply, just pass NULL as the context argument of
 <b>pcre2_match()</b>, <b>pcre2_dfa_match()</b>, or <b>pcre2_jit_match()</b>.
 </P>
 <P>
 A match context is created, copied, and freed by the following functions:
+<br>
+<br>
 <b>pcre2_match_context *pcre2_match_context_create(</b>
 <b>  pcre2_general_context *<i>gcontext</i>);</b>
 <br>
@@ -787,15 +899,19 @@
 A match context is created with default values for its parameters. These can
 be changed by calling the following functions, which return 0 on success, or
 PCRE2_ERROR_BADDATA if invalid data is detected.
+<br>
+<br>
 <b>int pcre2_set_callout(pcre2_match_context *<i>mcontext</i>,</b>
 <b>  int (*<i>callout_function</i>)(pcre2_callout_block *, void *),</b>
 <b>  void *<i>callout_data</i>);</b>
 <br>
 <br>
-This sets up a "callout" function, which PCRE2 will call at specified points
+This sets up a "callout" function for PCRE2 to call at specified points
 during a matching operation. Details are given in the
 <a href="pcre2callout.html"><b>pcre2callout</b></a>
 documentation.
+<br>
+<br>
 <b>int pcre2_set_offset_limit(pcre2_match_context *<i>mcontext</i>,</b>
 <b>  PCRE2_SIZE <i>value</i>);</b>
 <br>
@@ -804,41 +920,83 @@
 advance in the subject string. The default value is PCRE2_UNSET. The
 <b>pcre2_match()</b> and <b>pcre2_dfa_match()</b> functions return
 PCRE2_ERROR_NOMATCH if a match with a starting point before or at the given
-offset is not found. For example, if the pattern /abc/ is matched against
-"123abc" with an offset limit less than 3, the result is PCRE2_ERROR_NO_MATCH.
-A match can never be found if the <i>startoffset</i> argument of
-<b>pcre2_match()</b> or <b>pcre2_dfa_match()</b> is greater than the offset
-limit.
+offset is not found. The <b>pcre2_substitute()</b> function makes no more
+substitutions.
 </P>
 <P>
-When using this facility, you must set PCRE2_USE_OFFSET_LIMIT when calling
-<b>pcre2_compile()</b> so that when JIT is in use, different code can be
+For example, if the pattern /abc/ is matched against "123abc" with an offset
+limit less than 3, the result is PCRE2_ERROR_NO_MATCH. A match can never be
+found if the <i>startoffset</i> argument of <b>pcre2_match()</b>,
+<b>pcre2_dfa_match()</b>, or <b>pcre2_substitute()</b> is greater than the offset
+limit set in the match context.
+</P>
+<P>
+When using this facility, you must set the PCRE2_USE_OFFSET_LIMIT option when
+calling <b>pcre2_compile()</b> so that when JIT is in use, different code can be
 compiled. If a match is started with a non-default match limit when
 PCRE2_USE_OFFSET_LIMIT is not set, an error is generated.
 </P>
 <P>
 The offset limit facility can be used to track progress when searching large
-subject strings. See also the PCRE2_FIRSTLINE option, which requires a match to
-start within the first line of the subject. If this is set with an offset
-limit, a match must occur in the first line and also within the offset limit.
-In other words, whichever limit comes first is used.
+subject strings or to limit the extent of global substitutions. See also the
+PCRE2_FIRSTLINE option, which requires a match to start before or at the first
+newline that follows the start of matching in the subject. If this is set with
+an offset limit, a match must occur in the first line and also within the
+offset limit. In other words, whichever limit comes first is used.
+<br>
+<br>
+<b>int pcre2_set_heap_limit(pcre2_match_context *<i>mcontext</i>,</b>
+<b>  uint32_t <i>value</i>);</b>
+<br>
+<br>
+The <i>heap_limit</i> parameter specifies, in units of kilobytes, the maximum
+amount of heap memory that <b>pcre2_match()</b> may use to hold backtracking
+information when running an interpretive match. This limit does not apply to
+matching with the JIT optimization, which has its own memory control
+arrangements (see the
+<a href="pcre2jit.html"><b>pcre2jit</b></a>
+documentation for more details), nor does it apply to <b>pcre2_dfa_match()</b>.
+If the limit is reached, the negative error code PCRE2_ERROR_HEAPLIMIT is
+returned. The default limit is set when PCRE2 is built; the default default is
+very large and is essentially "unlimited".
+</P>
+<P>
+A value for the heap limit may also be supplied by an item at the start of a
+pattern of the form
+<pre>
+  (*LIMIT_HEAP=ddd)
+</pre>
+where ddd is a decimal number. However, such a setting is ignored unless ddd is
+less than the limit set by the caller of <b>pcre2_match()</b> or, if no such
+limit is set, less than the default.
+</P>
+<P>
+The <b>pcre2_match()</b> function starts out using a 20K vector on the system
+stack for recording backtracking points. The more nested backtracking points
+there are (that is, the deeper the search tree), the more memory is needed.
+Heap memory is used only if the initial vector is too small. If the heap limit
+is set to a value less than 21 (in particular, zero) no heap memory will be
+used. In this case, only patterns that do not have a lot of nested backtracking
+can be successfully processed.
+<br>
+<br>
 <b>int pcre2_set_match_limit(pcre2_match_context *<i>mcontext</i>,</b>
 <b>  uint32_t <i>value</i>);</b>
 <br>
 <br>
 The <i>match_limit</i> parameter provides a means of preventing PCRE2 from using
-up too many resources when processing patterns that are not going to match, but
-which have a very large number of possibilities in their search trees. The
-classic example is a pattern that uses nested unlimited repeats.
+up too many computing resources when processing patterns that are not going to
+match, but which have a very large number of possibilities in their search
+trees. The classic example is a pattern that uses nested unlimited repeats.
 </P>
 <P>
-Internally, <b>pcre2_match()</b> uses a function called <b>match()</b>, which it
-calls repeatedly (sometimes recursively). The limit set by <i>match_limit</i> is
-imposed on the number of times this function is called during a match, which
-has the effect of limiting the amount of backtracking that can take place. For
+There is an internal counter in <b>pcre2_match()</b> that is incremented each
+time round its main matching loop. If this value reaches the match limit,
+<b>pcre2_match()</b> returns the negative value PCRE2_ERROR_MATCHLIMIT. This has
+the effect of limiting the amount of backtracking that can take place. For
 patterns that are not anchored, the count restarts from zero for each position
-in the subject string. This limit is not relevant to <b>pcre2_dfa_match()</b>,
-which ignores it.
+in the subject string. This limit also applies to <b>pcre2_dfa_match()</b>,
+though the counting is done in a different way.
 </P>
 <P>
 When <b>pcre2_match()</b> is called with a pattern that was successfully
@@ -850,72 +1008,53 @@
 </P>
 <P>
 The default value for the limit can be set when PCRE2 is built; the default
-default is 10 million, which handles all but the most extreme cases. If the
-limit is exceeded, <b>pcre2_match()</b> returns PCRE2_ERROR_MATCHLIMIT. A value
+default is 10 million, which handles all but the most extreme cases. A value
 for the match limit may also be supplied by an item at the start of a pattern
 of the form
 <pre>
   (*LIMIT_MATCH=ddd)
 </pre>
 where ddd is a decimal number. However, such a setting is ignored unless ddd is
-less than the limit set by the caller of <b>pcre2_match()</b> or, if no such
-limit is set, less than the default.
-<b>int pcre2_set_recursion_limit(pcre2_match_context *<i>mcontext</i>,</b>
+less than the limit set by the caller of <b>pcre2_match()</b> or
+<b>pcre2_dfa_match()</b> or, if no such limit is set, less than the default.
+<br>
+<br>
+<b>int pcre2_set_depth_limit(pcre2_match_context *<i>mcontext</i>,</b>
 <b>  uint32_t <i>value</i>);</b>
 <br>
 <br>
-The <i>recursion_limit</i> parameter is similar to <i>match_limit</i>, but
-instead of limiting the total number of times that <b>match()</b> is called, it
-limits the depth of recursion. The recursion depth is a smaller number than the
-total number of calls, because not all calls to <b>match()</b> are recursive.
-This limit is of use only if it is set smaller than <i>match_limit</i>.
+This parameter limits the depth of nested backtracking in <b>pcre2_match()</b>.
+Each time a nested backtracking point is passed, a new memory "frame" is used
+to remember the state of matching at that point. Thus, this parameter
+indirectly limits the amount of memory that is used in a match. However,
+because the size of each memory "frame" depends on the number of capturing
+parentheses, the actual memory limit varies from pattern to pattern. This limit
+was more useful in versions before 10.30, where function recursion was used for
+backtracking.
 </P>
 <P>
-Limiting the recursion depth limits the amount of system stack that can be
-used, or, when PCRE2 has been compiled to use memory on the heap instead of the
-stack, the amount of heap memory that can be used. This limit is not relevant,
-and is ignored, when matching is done using JIT compiled code or by the
-<b>pcre2_dfa_match()</b> function.
+The depth limit is not relevant, and is ignored, when matching is done using
+JIT compiled code. However, it is supported by <b>pcre2_dfa_match()</b>, which
+uses it to limit the depth of internal recursive function calls that implement
+atomic groups, lookaround assertions, and pattern recursions. This is,
+therefore, an indirect limit on the amount of system stack that is used. A
+recursive pattern such as /(.)(?1)/, when matched to a very long string using
+<b>pcre2_dfa_match()</b>, can use a great deal of stack.
 </P>
 <P>
-The default value for <i>recursion_limit</i> can be set when PCRE2 is built; the
-default default is the same value as the default for <i>match_limit</i>. If the
-limit is exceeded, <b>pcre2_match()</b> returns PCRE2_ERROR_RECURSIONLIMIT. A
-value for the recursion limit may also be supplied by an item at the start of a
-pattern of the form
+The default value for the depth limit can be set when PCRE2 is built; the
+default default is the same value as the default for the match limit. If the
+limit is exceeded, <b>pcre2_match()</b> or <b>pcre2_dfa_match()</b> returns
+PCRE2_ERROR_DEPTHLIMIT. A value for the depth limit may also be supplied by an
+item at the start of a pattern of the form
 <pre>
-  (*LIMIT_RECURSION=ddd)
+  (*LIMIT_DEPTH=ddd)
 </pre>
 where ddd is a decimal number. However, such a setting is ignored unless ddd is
-less than the limit set by the caller of <b>pcre2_match()</b> or, if no such
-limit is set, less than the default.
-<b>int pcre2_set_recursion_memory_management(</b>
-<b>  pcre2_match_context *<i>mcontext</i>,</b>
-<b>  void *(*<i>private_malloc</i>)(PCRE2_SIZE, void *),</b>
-<b>  void (*<i>private_free</i>)(void *, void *), void *<i>memory_data</i>);</b>
-<br>
-<br>
-This function sets up two additional custom memory management functions for use
-by <b>pcre2_match()</b> when PCRE2 is compiled to use the heap for remembering
-backtracking data, instead of recursive function calls that use the system
-stack. There is a discussion about PCRE2's stack usage in the
-<a href="pcre2stack.html"><b>pcre2stack</b></a>
-documentation. See the
-<a href="pcre2build.html"><b>pcre2build</b></a>
-documentation for details of how to build PCRE2.
+less than the limit set by the caller of <b>pcre2_match()</b> or
+<b>pcre2_dfa_match()</b> or, if no such limit is set, less than the default.
 </P>
-<P>
-Using the heap for recursion is a non-standard way of building PCRE2, for use
-in environments that have limited stacks. Because of the greater use of memory
-management, <b>pcre2_match()</b> runs more slowly. Functions that are different
-to the general custom memory functions are provided so that special-purpose
-external code can be used for this case, because the memory blocks are all the
-same size. The blocks are retained by <b>pcre2_match()</b> until it is about to
-exit so that they can be re-used when possible during the match. In the absence
-of these functions, the normal custom memory management functions are used, if
-supplied, otherwise the system functions.
-</P>
-<br><a name="SEC17" href="#TOC1">CHECKING BUILD-TIME OPTIONS</a><br>
+<br><a name="SEC19" href="#TOC1">CHECKING BUILD-TIME OPTIONS</a><br>
 <P>
 <b>int pcre2_config(uint32_t <i>what</i>, void *<i>where</i>);</b>
 </P>
@@ -948,6 +1087,25 @@
 value of PCRE2_BSR_ANYCRLF means that \R matches only CR, LF, or CRLF. The
 default can be overridden when a pattern is compiled.
 <pre>
+  PCRE2_CONFIG_COMPILED_WIDTHS
+</pre>
+The output is a uint32_t integer whose lower bits indicate which code unit
+widths were selected when PCRE2 was built. The 1-bit indicates 8-bit support,
+and the 2-bit and 4-bit indicate 16-bit and 32-bit support, respectively.
+<pre>
+  PCRE2_CONFIG_DEPTHLIMIT
+</pre>
+The output is a uint32_t integer that gives the default limit for the depth of
+nested backtracking in <b>pcre2_match()</b> or the depth of nested recursions
+and lookarounds in <b>pcre2_dfa_match()</b>. Further details are given with
+<b>pcre2_set_depth_limit()</b> above.
+<pre>
+  PCRE2_CONFIG_HEAPLIMIT
+</pre>
+The output is a uint32_t integer that gives, in kilobytes, the default limit
+for the amount of heap memory used by <b>pcre2_match()</b>. Further details are
+given with <b>pcre2_set_heap_limit()</b> above.
+<pre>
   PCRE2_CONFIG_JIT
 </pre>
 The output is a uint32_t integer that is set to one if support for just-in-time
@@ -982,9 +1140,9 @@
 <pre>
   PCRE2_CONFIG_MATCHLIMIT
 </pre>
-The output is a uint32_t integer that gives the default limit for the number of
-internal matching function calls in a <b>pcre2_match()</b> execution. Further
-details are given with <b>pcre2_match()</b> below.
+The output is a uint32_t integer that gives the default match limit for
+<b>pcre2_match()</b>. Further details are given with
+<b>pcre2_set_match_limit()</b> above.
 <pre>
   PCRE2_CONFIG_NEWLINE
 </pre>
@@ -996,10 +1154,16 @@
   PCRE2_NEWLINE_CRLF     Carriage return, linefeed (CRLF)
   PCRE2_NEWLINE_ANY      Any Unicode line ending
   PCRE2_NEWLINE_ANYCRLF  Any of CR, LF, or CRLF
+  PCRE2_NEWLINE_NUL      The NUL character (binary zero)
 </pre>
 The default should normally correspond to the standard sequence for your
 operating system.
 <pre>
+  PCRE2_CONFIG_NEVER_BACKSLASH_C
+</pre>
+The output is a uint32_t integer that is set to one if the use of \C was
+permanently disabled when PCRE2 was built; otherwise it is set to zero.
+<pre>
   PCRE2_CONFIG_PARENSLIMIT
 </pre>
 The output is a uint32_t integer that gives the maximum depth of nesting
@@ -1009,19 +1173,10 @@
 stack that may already be used by the calling application. For finer control
 over compilation stack usage, see <b>pcre2_set_compile_recursion_guard()</b>.
 <pre>
-  PCRE2_CONFIG_RECURSIONLIMIT
-</pre>
-The output is a uint32_t integer that gives the default limit for the depth of
-recursion when calling the internal matching function in a <b>pcre2_match()</b>
-execution. Further details are given with <b>pcre2_match()</b> below.
-<pre>
   PCRE2_CONFIG_STACKRECURSE
 </pre>
-The output is a uint32_t integer that is set to one if internal recursion when
-running <b>pcre2_match()</b> is implemented by recursive function calls that use
-the system stack to remember their state. This is the usual way that PCRE2 is
-compiled. The output is zero if PCRE2 was compiled to use blocks of data on the
-heap instead of recursive function calls.
+This parameter is obsolete and should not be used in new code. The output is a
+uint32_t integer that is always set to zero.
 <pre>
   PCRE2_CONFIG_UNICODE_VERSION
 </pre>
@@ -1040,14 +1195,14 @@
 <pre>
   PCRE2_CONFIG_VERSION
 </pre>
-The <i>where</i> argument should point to a buffer that is at least 12 code
+The <i>where</i> argument should point to a buffer that is at least 24 code
 units long. (The exact length required can be found by calling
 <b>pcre2_config()</b> with <b>where</b> set to NULL.) The buffer is filled with
 the PCRE2 version string, zero-terminated. The number of code units used is
 returned. This is the length of the string plus one unit for the terminating
 zero.
 <a name="compiling"></a></P>
-<br><a name="SEC18" href="#TOC1">COMPILING A PATTERN</a><br>
+<br><a name="SEC20" href="#TOC1">COMPILING A PATTERN</a><br>
 <P>
 <b>pcre2_code *pcre2_compile(PCRE2_SPTR <i>pattern</i>, PCRE2_SIZE <i>length</i>,</b>
 <b>  uint32_t <i>options</i>, int *<i>errorcode</i>, PCRE2_SIZE *<i>erroroffset,</i></b>
@@ -1058,11 +1213,14 @@
 <br>
 <br>
 <b>pcre2_code *pcre2_code_copy(const pcre2_code *<i>code</i>);</b>
+<br>
+<br>
+<b>pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *<i>code</i>);</b>
 </P>
 <P>
 The <b>pcre2_compile()</b> function compiles a pattern into an internal form.
-The pattern is defined by a pointer to a string of code units and a length. If
-the pattern is zero-terminated, the length can be specified as
+The pattern is defined by a pointer to a string of code units and a length (in
+code units). If the pattern is zero-terminated, the length can be specified as
 PCRE2_ZERO_TERMINATED. The function returns a pointer to a block of memory that
 contains the compiled pattern and related data, or NULL if an error occurred.
 </P>
@@ -1079,9 +1237,22 @@
 <a href="#jitcompiling">below),</a>
 the JIT information cannot be copied (because it is position-dependent).
 The new copy can initially be used only for non-JIT matching, though it can be
-passed to <b>pcre2_jit_compile()</b> if required. The <b>pcre2_code_copy()</b>
-function provides a way for individual threads in a multithreaded application
-to acquire a private copy of shared compiled code.
+passed to <b>pcre2_jit_compile()</b> if required.
+</P>
+<P>
+The <b>pcre2_code_copy()</b> function provides a way for individual threads in a
+multithreaded application to acquire a private copy of shared compiled code.
+However, it does not make a copy of the character tables used by the compiled
+pattern; the new pattern code points to the same tables as the original code.
+(See
+<a href="#jitcompiling">"Locale Support"</a>
+below for details of these character tables.) In many applications the same
+tables are used throughout, so this behaviour is appropriate. Nevertheless,
+there are occasions when a copy of a compiled pattern and the relevant tables
+are needed. The <b>pcre2_code_copy_with_tables()</b> provides this facility.
+Copies of both the code and the tables are made, with the new code pointing to
+the new tables. The memory for the new tables is automatically freed when
+<b>pcre2_code_free()</b> is called for the new copy of the compiled code.
 </P>
 <P>
 NOTE: When one of the matching functions is called, pointers to the compiled
@@ -1105,8 +1276,8 @@
 <P>
 For those options that can be different in different parts of the pattern, the
 contents of the <i>options</i> argument specifies their settings at the start of
-compilation. The PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK options can be set at
-the time of matching as well as at compile time.
+compilation. The PCRE2_ANCHORED, PCRE2_ENDANCHORED, and PCRE2_NO_UTF_CHECK
+options can be set at the time of matching as well as at compile time.
 </P>
 <P>
 Other, less frequently required compile-time parameters (for example, the
@@ -1122,13 +1293,26 @@
 and <b>pcre2_compile()</b> returns a non-NULL value.
 </P>
 <P>
-The <b>pcre2_get_error_message()</b> function (see "Obtaining a textual error
+There are nearly 100 positive error codes that <b>pcre2_compile()</b> may return
+if it finds an error in the pattern. There are also some negative error codes
+that are used for invalid UTF strings. These are the same as given by
+<b>pcre2_match()</b> and <b>pcre2_dfa_match()</b>, and are described in the
+<a href="pcre2unicode.html"><b>pcre2unicode</b></a>
+page. There is no separate documentation for the positive error codes, because
+the textual error messages that are obtained by calling the
+<b>pcre2_get_error_message()</b> function (see "Obtaining a textual error
 message"
 <a href="#geterrormessage">below)</a>
-provides a textual message for each error code. Compilation errors have
-positive error codes; UTF formatting error codes are negative. For an invalid
-UTF-8 or UTF-16 string, the offset is that of the first code unit of the
-failing character.
+should be self-explanatory. Macro names starting with PCRE2_ERROR_ are defined
+for both positive and negative error codes in <b>pcre2.h</b>.
+</P>
+<P>
+The value returned in <i>erroroffset</i> is an indication of where in the
+pattern the error occurred. It is not necessarily the furthest point in the
+pattern that was read. For example, after the error "lookbehind assertion is
+not fixed length", the error offset points to the start of the failing
+assertion. For an invalid UTF-8 or UTF-16 string, the offset is that of the
+first code unit of the failing character.
 </P>
 <P>
 Some errors are not detected until the whole pattern has been scanned; in these
@@ -1209,13 +1393,15 @@
 option is set, normal backslash processing is applied to verb names and only an
 unescaped closing parenthesis terminates the name. A closing parenthesis can be
 included in a name either as \) or between \Q and \E. If the PCRE2_EXTENDED
-option is set, unescaped whitespace in verb names is skipped and #-comments are
-recognized, exactly as in the rest of the pattern.
+or PCRE2_EXTENDED_MORE option is set, unescaped whitespace in verb names is
+skipped and #-comments are recognized in this mode, exactly as in the rest of
+the pattern.
 <pre>
   PCRE2_AUTO_CALLOUT
 </pre>
 If this bit is set, <b>pcre2_compile()</b> automatically inserts callout items,
-all with number 255, before each pattern item. For discussion of the callout
+all with number 255, before each pattern item, except immediately before or
+after an explicit callout in the pattern. For discussion of the callout
 facility, see the
 <a href="pcre2callout.html"><b>pcre2callout</b></a>
 documentation.
@@ -1224,7 +1410,13 @@
 </pre>
 If this bit is set, letters in the pattern match both upper and lower case
 letters in the subject. It is equivalent to Perl's /i option, and it can be
-changed within a pattern by a (?i) option setting.
+changed within a pattern by a (?i) option setting. If PCRE2_UTF is set, Unicode
+properties are used for all characters with more than one other case, and for
+all characters whose code points are greater than U+007f. For lower valued
+characters with only one other case, a lookup table is used for speed. When
+PCRE2_UTF is not set, a lookup table is used for all code points less than 256,
+and higher code points (available only in 16-bit or 32-bit mode) are treated as
+not having another case.
 <pre>
   PCRE2_DOLLAR_ENDONLY
 </pre>
@@ -1254,6 +1446,30 @@
 <a href="pcre2pattern.html"><b>pcre2pattern</b></a>
 documentation.
 <pre>
+  PCRE2_ENDANCHORED
+</pre>
+If this bit is set, the end of any pattern match must be right at the end of
+the string being searched (the "subject string"). If the pattern match
+succeeds by reaching (*ACCEPT), but does not reach the end of the subject, the
+match fails at the current starting point. For unanchored patterns, a new match
+is then tried at the next starting point. However, if the match succeeds by
+reaching the end of the pattern, but not the end of the subject, backtracking
+occurs and an alternative match may be found. Consider these two patterns:
+<pre>
+  .(*ACCEPT)|..
+  .|..
+</pre>
+If matched against "abc" with PCRE2_ENDANCHORED set, the first matches "c"
+whereas the second matches "bc". The effect of PCRE2_ENDANCHORED can also be
+achieved by appropriate constructs in the pattern itself, which is the only way
+to do it in Perl.
+</P>
+<P>
+For DFA matching with <b>pcre2_dfa_match()</b>, PCRE2_ENDANCHORED applies only
+to the first (that is, the longest) matched string. Other parallel matches,
+which are necessarily substrings of the first one, must obviously end before
+the end of the subject.
+<pre>
   PCRE2_EXTENDED
 </pre>
 If this bit is set, most white space characters in the pattern are totally
@@ -1280,14 +1496,39 @@
 in the <b>pcre2pattern</b> documentation. A default is defined when PCRE2 is
 built.
 <pre>
+  PCRE2_EXTENDED_MORE
+</pre>
+This option has the effect of PCRE2_EXTENDED, but, in addition, unescaped space
+and horizontal tab characters are ignored inside a character class.
+PCRE2_EXTENDED_MORE is equivalent to Perl's 5.26 /xx option, and it can be
+changed within a pattern by a (?xx) option setting.
+<pre>
   PCRE2_FIRSTLINE
 </pre>
-If this option is set, an unanchored pattern is required to match before or at
-the first newline in the subject string, though the matched text may continue
-over the newline. See also PCRE2_USE_OFFSET_LIMIT, which provides a more
-general limiting facility. If PCRE2_FIRSTLINE is set with an offset limit, a
-match must occur in the first line and also within the offset limit. In other
-words, whichever limit comes first is used.
+If this option is set, the start of an unanchored pattern match must be before
+or at the first newline in the subject string following the start of matching,
+though the matched text may continue over the newline. If <i>startoffset</i> is
+non-zero, the limiting newline is not necessarily the first newline in the
+subject. For example, if the subject string is "abc\nxyz" (where \n
+represents a single-character newline) a pattern match for "yz" succeeds with
+PCRE2_FIRSTLINE if <i>startoffset</i> is greater than 3. See also
+PCRE2_USE_OFFSET_LIMIT, which provides a more general limiting facility. If
+PCRE2_FIRSTLINE is set with an offset limit, a match must occur in the first
+line and also within the offset limit. In other words, whichever limit comes
+first is used.
+<pre>
+  PCRE2_LITERAL
+</pre>
+If this option is set, all meta-characters in the pattern are disabled, and it
+is treated as a literal string. Matching literal strings with a regular
+expression engine is not the most efficient way of doing it. If you are doing a
+lot of literal matching and are worried about efficiency, you should consider
+using other approaches. The only other main options that are allowed with
+PCRE2_LITERAL are: PCRE2_ANCHORED, PCRE2_ENDANCHORED, PCRE2_AUTO_CALLOUT,
+PCRE2_CASELESS, PCRE2_FIRSTLINE, PCRE2_NO_START_OPTIMIZE, PCRE2_NO_UTF_CHECK,
+PCRE2_UTF, and PCRE2_USE_OFFSET_LIMIT. The extra options PCRE2_EXTRA_MATCH_LINE
+and PCRE2_EXTRA_MATCH_WORD are also supported. Any other options cause an
+error.
 <pre>
   PCRE2_MATCH_UNSET_BACKREF
 </pre>
@@ -1352,8 +1593,8 @@
 If this option is set, it disables the use of numbered capturing parentheses in
 the pattern. Any opening parenthesis that is not followed by ? behaves as if it
 were followed by ?: but named parentheses can still be used for capturing (and
-they acquire numbers in the usual way). There is no equivalent of this option
-in Perl. Note that, if this option is set, references to capturing groups (back
+they acquire numbers in the usual way). This is the same as Perl's /n option.
+Note that, when this option is set, references to capturing groups (back
 references or recursion/subroutine calls) may only refer to named groups,
 though the reference can be by name or by number.
 <pre>
@@ -1389,8 +1630,8 @@
 <P>
 There are a number of optimizations that may occur at the start of a match, in
 order to speed up the process. For example, if it is known that an unanchored
-match must start with a specific character, the matching code searches the
-subject for that character, and fails immediately if it cannot find it, without
+match must start with a specific code unit value, the matching code searches
+the subject for that value, and fails immediately if it cannot find it, without
 actually running the main matching function. This means that a special item
 such as (*COMMIT) at the start of a pattern is not considered until after a
 suitable starting point for the match has been found. Also, when callouts or
@@ -1419,9 +1660,11 @@
 match is run with PCRE2_NO_START_OPTIMIZE set, the initial scan along the
 subject string does not happen. The first match attempt is run starting from
 "D" and when this fails, (*COMMIT) prevents any further matches being tried, so
-the overall result is "no match". There are also other start-up optimizations.
-For example, a minimum length for the subject may be recorded. Consider the
-pattern
+the overall result is "no match".
+</P>
+<P>
+There are also other start-up optimizations. For example, a minimum length for
+the subject may be recorded. Consider the pattern
 <pre>
   (*MARK:A)(X|Y)
 </pre>
@@ -1442,17 +1685,30 @@
 <a href="pcre2unicode.html#utf32strings">UTF-32 strings</a>
 in the
 <a href="pcre2unicode.html"><b>pcre2unicode</b></a>
-document.
-If an invalid UTF sequence is found, <b>pcre2_compile()</b> returns a negative
-error code.
+document. If an invalid UTF sequence is found, <b>pcre2_compile()</b> returns a
+negative error code.
 </P>
 <P>
-If you know that your pattern is valid, and you want to skip this check for
-performance reasons, you can set the PCRE2_NO_UTF_CHECK option. When it is set,
-the effect of passing an invalid UTF string as a pattern is undefined. It may
-cause your program to crash or loop. Note that this option can also be passed
-to <b>pcre2_match()</b> and <b>pcre_dfa_match()</b>, to suppress validity
-checking of the subject string.
+If you know that your pattern is a valid UTF string, and you want to skip this
+check for performance reasons, you can set the PCRE2_NO_UTF_CHECK option. When
+it is set, the effect of passing an invalid UTF string as a pattern is
+undefined. It may cause your program to crash or loop.
+</P>
+<P>
+Note that this option can also be passed to <b>pcre2_match()</b> and
+<b>pcre_dfa_match()</b>, to suppress UTF validity checking of the subject
+string.
+</P>
+<P>
+Note also that setting PCRE2_NO_UTF_CHECK at compile time does not disable the
+error that is given if an escape sequence for an invalid Unicode code point is
+encountered in the pattern. In particular, the so-called "surrogate" code
+points (0xd800 to 0xdfff) are invalid. If you want to allow escape sequences
+such as \x{d800} you can set the PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES extra
+option, as described in the section entitled "Extra compile options"
+<a href="#extracompileoptions">below.</a>
+However, this is possible only in UTF-8 and UTF-32 modes, because these values
+are not representable in UTF-16.
 <pre>
   PCRE2_UCP
 </pre>
@@ -1465,7 +1721,7 @@
 <a href="pcre2pattern.html"><b>pcre2pattern</b></a>
 page. If you set PCRE2_UCP, matching one of the items it affects takes much
 longer. The option is available only if PCRE2 has been compiled with Unicode
-support.
+support (which is the default).
 <pre>
   PCRE2_UNGREEDY
 </pre>
@@ -1490,25 +1746,80 @@
 that are subsequently processed as strings of UTF characters instead of
 single-code-unit strings. It is available when PCRE2 is built to include
 Unicode support (which is the default). If Unicode support is not available,
-the use of this option provokes an error. Details of how this option changes
-the behaviour of PCRE2 are given in the
+the use of this option provokes an error. Details of how PCRE2_UTF changes the
+behaviour of PCRE2 are given in the
 <a href="pcre2unicode.html"><b>pcre2unicode</b></a>
 page.
-</P>
-<br><a name="SEC19" href="#TOC1">COMPILATION ERROR CODES</a><br>
+<a name="extracompileoptions"></a></P>
+<br><b>
+Extra compile options
+</b><br>
 <P>
-There are over 80 positive error codes that <b>pcre2_compile()</b> may return
-(via <i>errorcode</i>) if it finds an error in the pattern. There are also some
-negative error codes that are used for invalid UTF strings. These are the same
-as given by <b>pcre2_match()</b> and <b>pcre2_dfa_match()</b>, and are described
-in the
-<a href="pcre2unicode.html"><b>pcre2unicode</b></a>
-page. The <b>pcre2_get_error_message()</b> function (see "Obtaining a textual
-error message"
-<a href="#geterrormessage">below)</a>
-can be called to obtain a textual error message from any error code.
+Unlike the main compile-time options, the extra options are not saved with the
+compiled pattern. The option bits that can be set in a compile context by
+calling the <b>pcre2_set_compile_extra_options()</b> function are as follows:
+<pre>
+  PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES
+</pre>
+This option applies when compiling a pattern in UTF-8 or UTF-32 mode. It is
+forbidden in UTF-16 mode, and ignored in non-UTF modes. Unicode "surrogate"
+code points in the range 0xd800 to 0xdfff are used in pairs in UTF-16 to encode
+code points with values in the range 0x10000 to 0x10ffff. The surrogates cannot
+therefore be represented in UTF-16. They can be represented in UTF-8 and
+UTF-32, but are defined as invalid code points, and cause errors if encountered
+in a UTF-8 or UTF-32 string that is being checked for validity by PCRE2.
+</P>
+<P>
+These values also cause errors if encountered in escape sequences such as
+\x{d912} within a pattern. However, it seems that some applications, when
+using PCRE2 to check for unwanted characters in UTF-8 strings, explicitly test
+for the surrogates using escape sequences. The PCRE2_NO_UTF_CHECK option does
+not disable the error that occurs, because it applies only to the testing of
+input strings for UTF validity.
+</P>
+<P>
+If the extra option PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is set, surrogate code
+point values in UTF-8 and UTF-32 patterns no longer provoke errors and are
+incorporated in the compiled pattern. However, they can only match subject
+characters if the matching function is called with PCRE2_NO_UTF_CHECK set.
+<pre>
+  PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
+</pre>
+This is a dangerous option. Use with care. By default, an unrecognized escape
+such as \j or a malformed one such as \x{2z} causes a compile-time error when
+detected by <b>pcre2_compile()</b>. Perl is somewhat inconsistent in handling
+such items: for example, \j is treated as a literal "j", and non-hexadecimal
+digits in \x{} are just ignored, though warnings are given in both cases if
+Perl's warning switch is enabled. However, a malformed octal number after \o{
+always causes an error in Perl.
+</P>
+<P>
+If the PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL extra option is passed to
+<b>pcre2_compile()</b>, all unrecognized or erroneous escape sequences are
+treated as single-character escapes. For example, \j is a literal "j" and
+\x{2z} is treated as the literal string "x{2z}". Setting this option means
+that typos in patterns may go undetected and have unexpected results. This is a
+dangerous option. Use with care.
+<pre>
+  PCRE2_EXTRA_MATCH_LINE
+</pre>
+This option is provided for use by the <b>-x</b> option of <b>pcre2grep</b>. It
+causes the pattern only to match complete lines. This is achieved by
+automatically inserting the code for "^(?:" at the start of the compiled
+pattern and ")$" at the end. Thus, when PCRE2_MULTILINE is set, the matched
+line may be in the middle of the subject string. This option can be used with
+PCRE2_LITERAL.
+<pre>
+  PCRE2_EXTRA_MATCH_WORD
+</pre>
+This option is provided for use by the <b>-w</b> option of <b>pcre2grep</b>. It
+causes the pattern only to match strings that have a word boundary at the start
+and the end. This is achieved by automatically inserting the code for "\b(?:"
+at the start of the compiled pattern and ")\b" at the end. The option may be
+used with PCRE2_LITERAL. However, it is ignored if PCRE2_EXTRA_MATCH_LINE is
+also set.
 <a name="jitcompiling"></a></P>
-<br><a name="SEC20" href="#TOC1">JUST-IN-TIME (JIT) COMPILATION</a><br>
+<br><a name="SEC21" href="#TOC1">JUST-IN-TIME (JIT) COMPILATION</a><br>
 <P>
 <b>int pcre2_jit_compile(pcre2_code *<i>code</i>, uint32_t <i>options</i>);</b>
 <br>
@@ -1544,18 +1855,18 @@
 JIT compilation is a heavyweight optimization. It can take some time for
 patterns to be analyzed, and for one-off matches and simple patterns the
 benefit of faster execution might be offset by a much slower compilation time.
-Most, but not all patterns can be optimized by the JIT compiler.
+Most (but not all) patterns can be optimized by the JIT compiler.
 <a name="localesupport"></a></P>
-<br><a name="SEC21" href="#TOC1">LOCALE SUPPORT</a><br>
+<br><a name="SEC22" href="#TOC1">LOCALE SUPPORT</a><br>
 <P>
 PCRE2 handles caseless matching, and determines whether characters are letters,
 digits, or whatever, by reference to a set of tables, indexed by character code
 point. This applies only to characters whose code points are less than 256. By
 default, higher-valued code points never match escapes such as \w or \d.
-However, if PCRE2 is built with UTF support, all characters can be tested with
-\p and \P, or, alternatively, the PCRE2_UCP option can be set when a pattern
-is compiled; this causes \w and friends to use Unicode property support
-instead of the built-in tables.
+However, if PCRE2 is built with Unicode support, all characters can be tested
+with \p and \P, or, alternatively, the PCRE2_UCP option can be set when a
+pattern is compiled; this causes \w and friends to use Unicode property
+support instead of the built-in tables.
 </P>
 <P>
 The use of locales with Unicode is discouraged. If you are handling characters
@@ -1599,10 +1910,10 @@
 The pointer that is passed (via the compile context) to <b>pcre2_compile()</b>
 is saved with the compiled pattern, and the same tables are used by
 <b>pcre2_match()</b> and <b>pcre_dfa_match()</b>. Thus, for any single pattern,
-compilation, and matching all happen in the same locale, but different patterns
+compilation and matching both happen in the same locale, but different patterns
 can be processed in different locales.
 <a name="infoaboutpattern"></a></P>
-<br><a name="SEC22" href="#TOC1">INFORMATION ABOUT A COMPILED PATTERN</a><br>
+<br><a name="SEC23" href="#TOC1">INFORMATION ABOUT A COMPILED PATTERN</a><br>
 <P>
 <b>int pcre2_pattern_info(const pcre2 *<i>code</i>, uint32_t <i>what</i>, void *<i>where</i>);</b>
 </P>
@@ -1615,7 +1926,7 @@
 and the third argument is a pointer to a variable to receive the data. If the
 third argument is NULL, the first argument is ignored, and the function returns
 the size in bytes of the variable that is required for the information
-requested. Otherwise, The yield of the function is zero for success, or one of
+requested. Otherwise, the yield of the function is zero for success, or one of
 the following negative numbers:
 <pre>
   PCRE2_ERROR_NULL           the argument <i>code</i> was NULL
@@ -1639,12 +1950,15 @@
 <pre>
   PCRE2_INFO_ALLOPTIONS
   PCRE2_INFO_ARGOPTIONS
+  PCRE2_INFO_EXTRAOPTIONS
 </pre>
-Return a copy of the pattern's options. The third argument should point to a
+Return copies of the pattern's options. The third argument should point to a
 <b>uint32_t</b> variable. PCRE2_INFO_ARGOPTIONS returns exactly the options that
 were passed to <b>pcre2_compile()</b>, whereas PCRE2_INFO_ALLOPTIONS returns
 the compile options as modified by any top-level (*XXX) option settings such as
-(*UTF) at the start of the pattern itself.
+(*UTF) at the start of the pattern itself. PCRE2_INFO_EXTRAOPTIONS returns the
+extra options that were set in the compile context by calling the
+pcre2_set_compile_extra_options() function.
 </P>
 <P>
 For example, if the pattern /(*UTF)abc/ is compiled with the PCRE2_EXTENDED
@@ -1668,8 +1982,8 @@
   .* is not in an atomic group
   .* is not in a capturing group that is the subject of a back reference
   PCRE2_DOTALL is in force for .*
-  Neither (*PRUNE) nor (*SKIP) appears in the pattern.
-  PCRE2_NO_DOTSTAR_ANCHOR is not set.
+  Neither (*PRUNE) nor (*SKIP) appears in the pattern
+  PCRE2_NO_DOTSTAR_ANCHOR is not set
 </pre>
 For patterns that are auto-anchored, the PCRE2_ANCHORED bit is set in the
 options returned for PCRE2_INFO_ALLOPTIONS.
@@ -1697,6 +2011,15 @@
 where (?| is not used, this is also the total number of capturing subpatterns.
 The third argument should point to an <b>uint32_t</b> variable.
 <pre>
+  PCRE2_INFO_DEPTHLIMIT
+</pre>
+If the pattern set a backtracking depth limit by including an item of the form
+(*LIMIT_DEPTH=nnnn) at the start, the value is returned. The third argument
+should point to an unsigned 32-bit integer. If no such value has been set, the
+call to <b>pcre2_pattern_info()</b> returns the error PCRE2_ERROR_UNSET. Note
+that this limit will only be used during matching if it is less than the limit
+set or defaulted by the caller of the match function.
+<pre>
   PCRE2_INFO_FIRSTBITMAP
 </pre>
 In the absence of a single first code unit for a non-anchored pattern,
@@ -1713,21 +2036,29 @@
 Return information about the first code unit of any matched string, for a
 non-anchored pattern. The third argument should point to an <b>uint32_t</b>
 variable. If there is a fixed first value, for example, the letter "c" from a
-pattern such as (cat|cow|coyote), 1 is returned, and the character value can be
-retrieved using PCRE2_INFO_FIRSTCODEUNIT. If there is no fixed first value, but
-it is known that a match can occur only at the start of the subject or
-following a newline in the subject, 2 is returned. Otherwise, and for anchored
-patterns, 0 is returned.
+pattern such as (cat|cow|coyote), 1 is returned, and the value can be retrieved
+using PCRE2_INFO_FIRSTCODEUNIT. If there is no fixed first value, but it is
+known that a match can occur only at the start of the subject or following a
+newline in the subject, 2 is returned. Otherwise, and for anchored patterns, 0
+is returned.
 <pre>
   PCRE2_INFO_FIRSTCODEUNIT
 </pre>
-Return the value of the first code unit of any matched string in the situation
+Return the value of the first code unit of any matched string for a pattern
 where PCRE2_INFO_FIRSTCODETYPE returns 1; otherwise return 0. The third
 argument should point to an <b>uint32_t</b> variable. In the 8-bit library, the
 value is always less than 256. In the 16-bit library the value can be up to
 0xffff. In the 32-bit library in UTF-32 mode the value can be up to 0x10ffff,
 and up to 0xffffffff when not using UTF-32 mode.
 <pre>
+  PCRE2_INFO_FRAMESIZE
+</pre>
+Return the size (in bytes) of the data frames that are used to remember
+backtracking positions when the pattern is processed by <b>pcre2_match()</b>
+without the use of JIT. The third argument should point to an <b>size_t</b>
+variable. The frame size depends on the number of capturing parentheses in the
+pattern. Each additional capturing group adds two PCRE2_SIZE variables.
+<pre>
   PCRE2_INFO_HASBACKSLASHC
 </pre>
 Return 1 if the pattern contains any instances of \C, otherwise 0. The third
@@ -1737,7 +2068,17 @@
 </pre>
 Return 1 if the pattern contains any explicit matches for CR or LF characters,
 otherwise 0. The third argument should point to an <b>uint32_t</b> variable. An
-explicit match is either a literal CR or LF character, or \r or \n.
+explicit match is either a literal CR or LF character, or \r or \n or one of
+the equivalent hexadecimal or octal escape sequences.
+<pre>
+  PCRE2_INFO_HEAPLIMIT
+</pre>
+If the pattern set a heap memory limit by including an item of the form
+(*LIMIT_HEAP=nnnn) at the start, the value is returned. The third argument
+should point to an unsigned 32-bit integer. If no such value has been set, the
+call to <b>pcre2_pattern_info()</b> returns the error PCRE2_ERROR_UNSET. Note
+that this limit will only be used during matching if it is less than the limit
+set or defaulted by the caller of the match function.
 <pre>
   PCRE2_INFO_JCHANGED
 </pre>
@@ -1764,10 +2105,10 @@
 <pre>
   PCRE2_INFO_LASTCODEUNIT
 </pre>
-Return the value of the rightmost literal data unit that must exist in any
-matched string, other than at its start, if such a value has been recorded. The
-third argument should point to an <b>uint32_t</b> variable. If there is no such
-value, 0 is returned.
+Return the value of the rightmost literal code unit that must exist in any
+matched string, other than at its start, for a pattern where
+PCRE2_INFO_LASTCODETYPE returns 1. Otherwise, return 0. The third argument
+should point to an <b>uint32_t</b> variable.
 <pre>
   PCRE2_INFO_MATCHEMPTY
 </pre>
@@ -1782,7 +2123,9 @@
 If the pattern set a match limit by including an item of the form
 (*LIMIT_MATCH=nnnn) at the start, the value is returned. The third argument
 should point to an unsigned 32-bit integer. If no such value has been set, the
-call to <b>pcre2_pattern_info()</b> returns the error PCRE2_ERROR_UNSET.
+call to <b>pcre2_pattern_info()</b> returns the error PCRE2_ERROR_UNSET. Note
+that this limit will only be used during matching if it is less than the limit
+set or defaulted by the caller of the match function.
 <pre>
   PCRE2_INFO_MAXLOOKBEHIND
 </pre>
@@ -1794,7 +2137,8 @@
 lookbehind, though it does not actually inspect the previous character. This is
 to ensure that at least one character from the old segment is retained when a
 new segment is processed. Otherwise, if there are no lookbehinds in the
-pattern, \A might match incorrectly at the start of a new segment.
+pattern, \A might match incorrectly at the start of a second or subsequent
+segment.
 <pre>
   PCRE2_INFO_MINLENGTH
 </pre>
@@ -1874,23 +2218,17 @@
 <pre>
   PCRE2_INFO_NEWLINE
 </pre>
-The output is a <b>uint32_t</b> with one of the following values:
+The output is one of the following <b>uint32_t</b> values:
 <pre>
   PCRE2_NEWLINE_CR       Carriage return (CR)
   PCRE2_NEWLINE_LF       Linefeed (LF)
   PCRE2_NEWLINE_CRLF     Carriage return, linefeed (CRLF)
   PCRE2_NEWLINE_ANY      Any Unicode line ending
   PCRE2_NEWLINE_ANYCRLF  Any of CR, LF, or CRLF
+  PCRE2_NEWLINE_NUL      The NUL character (binary zero)
 </pre>
-This specifies the default character sequence that will be recognized as
-meaning "newline" while matching.
-<pre>
-  PCRE2_INFO_RECURSIONLIMIT
-</pre>
-If the pattern set a recursion limit by including an item of the form
-(*LIMIT_RECURSION=nnnn) at the start, the value is returned. The third
-argument should point to an unsigned 32-bit integer. If no such value has been
-set, the call to <b>pcre2_pattern_info()</b> returns the error PCRE2_ERROR_UNSET.
+This identifies the character sequence that will be recognized as meaning
+"newline" while matching.
 <pre>
   PCRE2_INFO_SIZE
 </pre>
@@ -1903,7 +2241,7 @@
 calculates the size has to over-estimate. Processing a pattern with the JIT
 compiler does not alter the value returned by this option.
 <a name="infoaboutcallouts"></a></P>
-<br><a name="SEC23" href="#TOC1">INFORMATION ABOUT A PATTERN'S CALLOUTS</a><br>
+<br><a name="SEC24" href="#TOC1">INFORMATION ABOUT A PATTERN'S CALLOUTS</a><br>
 <P>
 <b>int pcre2_callout_enumerate(const pcre2_code *<i>code</i>,</b>
 <b>  int (*<i>callback</i>)(pcre2_callout_enumerate_block *, void *),</b>
@@ -1922,7 +2260,7 @@
 <a href="pcre2callout.html"><b>pcre2callout</b></a>
 documentation, which also gives further details about callouts.
 </P>
-<br><a name="SEC24" href="#TOC1">SERIALIZATION AND PRECOMPILING</a><br>
+<br><a name="SEC25" href="#TOC1">SERIALIZATION AND PRECOMPILING</a><br>
 <P>
 It is possible to save compiled patterns on disc or elsewhere, and reload them
 later, subject to a number of restrictions. The functions whose names begin
@@ -1931,7 +2269,7 @@
 <a href="pcre2serialize.html"><b>pcre2serialize</b></a>
 documentation.
 <a name="matchdatablock"></a></P>
-<br><a name="SEC25" href="#TOC1">THE MATCH DATA BLOCK</a><br>
+<br><a name="SEC26" href="#TOC1">THE MATCH DATA BLOCK</a><br>
 <P>
 <b>pcre2_match_data *pcre2_match_data_create(uint32_t <i>ovecsize</i>,</b>
 <b>  pcre2_general_context *<i>gcontext</i>);</b>
@@ -1948,7 +2286,7 @@
 data block, which is an opaque structure that is accessed by function calls. In
 particular, the match data block contains a vector of offsets into the subject
 string that define the matched part of the subject and any substrings that were
-captured. This is know as the <i>ovector</i>.
+captured. This is known as the <i>ovector</i>.
 </P>
 <P>
 Before calling <b>pcre2_match()</b>, <b>pcre2_dfa_match()</b>, or
@@ -1956,9 +2294,9 @@
 the creation functions above. For <b>pcre2_match_data_create()</b>, the first
 argument is the number of pairs of offsets in the <i>ovector</i>. One pair of
 offsets is required to identify the string that matched the whole pattern, with
-another pair for each captured substring. For example, a value of 4 creates
-enough space to record the matched portion of the subject plus three captured
-substrings. A minimum of at least 1 pair is imposed by
+an additional pair for each captured substring. For example, a value of 4
+creates enough space to record the matched portion of the subject plus three
+captured substrings. A minimum of at least 1 pair is imposed by
 <b>pcre2_match_data_create()</b>, so it is always possible to return the overall
 matched string.
 </P>
@@ -2002,7 +2340,7 @@
 When a match data block itself is no longer needed, it should be freed by
 calling <b>pcre2_match_data_free()</b>.
 </P>
-<br><a name="SEC26" href="#TOC1">MATCHING A PATTERN: THE TRADITIONAL FUNCTION</a><br>
+<br><a name="SEC27" href="#TOC1">MATCHING A PATTERN: THE TRADITIONAL FUNCTION</a><br>
 <P>
 <b>int pcre2_match(const pcre2_code *<i>code</i>, PCRE2_SPTR <i>subject</i>,</b>
 <b>  PCRE2_SIZE <i>length</i>, PCRE2_SIZE <i>startoffset</i>,</b>
@@ -2033,7 +2371,7 @@
     11,             /* the length of the subject string */
     0,              /* start at offset 0 in the subject */
     0,              /* default options */
-    match_data,     /* the match data block */
+    md,             /* the match data block */
     NULL);          /* a match context; NULL means use defaults */
 </pre>
 If the subject string is zero-terminated, the length can be given as
@@ -2096,25 +2434,27 @@
 instead of one.
 </P>
 <P>
-If a non-zero starting offset is passed when the pattern is anchored, one
+If a non-zero starting offset is passed when the pattern is anchored, a single
 attempt to match at the given offset is made. This can only succeed if the
-pattern does not require the match to be at the start of the subject.
+pattern does not require the match to be at the start of the subject. In other
+words, the anchoring must be the result of setting the PCRE2_ANCHORED option or
+the use of .* with PCRE2_DOTALL, not by starting the pattern with ^ or \A.
 <a name="matchoptions"></a></P>
 <br><b>
 Option bits for <b>pcre2_match()</b>
 </b><br>
 <P>
 The unused bits of the <i>options</i> argument for <b>pcre2_match()</b> must be
-zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_NOTBOL,
-PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART, PCRE2_NO_JIT,
-PCRE2_NO_UTF_CHECK, PCRE2_PARTIAL_HARD, and PCRE2_PARTIAL_SOFT. Their action is
-described below.
+zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_ENDANCHORED,
+PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART,
+PCRE2_NO_JIT, PCRE2_NO_UTF_CHECK, PCRE2_PARTIAL_HARD, and PCRE2_PARTIAL_SOFT.
+Their action is described below.
 </P>
 <P>
-Setting PCRE2_ANCHORED at match time is not supported by the just-in-time (JIT)
-compiler. If it is set, JIT matching is disabled and the normal interpretive
-code in <b>pcre2_match()</b> is run. Apart from PCRE2_NO_JIT (obviously), the
-remaining options are supported for JIT matching.
+Setting PCRE2_ANCHORED or PCRE2_ENDANCHORED at match time is not supported by
+the just-in-time (JIT) compiler. If it is set, JIT matching is disabled and the
+interpretive code in <b>pcre2_match()</b> is run. Apart from PCRE2_NO_JIT
+(obviously), the remaining options are supported for JIT matching.
 <pre>
   PCRE2_ANCHORED
 </pre>
@@ -2124,6 +2464,12 @@
 matching time. Note that setting the option at match time disables JIT
 matching.
 <pre>
+  PCRE2_ENDANCHORED
+</pre>
+If the PCRE2_ENDANCHORED option is set, any string that <b>pcre2_match()</b>
+matches must be right at the end of the subject string. Note that setting the
+option at match time disables JIT matching.
+<pre>
   PCRE2_NOTBOL
 </pre>
 This option specifies that first character of the subject string is not the
@@ -2199,13 +2545,13 @@
 If you know that your subject is valid, and you want to skip these checks for
 performance reasons, you can set the PCRE2_NO_UTF_CHECK option when calling
 <b>pcre2_match()</b>. You might want to do this for the second and subsequent
-calls to <b>pcre2_match()</b> if you are making repeated calls to find all the
-matches in a single subject string.
+calls to <b>pcre2_match()</b> if you are making repeated calls to find other
+matches in the same subject string.
 </P>
 <P>
-NOTE: When PCRE2_NO_UTF_CHECK is set, the effect of passing an invalid string
-as a subject, or an invalid value of <i>startoffset</i>, is undefined. Your
-program may crash or loop indefinitely.
+WARNING: When PCRE2_NO_UTF_CHECK is set, the effect of passing an invalid
+string as a subject, or an invalid value of <i>startoffset</i>, is undefined.
+Your program may crash or loop indefinitely.
 <pre>
   PCRE2_PARTIAL_HARD
   PCRE2_PARTIAL_SOFT
@@ -2232,7 +2578,7 @@
 <a href="pcre2partial.html"><b>pcre2partial</b></a>
 documentation.
 </P>
-<br><a name="SEC27" href="#TOC1">NEWLINE HANDLING WHEN MATCHING</a><br>
+<br><a name="SEC28" href="#TOC1">NEWLINE HANDLING WHEN MATCHING</a><br>
 <P>
 When PCRE2 is built, a default newline convention is set; this is usually the
 standard convention for the operating system. The default can be overridden in
@@ -2264,15 +2610,15 @@
 </P>
 <P>
 An explicit match for CR of LF is either a literal appearance of one of those
-characters in the pattern, or one of the \r or \n escape sequences. Implicit
-matches such as [^X] do not count, nor does \s, even though it includes CR and
-LF in the characters that it matches.
+characters in the pattern, or one of the \r or \n or equivalent octal or
+hexadecimal escape sequences. Implicit matches such as [^X] do not count, nor
+does \s, even though it includes CR and LF in the characters that it matches.
 </P>
 <P>
 Notwithstanding the above, anomalous effects may still occur when CRLF is a
 valid newline sequence and explicit \r or \n escapes appear in the pattern.
 <a name="matchedstrings"></a></P>
-<br><a name="SEC28" href="#TOC1">HOW PCRE2_MATCH() RETURNS A STRING AND CAPTURED SUBSTRINGS</a><br>
+<br><a name="SEC29" href="#TOC1">HOW PCRE2_MATCH() RETURNS A STRING AND CAPTURED SUBSTRINGS</a><br>
 <P>
 <b>uint32_t pcre2_get_ovector_count(pcre2_match_data *<i>match_data</i>);</b>
 <br>
@@ -2322,12 +2668,12 @@
 documentation for details of partial matching.
 </P>
 <P>
-After a successful match, the first pair of offsets identifies the portion of
-the subject string that was matched by the entire pattern. The next pair is
-used for the first capturing subpattern, and so on. The value returned by
+After a fully successful match, the first pair of offsets identifies the
+portion of the subject string that was matched by the entire pattern. The next
+pair is used for the first captured substring, and so on. The value returned by
 <b>pcre2_match()</b> is one more than the highest numbered pair that has been
 set. For example, if two substrings have been captured, the returned value is
-3. If there are no capturing subpatterns, the return value from a successful
+3. If there are no captured substrings, the return value from a successful
 match is 1, indicating that just the first pair of offsets has been set.
 </P>
 <P>
@@ -2345,11 +2691,7 @@
 If the ovector is too small to hold all the captured substring offsets, as much
 as possible is filled in, and the function returns a value of zero. If captured
 substrings are not of interest, <b>pcre2_match()</b> may be called with a match
-data block whose ovector is of minimum length (that is, one pair). However, if
-the pattern contains back references and the <i>ovector</i> is not big enough to
-remember the related substrings, PCRE2 has to get additional memory for use
-during matching. Thus it is usually advisable to set up a match data block
-containing an ovector of reasonable size.
+data block whose ovector is of minimum length (that is, one pair).
 </P>
 <P>
 It is possible for capturing subpattern number <i>n+1</i> to match some part of
@@ -2375,7 +2717,7 @@
 <b>pcre2_match()</b>. The other elements retain whatever values they previously
 had.
 <a name="matchotherdata"></a></P>
-<br><a name="SEC29" href="#TOC1">OTHER INFORMATION ABOUT A MATCH</a><br>
+<br><a name="SEC30" href="#TOC1">OTHER INFORMATION ABOUT A MATCH</a><br>
 <P>
 <b>PCRE2_SPTR pcre2_get_mark(pcre2_match_data *<i>match_data</i>);</b>
 <br>
@@ -2390,25 +2732,28 @@
 </P>
 <P>
 After a successful match, a partial match (PCRE2_ERROR_PARTIAL), or a failure
-to match (PCRE2_ERROR_NOMATCH), a (*MARK) name may be available, and
-<b>pcre2_get_mark()</b> can be called. It returns a pointer to the
-zero-terminated name, which is within the compiled pattern. Otherwise NULL is
-returned. The length of the (*MARK) name (excluding the terminating zero) is
-stored in the code unit that preceeds the name. You should use this instead of
-relying on the terminating zero if the (*MARK) name might contain a binary
-zero.
+to match (PCRE2_ERROR_NOMATCH), a (*MARK), (*PRUNE), or (*THEN) name may be
+available. The function <b>pcre2_get_mark()</b> can be called to access this
+name. The same function applies to all three verbs. It returns a pointer to the
+zero-terminated name, which is within the compiled pattern. If no name is
+available, NULL is returned. The length of the name (excluding the terminating
+zero) is stored in the code unit that precedes the name. You should use this
+length instead of relying on the terminating zero if the name might contain a
+binary zero.
 </P>
 <P>
-After a successful match, the (*MARK) name that is returned is the
-last one encountered on the matching path through the pattern. After a "no
-match" or a partial match, the last encountered (*MARK) name is returned. For
-example, consider this pattern:
+After a successful match, the name that is returned is the last (*MARK),
+(*PRUNE), or (*THEN) name encountered on the matching path through the pattern.
+Instances of (*PRUNE) and (*THEN) without names are ignored. Thus, for example,
+if the matching path contains (*MARK:A)(*PRUNE), the name "A" is returned.
+After a "no match" or a partial match, the last encountered name is returned.
+For example, consider this pattern:
 <pre>
   ^(*MARK:A)((*MARK:B)a|b)c
 </pre>
-When it matches "bc", the returned mark is A. The B mark is "seen" in the first
+When it matches "bc", the returned name is A. The B mark is "seen" in the first
 branch of the group, but it is not on the matching path. On the other hand,
-when this pattern fails to match "bx", the returned mark is B.
+when this pattern fails to match "bx", the returned name is B.
 </P>
 <P>
 After a successful match, a partial match, or one of the invalid UTF errors
@@ -2425,7 +2770,7 @@
 <a href="pcre2unicode.html"><b>pcre2unicode</b></a>
 page.
 <a name="errorlist"></a></P>
-<br><a name="SEC30" href="#TOC1">ERROR RETURNS FROM <b>pcre2_match()</b></a><br>
+<br><a name="SEC31" href="#TOC1">ERROR RETURNS FROM <b>pcre2_match()</b></a><br>
 <P>
 If <b>pcre2_match()</b> fails, it returns a negative number. This can be
 converted to a text string by calling the <b>pcre2_get_error_message()</b>
@@ -2457,8 +2802,9 @@
 <pre>
   PCRE2_ERROR_BADMODE
 </pre>
-This error is given when a pattern that was compiled by the 8-bit library is
-passed to a 16-bit or 32-bit library function, or vice versa.
+This error is given when a compiled pattern is passed to a function in a
+library of a different code unit width, for example, a pattern compiled by
+the 8-bit library is passed to a 16-bit or 32-bit library function.
 <pre>
   PCRE2_ERROR_BADOFFSET
 </pre>
@@ -2483,20 +2829,19 @@
 <a href="pcre2callout.html"><b>pcre2callout</b></a>
 documentation for details.
 <pre>
+  PCRE2_ERROR_DEPTHLIMIT
+</pre>
+The nested backtracking depth limit was reached.
+<pre>
+  PCRE2_ERROR_HEAPLIMIT
+</pre>
+The heap limit was reached.
+<pre>
   PCRE2_ERROR_INTERNAL
 </pre>
 An unexpected internal error has occurred. This error could be caused by a bug
 in PCRE2 or by overwriting of the compiled pattern.
 <pre>
-  PCRE2_ERROR_JIT_BADOPTION
-</pre>
-This error is returned when a pattern that was successfully studied using JIT
-is being matched, but the matching mode (partial or complete match) does not
-correspond to any JIT compilation mode. When the JIT fast path function is
-used, this error may be also given for invalid options. See the
-<a href="pcre2jit.html"><b>pcre2jit</b></a>
-documentation for more details.
-<pre>
   PCRE2_ERROR_JIT_STACKLIMIT
 </pre>
 This error is returned when a pattern that was successfully studied using JIT
@@ -2507,15 +2852,14 @@
 <pre>
   PCRE2_ERROR_MATCHLIMIT
 </pre>
-The backtracking limit was reached.
+The backtracking match limit was reached.
 <pre>
   PCRE2_ERROR_NOMEMORY
 </pre>
-If a pattern contains back references, but the ovector is not big enough to
-remember the referenced substrings, PCRE2 gets a block of memory at the start
-of matching to use for this purpose. There are some other special cases where
-extra memory is needed during matching. This error is given when memory cannot
-be obtained.
+If a pattern contains many nested backtracking points, heap memory is used to
+remember them. This error is given when the memory allocation function (default
+or custom) fails. Note that a different error, PCRE2_ERROR_HEAPLIMIT, is given
+if the amount of memory needed exceeds the heap limit.
 <pre>
   PCRE2_ERROR_NULL
 </pre>
@@ -2531,12 +2875,8 @@
 faulted at compile time, but more complicated cases, in particular mutual
 recursions between two different subpatterns, cannot be detected until matching
 is attempted.
-<pre>
-  PCRE2_ERROR_RECURSIONLIMIT
-</pre>
-The internal recursion limit was reached.
 <a name="geterrormessage"></a></P>
-<br><a name="SEC31" href="#TOC1">OBTAINING A TEXTUAL ERROR MESSAGE</a><br>
+<br><a name="SEC32" href="#TOC1">OBTAINING A TEXTUAL ERROR MESSAGE</a><br>
 <P>
 <b>int pcre2_get_error_message(int <i>errorcode</i>, PCRE2_UCHAR *<i>buffer</i>,</b>
 <b>  PCRE2_SIZE <i>bufflen</i>);</b>
@@ -2545,8 +2885,8 @@
 A text message for an error code from any PCRE2 function (compile, match, or
 auxiliary) can be obtained by calling <b>pcre2_get_error_message()</b>. The code
 is passed as the first argument, with the remaining two arguments specifying a
-code unit buffer and its length, into which the text message is placed. Note
-that the message is returned in code units of the appropriate width for the
+code unit buffer and its length in code units, into which the text message is
+placed. The message is returned in code units of the appropriate width for the
 library that is being used.
 </P>
 <P>
@@ -2557,7 +2897,7 @@
 a trailing zero), and the negative error code PCRE2_ERROR_NOMEMORY is returned.
 None of the messages are very long; a buffer size of 120 code units is ample.
 <a name="extractbynumber"></a></P>
-<br><a name="SEC32" href="#TOC1">EXTRACTING CAPTURED SUBSTRINGS BY NUMBER</a><br>
+<br><a name="SEC33" href="#TOC1">EXTRACTING CAPTURED SUBSTRINGS BY NUMBER</a><br>
 <P>
 <b>int pcre2_substring_length_bynumber(pcre2_match_data *<i>match_data</i>,</b>
 <b>  uint32_t <i>number</i>, PCRE2_SIZE *<i>length</i>);</b>
@@ -2654,7 +2994,7 @@
 (abc)|(def) and the subject is "def", and the ovector contains at least two
 capturing slots, substring number 1 is unset.
 </P>
-<br><a name="SEC33" href="#TOC1">EXTRACTING A LIST OF ALL CAPTURED SUBSTRINGS</a><br>
+<br><a name="SEC34" href="#TOC1">EXTRACTING A LIST OF ALL CAPTURED SUBSTRINGS</a><br>
 <P>
 <b>int pcre2_substring_list_get(pcre2_match_data *<i>match_data</i>,</b>
 <b>"  PCRE2_UCHAR ***<i>listptr</i>, PCRE2_SIZE **<i>lengthsptr</i>);</b>
@@ -2693,7 +3033,7 @@
 appropriate offset in the ovector, which contain PCRE2_UNSET for unset
 substrings, or by calling <b>pcre2_substring_length_bynumber()</b>.
 <a name="extractbyname"></a></P>
-<br><a name="SEC34" href="#TOC1">EXTRACTING CAPTURED SUBSTRINGS BY NAME</a><br>
+<br><a name="SEC35" href="#TOC1">EXTRACTING CAPTURED SUBSTRINGS BY NAME</a><br>
 <P>
 <b>int pcre2_substring_number_from_name(const pcre2_code *<i>code</i>,</b>
 <b>  PCRE2_SPTR <i>name</i>);</b>
@@ -2725,8 +3065,8 @@
 compiled pattern, and the second is the name. The yield of the function is the
 subpattern number, PCRE2_ERROR_NOSUBSTRING if there is no subpattern of that
 name, or PCRE2_ERROR_NOUNIQUESUBSTRING if there is more than one subpattern of
-that name. Given the number, you can extract the substring directly, or use one
-of the functions described above.
+that name. Given the number, you can extract the substring directly from the
+ovector, or use one of the "bynumber" functions described above.
 </P>
 <P>
 For convenience, there are also "byname" functions that correspond to the
@@ -2753,7 +3093,7 @@
 numbers. For this reason, the use of different names for subpatterns of the
 same number causes an error at compile time.
 </P>
-<br><a name="SEC35" href="#TOC1">CREATING A NEW STRING WITH SUBSTITUTIONS</a><br>
+<br><a name="SEC36" href="#TOC1">CREATING A NEW STRING WITH SUBSTITUTIONS</a><br>
 <P>
 <b>int pcre2_substitute(const pcre2_code *<i>code</i>, PCRE2_SPTR <i>subject</i>,</b>
 <b>  PCRE2_SIZE <i>length</i>, PCRE2_SIZE <i>startoffset</i>,</b>
@@ -2800,12 +3140,12 @@
 In the replacement string, which is interpreted as a UTF string in UTF mode,
 and is checked for UTF validity unless the PCRE2_NO_UTF_CHECK option is set, a
 dollar character is an escape character that can specify the insertion of
-characters from capturing groups or (*MARK) items in the pattern. The following
-forms are always recognized:
+characters from capturing groups or (*MARK), (*PRUNE), or (*THEN) items in the
+pattern. The following forms are always recognized:
 <pre>
   $$                  insert a dollar character
   $&#60;n&#62; or ${&#60;n&#62;}      insert the contents of group &#60;n&#62;
-  $*MARK or ${*MARK}  insert the name of the last (*MARK) encountered
+  $*MARK or ${*MARK}  insert a (*MARK), (*PRUNE), or (*THEN) name
 </pre>
 Either a group number or a group name can be given for &#60;n&#62;. Curly brackets are
 required only if the following character would be interpreted as part of the
@@ -2814,25 +3154,43 @@
 string "+$1$0$1+", the result is "=+babcb+=".
 </P>
 <P>
-The facility for inserting a (*MARK) name can be used to perform simple
-simultaneous substitutions, as this <b>pcre2test</b> example shows:
+$*MARK inserts the name from the last encountered (*MARK), (*PRUNE), or (*THEN)
+on the matching path that has a name. (*MARK) must always include a name, but
+(*PRUNE) and (*THEN) need not. For example, in the case of (*MARK:A)(*PRUNE)
+the name inserted is "A", but for (*MARK:A)(*PRUNE:B) the relevant name is "B".
+This facility can be used to perform simple simultaneous substitutions, as this
+<b>pcre2test</b> example shows:
 <pre>
-  /(*:pear)apple|(*:orange)lemon/g,replace=${*MARK}
+  /(*MARK:pear)apple|(*MARK:orange)lemon/g,replace=${*MARK}
       apple lemon
    2: pear orange
 </pre>
 As well as the usual options for <b>pcre2_match()</b>, a number of additional
-options can be set in the <i>options</i> argument.
+options can be set in the <i>options</i> argument of <b>pcre2_substitute()</b>.
 </P>
 <P>
 PCRE2_SUBSTITUTE_GLOBAL causes the function to iterate over the subject string,
-replacing every matching substring. If this is not set, only the first matching
-substring is replaced. If any matched substring has zero length, after the
-substitution has happened, an attempt to find a non-empty match at the same
-position is performed. If this is not successful, the current position is
-advanced by one character except when CRLF is a valid newline sequence and the
-next two characters are CR, LF. In this case, the current position is advanced
-by two characters.
+replacing every matching substring. If this option is not set, only the first
+matching substring is replaced. The search for matches takes place in the
+original subject string (that is, previous replacements do not affect it).
+Iteration is implemented by advancing the <i>startoffset</i> value for each
+search, which is always passed the entire subject string. If an offset limit is
+set in the match context, searching stops when that limit is reached.
+</P>
+<P>
+You can restrict the effect of a global substitution to a portion of the
+subject string by setting either or both of <i>startoffset</i> and an offset
+limit. Here is a \fPpcre2test\fP example:
+<pre>
+  /B/g,replace=!,use_offset_limit
+  ABC ABC ABC ABC\=offset=3,offset_limit=12
+   2: ABC A!C A!C ABC
+</pre>
+When continuing with global substitutions after matching a substring with zero
+length, an attempt to find a non-empty match at the same offset is performed.
+If this is not successful, the offset is advanced by one character except when
+CRLF is a valid newline sequence and the next two characters are CR, LF. In
+this case, the offset is advanced by two characters.
 </P>
 <P>
 PCRE2_SUBSTITUTE_OVERFLOW_LENGTH changes what happens when the output buffer is
@@ -2949,10 +3307,10 @@
 <P>
 PCRE2_ERROR_BADREPLACEMENT is used for miscellaneous syntax errors in the
 replacement string, with more particular errors being PCRE2_ERROR_BADREPESCAPE
-(invalid escape sequence), PCRE2_ERROR_REPMISSING_BRACE (closing curly bracket
-not found), PCRE2_BADSUBSTITUTION (syntax error in extended group
-substitution), and PCRE2_BADSUBPATTERN (the pattern match ended before it
-started, which can happen if \K is used in an assertion).
+(invalid escape sequence), PCRE2_ERROR_REPMISSINGBRACE (closing curly bracket
+not found), PCRE2_ERROR_BADSUBSTITUTION (syntax error in extended group
+substitution), and PCRE2_ERROR_BADSUBSPATTERN (the pattern match ended before
+it started, which can happen if \K is used in an assertion).
 </P>
 <P>
 As for all PCRE2 errors, a text message that describes the error can be
@@ -2960,7 +3318,7 @@
 "Obtaining a textual error message"
 <a href="#geterrormessage">above).</a>
 </P>
-<br><a name="SEC36" href="#TOC1">DUPLICATE SUBPATTERN NAMES</a><br>
+<br><a name="SEC37" href="#TOC1">DUPLICATE SUBPATTERN NAMES</a><br>
 <P>
 <b>int pcre2_substring_nametable_scan(const pcre2_code *<i>code</i>,</b>
 <b>  PCRE2_SPTR <i>name</i>, PCRE2_SPTR *<i>first</i>, PCRE2_SPTR *<i>last</i>);</b>
@@ -3005,7 +3363,7 @@
 relevant entries for the name, you can extract each of their numbers, and hence
 the captured data.
 </P>
-<br><a name="SEC37" href="#TOC1">FINDING ALL POSSIBLE MATCHES AT ONE POSITION</a><br>
+<br><a name="SEC38" href="#TOC1">FINDING ALL POSSIBLE MATCHES AT ONE POSITION</a><br>
 <P>
 The traditional matching function uses a similar algorithm to Perl, which stops
 when it finds the first match at a given point in the subject. If you want to
@@ -3023,7 +3381,7 @@
 other alternatives. Ultimately, when it runs out of matches,
 <b>pcre2_match()</b> will yield PCRE2_ERROR_NOMATCH.
 <a name="dfamatch"></a></P>
-<br><a name="SEC38" href="#TOC1">MATCHING A PATTERN: THE ALTERNATIVE FUNCTION</a><br>
+<br><a name="SEC39" href="#TOC1">MATCHING A PATTERN: THE ALTERNATIVE FUNCTION</a><br>
 <P>
 <b>int pcre2_dfa_match(const pcre2_code *<i>code</i>, PCRE2_SPTR <i>subject</i>,</b>
 <b>  PCRE2_SIZE <i>length</i>, PCRE2_SIZE <i>startoffset</i>,</b>
@@ -3034,11 +3392,12 @@
 <P>
 The function <b>pcre2_dfa_match()</b> is called to match a subject string
 against a compiled pattern, using a matching algorithm that scans the subject
-string just once, and does not backtrack. This has different characteristics to
-the normal algorithm, and is not compatible with Perl. Some of the features of
-PCRE2 patterns are not supported. Nevertheless, there are times when this kind
-of matching can be useful. For a discussion of the two matching algorithms, and
-a list of features that <b>pcre2_dfa_match()</b> does not support, see the
+string just once (not counting lookaround assertions), and does not backtrack.
+This has different characteristics to the normal algorithm, and is not
+compatible with Perl. Some of the features of PCRE2 patterns are not supported.
+Nevertheless, there are times when this kind of matching can be useful. For a
+discussion of the two matching algorithms, and a list of features that
+<b>pcre2_dfa_match()</b> does not support, see the
 <a href="pcre2matching.html"><b>pcre2matching</b></a>
 documentation.
 </P>
@@ -3066,7 +3425,7 @@
     11,             /* the length of the subject string */
     0,              /* start at offset 0 in the subject */
     0,              /* default options */
-    match_data,     /* the match data block */
+    md,             /* the match data block */
     NULL,           /* a match context; NULL means use defaults */
     wspace,         /* working space vector */
     20);            /* number of elements (NOT size in bytes) */
@@ -3077,11 +3436,11 @@
 </b><br>
 <P>
 The unused bits of the <i>options</i> argument for <b>pcre2_dfa_match()</b> must
-be zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_NOTBOL,
-PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART, PCRE2_NO_UTF_CHECK,
-PCRE2_PARTIAL_HARD, PCRE2_PARTIAL_SOFT, PCRE2_DFA_SHORTEST, and
-PCRE2_DFA_RESTART. All but the last four of these are exactly the same as for
-<b>pcre2_match()</b>, so their description is not repeated here.
+be zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_ENDANCHORED,
+PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART,
+PCRE2_NO_UTF_CHECK, PCRE2_PARTIAL_HARD, PCRE2_PARTIAL_SOFT, PCRE2_DFA_SHORTEST,
+and PCRE2_DFA_RESTART. All but the last four of these are exactly the same as
+for <b>pcre2_match()</b>, so their description is not repeated here.
 <pre>
   PCRE2_PARTIAL_HARD
   PCRE2_PARTIAL_SOFT
@@ -3174,7 +3533,7 @@
 repeats at the end of a pattern (as well as internally). For example, the
 pattern "a\d+" is compiled as if it were "a\d++". For DFA matching, this
 means that only one possible match is found. If you really do want multiple
-matches in such cases, either use an ungreedy repeat auch as "a\d+?" or set
+matches in such cases, either use an ungreedy repeat such as "a\d+?" or set
 the PCRE2_NO_AUTO_POSSESS option when compiling.
 </P>
 <br><b>
@@ -3218,13 +3577,13 @@
 should contain data about the previous partial match. If any of these checks
 fail, this error is given.
 </P>
-<br><a name="SEC39" href="#TOC1">SEE ALSO</a><br>
+<br><a name="SEC40" href="#TOC1">SEE ALSO</a><br>
 <P>
 <b>pcre2build</b>(3), <b>pcre2callout</b>(3), <b>pcre2demo(3)</b>,
 <b>pcre2matching</b>(3), <b>pcre2partial</b>(3), <b>pcre2posix</b>(3),
-<b>pcre2sample</b>(3), <b>pcre2stack</b>(3), <b>pcre2unicode</b>(3).
+<b>pcre2sample</b>(3), <b>pcre2unicode</b>(3).
 </P>
-<br><a name="SEC40" href="#TOC1">AUTHOR</a><br>
+<br><a name="SEC41" href="#TOC1">AUTHOR</a><br>
 <P>
 Philip Hazel
 <br>
@@ -3233,11 +3592,11 @@
 Cambridge, England.
 <br>
 </P>
-<br><a name="SEC41" href="#TOC1">REVISION</a><br>
+<br><a name="SEC42" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 17 June 2016
+Last updated: 31 December 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2build.html b/dist2/doc/html/pcre2build.html
index 6c8e1de..823e605 100644
--- a/dist2/doc/html/pcre2build.html
+++ b/dist2/doc/html/pcre2build.html
@@ -23,20 +23,21 @@
 <li><a name="TOC8" href="#SEC8">NEWLINE RECOGNITION</a>
 <li><a name="TOC9" href="#SEC9">WHAT \R MATCHES</a>
 <li><a name="TOC10" href="#SEC10">HANDLING VERY LARGE PATTERNS</a>
-<li><a name="TOC11" href="#SEC11">AVOIDING EXCESSIVE STACK USAGE</a>
-<li><a name="TOC12" href="#SEC12">LIMITING PCRE2 RESOURCE USAGE</a>
-<li><a name="TOC13" href="#SEC13">CREATING CHARACTER TABLES AT BUILD TIME</a>
-<li><a name="TOC14" href="#SEC14">USING EBCDIC CODE</a>
-<li><a name="TOC15" href="#SEC15">PCRE2GREP SUPPORT FOR EXTERNAL SCRIPTS</a>
-<li><a name="TOC16" href="#SEC16">PCRE2GREP OPTIONS FOR COMPRESSED FILE SUPPORT</a>
-<li><a name="TOC17" href="#SEC17">PCRE2GREP BUFFER SIZE</a>
-<li><a name="TOC18" href="#SEC18">PCRE2TEST OPTION FOR LIBREADLINE SUPPORT</a>
-<li><a name="TOC19" href="#SEC19">INCLUDING DEBUGGING CODE</a>
-<li><a name="TOC20" href="#SEC20">DEBUGGING WITH VALGRIND SUPPORT</a>
-<li><a name="TOC21" href="#SEC21">CODE COVERAGE REPORTING</a>
-<li><a name="TOC22" href="#SEC22">SEE ALSO</a>
-<li><a name="TOC23" href="#SEC23">AUTHOR</a>
-<li><a name="TOC24" href="#SEC24">REVISION</a>
+<li><a name="TOC11" href="#SEC11">LIMITING PCRE2 RESOURCE USAGE</a>
+<li><a name="TOC12" href="#SEC12">CREATING CHARACTER TABLES AT BUILD TIME</a>
+<li><a name="TOC13" href="#SEC13">USING EBCDIC CODE</a>
+<li><a name="TOC14" href="#SEC14">PCRE2GREP SUPPORT FOR EXTERNAL SCRIPTS</a>
+<li><a name="TOC15" href="#SEC15">PCRE2GREP OPTIONS FOR COMPRESSED FILE SUPPORT</a>
+<li><a name="TOC16" href="#SEC16">PCRE2GREP BUFFER SIZE</a>
+<li><a name="TOC17" href="#SEC17">PCRE2TEST OPTION FOR LIBREADLINE SUPPORT</a>
+<li><a name="TOC18" href="#SEC18">INCLUDING DEBUGGING CODE</a>
+<li><a name="TOC19" href="#SEC19">DEBUGGING WITH VALGRIND SUPPORT</a>
+<li><a name="TOC20" href="#SEC20">CODE COVERAGE REPORTING</a>
+<li><a name="TOC21" href="#SEC21">SUPPORT FOR FUZZERS</a>
+<li><a name="TOC22" href="#SEC22">OBSOLETE OPTION</a>
+<li><a name="TOC23" href="#SEC23">SEE ALSO</a>
+<li><a name="TOC24" href="#SEC24">AUTHOR</a>
+<li><a name="TOC25" href="#SEC25">REVISION</a>
 </ul>
 <br><a name="SEC1" href="#TOC1">BUILDING PCRE2</a><br>
 <P>
@@ -77,19 +78,19 @@
 <pre>
   ./configure --help
 </pre>
-The following sections include descriptions of options whose names begin with
---enable or --disable. These settings specify changes to the defaults for the
-<b>configure</b> command. Because of the way that <b>configure</b> works,
---enable and --disable always come in pairs, so the complementary option always
-exists as well, but as it specifies the default, it is not described.
+The following sections include descriptions of "on/off" options whose names
+begin with --enable or --disable. Because of the way that <b>configure</b>
+works, --enable and --disable always come in pairs, so the complementary option
+always exists as well, but as it specifies the default, it is not described.
+Options that specify values have names that start with --with.
 </P>
 <br><a name="SEC3" href="#TOC1">BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES</a><br>
 <P>
 By default, a library called <b>libpcre2-8</b> is built, containing functions
-that take string arguments contained in vectors of bytes, interpreted either as
+that take string arguments contained in arrays of bytes, interpreted either as
 single-byte characters, or UTF-8 strings. You can also build two other
 libraries, called <b>libpcre2-16</b> and <b>libpcre2-32</b>, which process
-strings that are contained in vectors of 16-bit and 32-bit code units,
+strings that are contained in arrays of 16-bit and 32-bit code units,
 respectively. These can be interpreted either as single-unit characters or
 UTF-16/UTF-32 strings. To build these additional libraries, add one or both of
 the following to the <b>configure</b> command:
@@ -137,10 +138,10 @@
 </P>
 <P>
 UTF support allows the libraries to process character code points up to
-0x10ffff in the strings that they handle. It also provides support for
-accessing the Unicode properties of such characters, using pattern escapes such
-as \P, \p, and \X. Only the general category properties such as <i>Lu</i> and
-<i>Nd</i> are supported. Details are given in the
+0x10ffff in the strings that they handle. Unicode support also gives access to
+the Unicode properties of characters, using pattern escapes such as \P, \p,
+and \X. Only the general category properties such as <i>Lu</i> and <i>Nd</i> are
+supported. Details are given in the
 <a href="pcre2pattern.html"><b>pcre2pattern</b></a>
 documentation.
 </P>
@@ -164,13 +165,18 @@
 </P>
 <br><a name="SEC7" href="#TOC1">JUST-IN-TIME COMPILER SUPPORT</a><br>
 <P>
-Just-in-time compiler support is included in the build by specifying
+Just-in-time (JIT) compiler support is included in the build by specifying
 <pre>
   --enable-jit
 </pre>
 This support is available only for certain hardware architectures. If this
-option is set for an unsupported architecture, a building error occurs.
-See the
+option is set for an unsupported architecture, a building error occurs. If you
+are running under SELinux you may also want to add
+<pre>
+  --enable-jit-sealloc
+</pre>
+which enables the use of an execmem allocator in JIT that is compatible with
+SELinux. This has no effect if JIT is not enabled. See the
 <a href="pcre2jit.html"><b>pcre2jit</b></a>
 documentation for a discussion of JIT usage. When JIT support is enabled,
 pcre2grep automatically makes use of it, unless you add
@@ -202,19 +208,23 @@
   --enable-newline-is-anycrlf
 </pre>
 which causes PCRE2 to recognize any of the three sequences CR, LF, or CRLF as
-indicating a line ending. Finally, a fifth option, specified by
+indicating a line ending. A fifth option, specified by
 <pre>
   --enable-newline-is-any
 </pre>
 causes PCRE2 to recognize any Unicode newline sequence. The Unicode newline
 sequences are the three just mentioned, plus the single characters VT (vertical
 tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line
-separator, U+2028), and PS (paragraph separator, U+2029).
+separator, U+2028), and PS (paragraph separator, U+2029). The final option is
+<pre>
+  --enable-newline-is-nul
+</pre>
+which causes NUL (binary zero) is set as the default line-ending character.
 </P>
 <P>
 Whatever default line ending convention is selected when PCRE2 is built can be
 overridden by applications that use the library. At build time it is
-conventional to use the standard for your operating system.
+recommended to use the standard for your operating system.
 </P>
 <br><a name="SEC9" href="#TOC1">WHAT \R MATCHES</a><br>
 <P>
@@ -226,7 +236,7 @@
 </pre>
 the default is changed so that \R matches only CR, LF, or CRLF. Whatever is
 selected when PCRE2 is built can be overridden by applications that use the
-called.
+library.
 </P>
 <br><a name="SEC10" href="#TOC1">HANDLING VERY LARGE PATTERNS</a><br>
 <P>
@@ -247,58 +257,62 @@
 additional data when handling them. For the 32-bit library the value is always
 4 and cannot be overridden; the value of --with-link-size is ignored.
 </P>
-<br><a name="SEC11" href="#TOC1">AVOIDING EXCESSIVE STACK USAGE</a><br>
+<br><a name="SEC11" href="#TOC1">LIMITING PCRE2 RESOURCE USAGE</a><br>
 <P>
-When matching with the <b>pcre2_match()</b> function, PCRE2 implements
-backtracking by making recursive calls to an internal function called
-<b>match()</b>. In environments where the size of the stack is limited, this can
-severely limit PCRE2's operation. (The Unix environment does not usually suffer
-from this problem, but it may sometimes be necessary to increase the maximum
-stack size. There is a discussion in the
-<a href="pcre2stack.html"><b>pcre2stack</b></a>
-documentation.) An alternative approach to recursion that uses memory from the
-heap to remember data, instead of using recursive function calls, has been
-implemented to work round the problem of limited stack size. If you want to
-build a version of PCRE2 that works this way, add
-<pre>
-  --disable-stack-for-recursion
-</pre>
-to the <b>configure</b> command. By default, the system functions <b>malloc()</b>
-and <b>free()</b> are called to manage the heap memory that is required, but
-custom memory management functions can be called instead. PCRE2 runs noticeably
-more slowly when built in this way. This option affects only the
-<b>pcre2_match()</b> function; it is not relevant for <b>pcre2_dfa_match()</b>.
-</P>
-<br><a name="SEC12" href="#TOC1">LIMITING PCRE2 RESOURCE USAGE</a><br>
-<P>
-Internally, PCRE2 has a function called <b>match()</b>, which it calls
-repeatedly (sometimes recursively) when matching a pattern with the
-<b>pcre2_match()</b> function. By controlling the maximum number of times this
-function may be called during a single matching operation, a limit can be
-placed on the resources used by a single call to <b>pcre2_match()</b>. The limit
-can be changed at run time, as described in the
+The <b>pcre2_match()</b> function increments a counter each time it goes round
+its main loop. Putting a limit on this counter controls the amount of computing
+resource used by a single call to <b>pcre2_match()</b>. The limit can be changed
+at run time, as described in the
 <a href="pcre2api.html"><b>pcre2api</b></a>
 documentation. The default is 10 million, but this can be changed by adding a
 setting such as
 <pre>
   --with-match-limit=500000
 </pre>
-to the <b>configure</b> command. This setting has no effect on the
-<b>pcre2_dfa_match()</b> matching function.
+to the <b>configure</b> command. This setting also applies to the
+<b>pcre2_dfa_match()</b> matching function, and to JIT matching (though the
+counting is done differently).
 </P>
 <P>
-In some environments it is desirable to limit the depth of recursive calls of
-<b>match()</b> more strictly than the total number of calls, in order to
-restrict the maximum amount of stack (or heap, if --disable-stack-for-recursion
-is specified) that is used. A second limit controls this; it defaults to the
-value that is set for --with-match-limit, which imposes no additional
-constraints. However, you can set a lower limit by adding, for example,
+The <b>pcre2_match()</b> function starts out using a 20K vector on the system
+stack to record backtracking points. The more nested backtracking points there
+are (that is, the deeper the search tree), the more memory is needed. If the
+initial vector is not large enough, heap memory is used, up to a certain limit,
+which is specified in kilobytes. The limit can be changed at run time, as
+described in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+documentation. The default limit (in effect unlimited) is 20 million. You can
+change this by a setting such as
 <pre>
-  --with-match-limit-recursion=10000
+  --with-heap-limit=500
 </pre>
-to the <b>configure</b> command. This value can also be overridden at run time.
+which limits the amount of heap to 500 kilobytes. This limit applies only to
+interpretive matching in pcre2_match(). It does not apply when JIT (which has
+its own memory arrangements) is used, nor does it apply to
+<b>pcre2_dfa_match()</b>.
 </P>
-<br><a name="SEC13" href="#TOC1">CREATING CHARACTER TABLES AT BUILD TIME</a><br>
+<P>
+You can also explicitly limit the depth of nested backtracking in the
+<b>pcre2_match()</b> interpreter. This limit defaults to the value that is set
+for --with-match-limit. You can set a lower default limit by adding, for
+example,
+<pre>
+  --with-match-limit_depth=10000
+</pre>
+to the <b>configure</b> command. This value can be overridden at run time. This
+depth limit indirectly limits the amount of heap memory that is used, but
+because the size of each backtracking "frame" depends on the number of
+capturing parentheses in a pattern, the amount of heap that is used before the
+limit is reached varies from pattern to pattern. This limit was more useful in
+versions before 10.30, where function recursion was used for backtracking.
+</P>
+<P>
+As well as applying to <b>pcre2_match()</b>, the depth limit also controls
+the depth of recursive function calls in <b>pcre2_dfa_match()</b>. These are
+used for lookaround assertions, atomic groups, and recursion within patterns.
+The limit does not apply to JIT matching.
+</P>
+<br><a name="SEC12" href="#TOC1">CREATING CHARACTER TABLES AT BUILD TIME</a><br>
 <P>
 PCRE2 uses fixed tables for processing characters whose code points are less
 than 256. By default, PCRE2 is built with a set of tables that are distributed
@@ -310,12 +324,12 @@
 to the <b>configure</b> command, the distributed tables are no longer used.
 Instead, a program called <b>dftables</b> is compiled and run. This outputs the
 source for new set of tables, created in the default locale of your C run-time
-system. (This method of replacing the tables does not work if you are cross
+system. This method of replacing the tables does not work if you are cross
 compiling, because <b>dftables</b> is run on the local host. If you need to
 create alternative tables when cross compiling, you will have to do so "by
-hand".)
+hand".
 </P>
-<br><a name="SEC14" href="#TOC1">USING EBCDIC CODE</a><br>
+<br><a name="SEC13" href="#TOC1">USING EBCDIC CODE</a><br>
 <P>
 PCRE2 assumes by default that it will run in an environment where the character
 code is ASCII or Unicode, which is a superset of ASCII. This is the case for
@@ -350,7 +364,7 @@
 and equivalent run-time options, refer to these character values in an EBCDIC
 environment.
 </P>
-<br><a name="SEC15" href="#TOC1">PCRE2GREP SUPPORT FOR EXTERNAL SCRIPTS</a><br>
+<br><a name="SEC14" href="#TOC1">PCRE2GREP SUPPORT FOR EXTERNAL SCRIPTS</a><br>
 <P>
 By default, on non-Windows systems, <b>pcre2grep</b> supports the use of
 callouts with string arguments within the patterns it is matching, in order to
@@ -359,7 +373,7 @@
 documentation. This support can be disabled by adding
 --disable-pcre2grep-callout to the <b>configure</b> command.
 </P>
-<br><a name="SEC16" href="#TOC1">PCRE2GREP OPTIONS FOR COMPRESSED FILE SUPPORT</a><br>
+<br><a name="SEC15" href="#TOC1">PCRE2GREP OPTIONS FOR COMPRESSED FILE SUPPORT</a><br>
 <P>
 By default, <b>pcre2grep</b> reads all files as plain text. You can build it so
 that it recognizes files whose names end in <b>.gz</b> or <b>.bz2</b>, and reads
@@ -372,22 +386,25 @@
 relevant libraries are installed on your system. Configuration will fail if
 they are not.
 </P>
-<br><a name="SEC17" href="#TOC1">PCRE2GREP BUFFER SIZE</a><br>
+<br><a name="SEC16" href="#TOC1">PCRE2GREP BUFFER SIZE</a><br>
 <P>
 <b>pcre2grep</b> uses an internal buffer to hold a "window" on the file it is
 scanning, in order to be able to output "before" and "after" lines when it
-finds a match. The size of the buffer is controlled by a parameter whose
-default value is 20K. The buffer itself is three times this size, but because
-of the way it is used for holding "before" lines, the longest line that is
-guaranteed to be processable is the parameter size. You can change the default
-parameter value by adding, for example,
+finds a match. The starting size of the buffer is controlled by a parameter
+whose default value is 20K. The buffer itself is three times this size, but
+because of the way it is used for holding "before" lines, the longest line that
+is guaranteed to be processable is the parameter size. If a longer line is
+encountered, <b>pcre2grep</b> automatically expands the buffer, up to a
+specified maximum size, whose default is 1M or the starting size, whichever is
+the larger. You can change the default parameter values by adding, for example,
 <pre>
-  --with-pcre2grep-bufsize=50K
+  --with-pcre2grep-bufsize=51200
+  --with-pcre2grep-max-bufsize=2097152
 </pre>
-to the <b>configure</b> command. The caller of \fPpcre2grep\fP can override this
-value by using --buffer-size on the command line.
+to the <b>configure</b> command. The caller of \fPpcre2grep\fP can override
+these values by using --buffer-size and --max-buffer-size on the command line.
 </P>
-<br><a name="SEC18" href="#TOC1">PCRE2TEST OPTION FOR LIBREADLINE SUPPORT</a><br>
+<br><a name="SEC17" href="#TOC1">PCRE2TEST OPTION FOR LIBREADLINE SUPPORT</a><br>
 <P>
 If you add one of
 <pre>
@@ -421,7 +438,7 @@
 </pre>
 immediately before the <b>configure</b> command.
 </P>
-<br><a name="SEC19" href="#TOC1">INCLUDING DEBUGGING CODE</a><br>
+<br><a name="SEC18" href="#TOC1">INCLUDING DEBUGGING CODE</a><br>
 <P>
 If you add
 <pre>
@@ -430,7 +447,7 @@
 to the <b>configure</b> command, additional debugging code is included in the
 build. This feature is intended for use by the PCRE2 maintainers.
 </P>
-<br><a name="SEC20" href="#TOC1">DEBUGGING WITH VALGRIND SUPPORT</a><br>
+<br><a name="SEC19" href="#TOC1">DEBUGGING WITH VALGRIND SUPPORT</a><br>
 <P>
 If you add
 <pre>
@@ -440,7 +457,7 @@
 certain memory regions as unaddressable. This allows it to detect invalid
 memory accesses, and is mostly useful for debugging PCRE2 itself.
 </P>
-<br><a name="SEC21" href="#TOC1">CODE COVERAGE REPORTING</a><br>
+<br><a name="SEC20" href="#TOC1">CODE COVERAGE REPORTING</a><br>
 <P>
 If your C compiler is gcc, you can build a version of PCRE2 that can generate a
 code coverage report for its test suite. To enable this, you must install
@@ -497,11 +514,47 @@
 information about code coverage, see the <b>gcov</b> and <b>lcov</b>
 documentation.
 </P>
-<br><a name="SEC22" href="#TOC1">SEE ALSO</a><br>
+<br><a name="SEC21" href="#TOC1">SUPPORT FOR FUZZERS</a><br>
+<P>
+There is a special option for use by people who want to run fuzzing tests on
+PCRE2:
+<pre>
+  --enable-fuzz-support
+</pre>
+At present this applies only to the 8-bit library. If set, it causes an extra
+library called libpcre2-fuzzsupport.a to be built, but not installed. This
+contains a single function called LLVMFuzzerTestOneInput() whose arguments are
+a pointer to a string and the length of the string. When called, this function
+tries to compile the string as a pattern, and if that succeeds, to match it.
+This is done both with no options and with some random options bits that are
+generated from the string.
+</P>
+<P>
+Setting --enable-fuzz-support also causes a binary called <b>pcre2fuzzcheck</b>
+to be created. This is normally run under valgrind or used when PCRE2 is
+compiled with address sanitizing enabled. It calls the fuzzing function and
+outputs information about it is doing. The input strings are specified by
+arguments: if an argument starts with "=" the rest of it is a literal input
+string. Otherwise, it is assumed to be a file name, and the contents of the
+file are the test string.
+</P>
+<br><a name="SEC22" href="#TOC1">OBSOLETE OPTION</a><br>
+<P>
+In versions of PCRE2 prior to 10.30, there were two ways of handling
+backtracking in the <b>pcre2_match()</b> function. The default was to use the
+system stack, but if
+<pre>
+  --disable-stack-for-recursion
+</pre>
+was set, memory on the heap was used. From release 10.30 onwards this has
+changed (the stack is no longer used) and this option now does nothing except
+give a warning.
+</P>
+<br><a name="SEC23" href="#TOC1">SEE ALSO</a><br>
 <P>
 <b>pcre2api</b>(3), <b>pcre2-config</b>(3).
 </P>
-<br><a name="SEC23" href="#TOC1">AUTHOR</a><br>
+<br><a name="SEC24" href="#TOC1">AUTHOR</a><br>
 <P>
 Philip Hazel
 <br>
@@ -510,11 +563,11 @@
 Cambridge, England.
 <br>
 </P>
-<br><a name="SEC24" href="#TOC1">REVISION</a><br>
+<br><a name="SEC25" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 01 April 2016
+Last updated: 18 July 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2callout.html b/dist2/doc/html/pcre2callout.html
index 7e85c9a..2adf21a 100644
--- a/dist2/doc/html/pcre2callout.html
+++ b/dist2/doc/html/pcre2callout.html
@@ -57,16 +57,23 @@
 </pre>
 If the PCRE2_AUTO_CALLOUT option bit is set when a pattern is compiled, PCRE2
 automatically inserts callouts, all with number 255, before each item in the
-pattern. For example, if PCRE2_AUTO_CALLOUT is used with the pattern
+pattern except for immediately before or after an explicit callout. For
+example, if PCRE2_AUTO_CALLOUT is used with the pattern
+<pre>
+  A(?C3)B
+</pre>
+it is processed as if it were
+<pre>
+  (?C255)A(?C3)B(?C255)
+</pre>
+Here is a more complicated example:
 <pre>
   A(\d{2}|--)
 </pre>
-it is processed as if it were
-<br>
-<br>
-(?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
-<br>
-<br>
+With PCRE2_AUTO_CALLOUT, this pattern is processed as if it were
+<pre>
+  (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
+</pre>
 Notice that there is a callout before and after each parenthesis and
 alternation bar. If the pattern contains a conditional group whose condition is
 an assertion, an automatic callout is inserted immediately before the
@@ -107,10 +114,10 @@
   No match
 </pre>
 This indicates that when matching [bc] fails, there is no backtracking into a+
-and therefore the callouts that would be taken for the backtracks do not occur.
-You can disable the auto-possessify feature by passing PCRE2_NO_AUTO_POSSESS to
-<b>pcre2_compile()</b>, or starting the pattern with (*NO_AUTO_POSSESS). In this
-case, the output changes to this:
+(because it is being treated as a++) and therefore the callouts that would be
+taken for the backtracks do not occur. You can disable the auto-possessify
+feature by passing PCRE2_NO_AUTO_POSSESS to <b>pcre2_compile()</b>, or starting
+the pattern with (*NO_AUTO_POSSESS). In this case, the output changes to this:
 <pre>
   ---&#62;aaaa
    +0 ^        a+
@@ -131,10 +138,14 @@
 a pattern. If PCRE2_DOTALL is set, so that the dot can match any character, the
 pattern is automatically anchored. If PCRE2_DOTALL is not set, a match can
 start only after an internal newline or at the beginning of the subject, and
-<b>pcre2_compile()</b> remembers this. This optimization is disabled, however,
-if .* is in an atomic group or if there is a back reference to the capturing
-group in which it appears. It is also disabled if the pattern contains (*PRUNE)
-or (*SKIP). However, the presence of callouts does not affect it.
+<b>pcre2_compile()</b> remembers this. If a pattern has more than one top-level
+branch, automatic anchoring occurs if all branches are anchorable.
+</P>
+<P>
+This optimization is disabled, however, if .* is in an atomic group or if there
+is a back reference to the capturing group in which it appears. It is also
+disabled if the pattern contains (*PRUNE) or (*SKIP). However, the presence of
+callouts does not affect it.
 </P>
 <P>
 For example, if the pattern .*\d is compiled with PCRE2_AUTO_CALLOUT and
@@ -166,10 +177,6 @@
 Another optimization, described in the next section, means that there is no
 subsequent attempt to match with an empty subject.
 </P>
-<P>
-If a pattern has more than one top-level branch, automatic anchoring occurs if
-all branches are anchorable.
-</P>
 <br><b>
 Other optimizations
 </b><br>
@@ -185,9 +192,10 @@
 result is still no match, the callout is obeyed.
 </P>
 <P>
-PCRE2 also knows the minimum length of a matching string, and will immediately
-give a "no match" return without actually running a match if the subject is not
-long enough, or, for unanchored patterns, if it has been scanned far enough.
+For most patterns PCRE2 also knows the minimum length of a matching string, and
+will immediately give a "no match" return without actually running a match if
+the subject is not long enough, or, for unanchored patterns, if it has been
+scanned far enough.
 </P>
 <P>
 You can disable these optimizations by passing the PCRE2_NO_START_OPTIMIZE
@@ -198,18 +206,20 @@
 <br><a name="SEC4" href="#TOC1">THE CALLOUT INTERFACE</a><br>
 <P>
 During matching, when PCRE2 reaches a callout point, if an external function is
-set in the match context, it is called. This applies to both normal and DFA
-matching. The first argument to the callout function is a pointer to a
-<b>pcre2_callout</b> block. The second argument is the void * callout data that
-was supplied when the callout was set up by calling <b>pcre2_set_callout()</b>
-(see the
+provided in the match context, it is called. This applies to both normal,
+DFA, and JIT matching. The first argument to the callout function is a pointer
+to a <b>pcre2_callout</b> block. The second argument is the void * callout data
+that was supplied when the callout was set up by calling
+<b>pcre2_set_callout()</b> (see the
 <a href="pcre2api.html"><b>pcre2api</b></a>
-documentation). The callout block structure contains the following fields:
+documentation). The callout block structure contains the following fields, not
+necessarily in this order:
 <pre>
   uint32_t      <i>version</i>;
   uint32_t      <i>callout_number</i>;
   uint32_t      <i>capture_top</i>;
   uint32_t      <i>capture_last</i>;
+  uint32_t      <i>callout_flags</i>;
   PCRE2_SIZE   *<i>offset_vector</i>;
   PCRE2_SPTR    <i>mark</i>;
   PCRE2_SPTR    <i>subject</i>;
@@ -223,11 +233,12 @@
   PCRE2_SPTR    <i>callout_string</i>;
 </pre>
 The <i>version</i> field contains the version number of the block format. The
-current version is 1; the three callout string fields were added for this
-version. If you are writing an application that might use an earlier release of
-PCRE2, you should check the version number before accessing any of these
-fields. The version number will increase in future if more fields are added,
-but the intention is never to remove any of the existing fields.
+current version is 2; the three callout string fields were added for version 1,
+and the <i>callout_flags</i> field for version 2. If you are writing an
+application that might use an earlier release of PCRE2, you should check the
+version number before accessing any of these fields. The version number will
+increase in future if more fields are added, but the intention is never to
+remove any of the existing fields.
 </P>
 <br><b>
 Fields for numerical callouts
@@ -235,8 +246,8 @@
 <P>
 For a numerical callout, <i>callout_string</i> is NULL, and <i>callout_number</i>
 contains the number of the callout, in the range 0-255. This is the number
-that follows (?C for manual callouts; it is 255 for automatically generated
-callouts.
+that follows (?C for callouts that part of the pattern; it is 255 for
+automatically generated callouts.
 </P>
 <br><b>
 Fields for string callouts
@@ -267,12 +278,42 @@
 callout.
 </P>
 <P>
-The <i>offset_vector</i> field is a pointer to the vector of capturing offsets
-(the "ovector") that was passed to the matching function in the match data
-block. When <b>pcre2_match()</b> is used, the contents can be inspected in
+The <i>offset_vector</i> field is a pointer to a vector of capturing offsets
+(the "ovector"). You may read the elements in this vector, but you must not
+change any of them.
+</P>
+<P>
+For calls to <b>pcre2_match()</b>, the <i>offset_vector</i> field is not (since
+release 10.30) a pointer to the actual ovector that was passed to the matching
+function in the match data block. Instead it points to an internal ovector of a
+size large enough to hold all possible captured substrings in the pattern. Note
+that whenever a recursion or subroutine call within a pattern completes, the
+capturing state is reset to what it was before.
+</P>
+<P>
+The <i>capture_last</i> field contains the number of the most recently captured
+substring, and the <i>capture_top</i> field contains one more than the number of
+the highest numbered captured substring so far. If no substrings have yet been
+captured, the value of <i>capture_last</i> is 0 and the value of
+<i>capture_top</i> is 1. The values of these fields do not always differ by one;
+for example, when the callout in the pattern ((a)(b))(?C2) is taken,
+<i>capture_last</i> is 1 but <i>capture_top</i> is 4.
+</P>
+<P>
+The contents of ovector[2] to ovector[&#60;capture_top&#62;*2-1] can be inspected in
 order to extract substrings that have been matched so far, in the same way as
-for extracting substrings after a match has completed. For the DFA matching
-function, this field is not useful.
+extracting substrings after a match has completed. The values in ovector[0] and
+ovector[1] are always PCRE2_UNSET because the match is by definition not
+complete. Substrings that have not been captured but whose numbers are less
+than <i>capture_top</i> also have both of their ovector slots set to
+PCRE2_UNSET.
+</P>
+<P>
+For DFA matching, the <i>offset_vector</i> field points to the ovector that was
+passed to the matching function in the match data block, but it holds no useful
+information at callout time because <b>pcre2_dfa_match()</b> does not support
+substring capturing. The value of <i>capture_top</i> is always 1 and the value
+of <i>capture_last</i> is always 0 for DFA matching.
 </P>
 <P>
 The <i>subject</i> and <i>subject_length</i> fields contain copies of the values
@@ -291,29 +332,20 @@
 current match pointer.
 </P>
 <P>
-When the <b>pcre2_match()</b> is used, the <i>capture_top</i> field contains one
-more than the number of the highest numbered captured substring so far. If no
-substrings have been captured, the value of <i>capture_top</i> is one. This is
-always the case when the DFA functions are used, because they do not support
-captured substrings.
-</P>
-<P>
-The <i>capture_last</i> field contains the number of the most recently captured
-substring. However, when a recursion exits, the value reverts to what it was
-outside the recursion, as do the values of all captured substrings. If no
-substrings have been captured, the value of <i>capture_last</i> is 0. This is
-always the case for the DFA matching functions.
-</P>
-<P>
 The <i>pattern_position</i> field contains the offset in the pattern string to
 the next item to be matched.
 </P>
 <P>
 The <i>next_item_length</i> field contains the length of the next item to be
-matched in the pattern string. When the callout immediately precedes an
-alternation bar, a closing parenthesis, or the end of the pattern, the length
-is zero. When the callout precedes an opening parenthesis, the length is that
-of the entire subpattern.
+processed in the pattern string. When the callout is at the end of the pattern,
+the length is zero. When the callout precedes an opening parenthesis, the
+length includes meta characters that follow the parenthesis. For example, in a
+callout before an assertion such as (?=ab) the length is 3. For an an
+alternation bar or a closing parenthesis, the length is one, unless a closing
+parenthesis is followed by a quantifier, in which case its length is included.
+(This changed in release 10.23. In earlier releases, before an opening
+parenthesis the length was that of the entire subpattern, and before an
+alternation bar or a closing parenthesis the length was zero.)
 </P>
 <P>
 The <i>pattern_position</i> and <i>next_item_length</i> fields are intended to
@@ -329,6 +361,36 @@
 of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In
 callouts from the DFA matching function this field always contains NULL.
 </P>
+<P>
+The <i>callout_flags</i> field is always zero in callouts from
+<b>pcre2_dfa_match()</b> or when JIT is being used. When <b>pcre2_match()</b>
+without JIT is used, the following bits may be set:
+<pre>
+  PCRE2_CALLOUT_STARTMATCH
+</pre>
+This is set for the first callout after the start of matching for each new
+starting position in the subject.
+<pre>
+  PCRE2_CALLOUT_BACKTRACK
+</pre>
+This is set if there has been a matching backtrack since the previous callout,
+or since the start of matching if this is the first callout from a
+<b>pcre2_match()</b> run.
+</P>
+<P>
+Both bits are set when a backtrack has caused a "bumpalong" to a new starting
+position in the subject. Output from <b>pcre2test</b> does not indicate the
+presence of these bits unless the <b>callout_extra</b> modifier is set.
+</P>
+<P>
+The information in the <b>callout_flags</b> field is provided so that
+applications can track and tell their users how matching with backtracking is
+done. This can be useful when trying to optimize patterns, or just to
+understand how PCRE2 works. There is no support in <b>pcre2_dfa_match()</b>
+because there is no backtracking in DFA matching, and there is no support in
+JIT because JIT is all about maximimizing matching performance. In both these
+cases the <b>callout_flags</b> field is always zero.
+</P>
 <br><a name="SEC5" href="#TOC1">RETURN VALUES FROM CALLOUTS</a><br>
 <P>
 The external callout function returns an integer to PCRE2. If the value is
@@ -399,9 +461,9 @@
 </P>
 <br><a name="SEC8" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 23 March 2015
+Last updated: 22 December 2017
 <br>
-Copyright &copy; 1997-2015 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2compat.html b/dist2/doc/html/pcre2compat.html
index 3b29e6f..e6d2e7e 100644
--- a/dist2/doc/html/pcre2compat.html
+++ b/dist2/doc/html/pcre2compat.html
@@ -18,7 +18,8 @@
 <P>
 This document describes the differences in the ways that PCRE2 and Perl handle
 regular expressions. The differences described here are with respect to Perl
-versions 5.10 and above.
+versions 5.26, but as both Perl and PCRE2 are continually changing, the
+information may sometimes be out of date.
 </P>
 <P>
 1. PCRE2 has only a subset of Perl's Unicode support. Details of what it does
@@ -27,17 +28,18 @@
 page.
 </P>
 <P>
-2. PCRE2 allows repeat quantifiers only on parenthesized assertions, but they
-do not mean what you might think. For example, (?!a){3} does not assert that
-the next three characters are not "a". It just asserts that the next character
-is not "a" three times (in principle: PCRE2 optimizes this to run the assertion
-just once). Perl allows repeat quantifiers on other assertions such as \b, but
-these do not seem to have any use.
+2. Like Perl, PCRE2 allows repeat quantifiers on parenthesized assertions, but
+they do not mean what you might think. For example, (?!a){3} does not assert
+that the next three characters are not "a". It just asserts that the next
+character is not "a" three times (in principle: PCRE2 optimizes this to run the
+assertion just once). Perl allows some repeat quantifiers on other assertions,
+for example, \b* (but not \b{3}), but these do not seem to have any use.
 </P>
 <P>
-3. Capturing subpatterns that occur inside negative lookahead assertions are
-counted, but their entries in the offsets vector are never set. Perl sometimes
-(but not always) sets its numerical variables from inside negative assertions.
+3. Capturing subpatterns that occur inside negative lookaround assertions are
+counted, but their entries in the offsets vector are set only when a negative
+assertion is a condition that has a matching branch (that is, the condition is
+false).
 </P>
 <P>
 4. The following Perl escape sequences are not supported: \l, \u, \L,
@@ -50,13 +52,13 @@
 </P>
 <P>
 5. The Perl escape sequences \p, \P, and \X are supported only if PCRE2 is
-built with Unicode support. The properties that can be tested with \p and \P
-are limited to the general category properties such as Lu and Nd, script names
-such as Greek or Han, and the derived properties Any and L&. PCRE2 does support
-the Cs (surrogate) property, which Perl does not; the Perl documentation says
-"Because Perl hides the need for the user to understand the internal
-representation of Unicode characters, there is no need to implement the
-somewhat messy concept of surrogates."
+built with Unicode support (the default). The properties that can be tested
+with \p and \P are limited to the general category properties such as Lu and
+Nd, script names such as Greek or Han, and the derived properties Any and L&.
+PCRE2 does support the Cs (surrogate) property, which Perl does not; the Perl
+documentation says "Because Perl hides the need for the user to understand the
+internal representation of Unicode characters, there is no need to implement
+the somewhat messy concept of surrogates."
 </P>
 <P>
 6. PCRE2 does support the \Q...\E escape for quoting substrings. Characters
@@ -75,23 +77,15 @@
 </P>
 <P>
 7. Fairly obviously, PCRE2 does not support the (?{code}) and (??{code})
-constructions. However, there is support for recursive patterns. This is not
-available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE2 "callout"
-feature allows an external function to be called during pattern matching. See
-the
+constructions. However, there is support PCRE2's "callout" feature, which
+allows an external function to be called during pattern matching. See the
 <a href="pcre2callout.html"><b>pcre2callout</b></a>
 documentation for details.
 </P>
 <P>
-8. Subroutine calls (whether recursive or not) are treated as atomic groups.
-Atomic recursion is like Python, but unlike Perl. Captured values that are set
-outside a subroutine call can be referenced from inside in PCRE2, but not in
-Perl. There is a discussion that explains these differences in more detail in
-the
-<a href="pcre2pattern.html#recursiondifference">section on recursion differences from Perl</a>
-in the
-<a href="pcre2pattern.html"><b>pcre2pattern</b></a>
-page.
+8. Subroutine calls (whether recursive or not) were treated as atomic groups up
+to PCRE2 release 10.23, but from release 10.30 this changed, and backtracking
+into subroutine calls is now supported, as in Perl.
 </P>
 <P>
 9. If any of the backtracking control verbs are used in a subpattern that is
@@ -107,7 +101,7 @@
 one that is backtracked onto acts. For example, in the pattern
 A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure in C
 triggers (*PRUNE). Perl's behaviour is more complex; in many cases it is the
-same as PCRE2, but there are examples where it differs.
+same as PCRE2, but there are cases where it differs.
 </P>
 <P>
 11. Most backtracking verbs in assertions have their normal actions. They are
@@ -123,7 +117,7 @@
 13. PCRE2's handling of duplicate subpattern numbers and duplicate subpattern
 names is not as general as Perl's. This is a consequence of the fact the PCRE2
 works internally just with numbers, using an external table to translate
-between numbers and names. In particular, a pattern such as (?|(?&#60;a&#62;A)|(?&#60;b)B),
+between numbers and names. In particular, a pattern such as (?|(?&#60;a&#62;A)|(?&#60;b&#62;B),
 where the two capturing parentheses have the same number but different names,
 is not supported, and causes an error at compile time. If it were allowed, it
 would not be possible to distinguish which parentheses matched, because both
@@ -131,10 +125,11 @@
 an error is given at compile time.
 </P>
 <P>
-14. Perl recognizes comments in some places that PCRE2 does not, for example,
-between the ( and ? at the start of a subpattern. If the /x modifier is set,
-Perl allows white space between ( and ? (though current Perls warn that this is
-deprecated) but PCRE2 never does, even if the PCRE2_EXTENDED option is set.
+14. Perl used to recognize comments in some places that PCRE2 does not, for
+example, between the ( and ? at the start of a subpattern. If the /x modifier
+is set, Perl allowed white space between ( and ? though the latest Perls give
+an error (for a while it was just deprecated). There may still be some cases
+where Perl behaves differently.
 </P>
 <P>
 15. Perl, when in warning mode, gives warnings for character classes such as
@@ -146,14 +141,14 @@
 16. In PCRE2, the upper/lower case character properties Lu and Ll are not
 affected when case-independent matching is specified. For example, \p{Lu}
 always matches an upper case letter. I think Perl has changed in this respect;
-in the release at the time of writing (5.16), \p{Lu} and \p{Ll} match all
+in the release at the time of writing (5.24), \p{Lu} and \p{Ll} match all
 letters, regardless of case, when case independence is specified.
 </P>
 <P>
 17. PCRE2 provides some extensions to the Perl regular expression facilities.
 Perl 5.10 includes new features that are not in earlier versions of Perl, some
-of which (such as named parentheses) have been in PCRE2 for some time. This
-list is with respect to Perl 5.10:
+of which (such as named parentheses) were in PCRE2 for some time before. This
+list is with respect to Perl 5.26:
 <br>
 <br>
 (a) Although lookbehind assertions in PCRE2 must match fixed length strings,
@@ -161,43 +156,63 @@
 of string. Perl requires them all to have the same length.
 <br>
 <br>
-(b) If PCRE2_DOLLAR_ENDONLY is set and PCRE2_MULTILINE is not set, the $
+(b) From PCRE2 10.23, back references to groups of fixed length are supported
+in lookbehinds, provided that there is no possibility of referencing a
+non-unique number or name. Perl does not support backreferences in lookbehinds.
+<br>
+<br>
+(c) If PCRE2_DOLLAR_ENDONLY is set and PCRE2_MULTILINE is not set, the $
 meta-character matches only at the very end of the string.
 <br>
 <br>
-(c) A backslash followed by a letter with no special meaning is faulted. (Perl
+(d) A backslash followed by a letter with no special meaning is faulted. (Perl
 can be made to issue a warning.)
 <br>
 <br>
-(d) If PCRE2_UNGREEDY is set, the greediness of the repetition quantifiers is
+(e) If PCRE2_UNGREEDY is set, the greediness of the repetition quantifiers is
 inverted, that is, by default they are not greedy, but if followed by a
 question mark they are.
 <br>
 <br>
-(e) PCRE2_ANCHORED can be used at matching time to force a pattern to be tried
+(f) PCRE2_ANCHORED can be used at matching time to force a pattern to be tried
 only at the first matching position in the subject string.
 <br>
 <br>
-(f) The PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART, and
-PCRE2_NO_AUTO_CAPTURE options have no Perl equivalents.
+(g) The PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART
+options have no Perl equivalents.
 <br>
 <br>
-(g) The \R escape sequence can be restricted to match only CR, LF, or CRLF
+(h) The \R escape sequence can be restricted to match only CR, LF, or CRLF
 by the PCRE2_BSR_ANYCRLF option.
 <br>
 <br>
-(h) The callout facility is PCRE2-specific.
+(i) The callout facility is PCRE2-specific. Perl supports codeblocks and
+variable interpolation, but not general hooks on every match.
 <br>
 <br>
-(i) The partial matching facility is PCRE2-specific.
+(j) The partial matching facility is PCRE2-specific.
 <br>
 <br>
-(j) The alternative matching function (<b>pcre2_dfa_match()</b> matches in a
+(k) The alternative matching function (<b>pcre2_dfa_match()</b> matches in a
 different way and is not Perl-compatible.
 <br>
 <br>
-(k) PCRE2 recognizes some special sequences such as (*CR) at the start of
-a pattern that set overall options that cannot be changed within the pattern.
+(l) PCRE2 recognizes some special sequences such as (*CR) or (*NO_JIT) at
+the start of a pattern that set overall options that cannot be changed within
+the pattern.
+</P>
+<P>
+18. The Perl /a modifier restricts /d numbers to pure ascii, and the /aa
+modifier restricts /i case-insensitive matching to pure ascii, ignoring Unicode
+rules. This separation cannot be represented with PCRE2_UCP.
+</P>
+<P>
+19. Perl has different limits than PCRE2. See the
+<a href="pcre2limit.html"><b>pcre2limit</b></a>
+documentation for details. Perl went with 5.10 from recursion to iteration
+keeping the intermediate matches on the heap, which is ~10% slower but does not
+fall into any stack-overflow limit. PCRE2 made a similar change at release
+10.30, and also has many build-time and run-time customizable limits.
 </P>
 <br><b>
 AUTHOR
@@ -214,9 +229,9 @@
 REVISION
 </b><br>
 <P>
-Last updated: 15 March 2015
+Last updated: 18 April 2017
 <br>
-Copyright &copy; 1997-2015 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2convert.html b/dist2/doc/html/pcre2convert.html
new file mode 100644
index 0000000..8b4d87f
--- /dev/null
+++ b/dist2/doc/html/pcre2convert.html
@@ -0,0 +1,190 @@
+<html>
+<head>
+<title>pcre2convert specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2convert man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<ul>
+<li><a name="TOC1" href="#SEC1">EXPERIMENTAL PATTERN CONVERSION FUNCTIONS</a>
+<li><a name="TOC2" href="#SEC2">THE CONVERT CONTEXT</a>
+<li><a name="TOC3" href="#SEC3">THE CONVERSION FUNCTION</a>
+<li><a name="TOC4" href="#SEC4">CONVERTING GLOBS</a>
+<li><a name="TOC5" href="#SEC5">CONVERTING POSIX PATTERNS</a>
+<li><a name="TOC6" href="#SEC6">AUTHOR</a>
+<li><a name="TOC7" href="#SEC7">REVISION</a>
+</ul>
+<br><a name="SEC1" href="#TOC1">EXPERIMENTAL PATTERN CONVERSION FUNCTIONS</a><br>
+<P>
+This document describes a set of functions that can be used to convert
+"foreign" patterns into PCRE2 regular expressions. This facility is currently
+experimental, and may be changed in future releases. Two kinds of pattern,
+globs and POSIX patterns, are supported.
+</P>
+<br><a name="SEC2" href="#TOC1">THE CONVERT CONTEXT</a><br>
+<P>
+<b>pcre2_convert_context *pcre2_convert_context_create(</b>
+<b>  pcre2_general_context *<i>gcontext</i>);</b>
+<br>
+<br>
+<b>pcre2_convert_context *pcre2_convert_context_copy(</b>
+<b>  pcre2_convert_context *<i>cvcontext</i>);</b>
+<br>
+<br>
+<b>void pcre2_convert_context_free(pcre2_convert_context *<i>cvcontext</i>);</b>
+<br>
+<br>
+<b>int pcre2_set_glob_escape(pcre2_convert_context *<i>cvcontext</i>,</b>
+<b>  uint32_t <i>escape_char</i>);</b>
+<br>
+<br>
+<b>int pcre2_set_glob_separator(pcre2_convert_context *<i>cvcontext</i>,</b>
+<b>  uint32_t <i>separator_char</i>);</b>
+<br>
+<br>
+A convert context is used to hold parameters that affect the way that pattern
+conversion works. Like all PCRE2 contexts, you need to use a context only if
+you want to override the defaults. There are the usual create, copy, and free
+functions. If custom memory management functions are set in a general context
+that is passed to <b>pcre2_convert_context_create()</b>, they are used for all
+memory management within the conversion functions.
+</P>
+<P>
+There are only two parameters in the convert context at present. Both apply
+only to glob conversions. The escape character defaults to grave accent under
+Windows, otherwise backslash. It can be set to zero, meaning no escape
+character, or to any punctuation character with a code point less than 256.
+The separator character defaults to backslash under Windows, otherwise forward
+slash. It can be set to forward slash, backslash, or dot.
+</P>
+<P>
+The two setting functions return zero on success, or PCRE2_ERROR_BADDATA if
+their second argument is invalid.
+</P>
+<br><a name="SEC3" href="#TOC1">THE CONVERSION FUNCTION</a><br>
+<P>
+<b>int pcre2_pattern_convert(PCRE2_SPTR <i>pattern</i>, PCRE2_SIZE <i>length</i>,</b>
+<b>  uint32_t <i>options</i>, PCRE2_UCHAR **<i>buffer</i>,</b>
+<b>  PCRE2_SIZE *<i>blength</i>, pcre2_convert_context *<i>cvcontext</i>);</b>
+<br>
+<br>
+<b>void pcre2_converted_pattern_free(PCRE2_UCHAR *<i>converted_pattern</i>);</b>
+<br>
+<br>
+The first two arguments of <b>pcre2_pattern_convert()</b> define the foreign
+pattern that is to be converted. The length may be given as
+PCRE2_ZERO_TERMINATED. The <b>options</b> argument defines how the pattern is to
+be processed. If the input is UTF, the PCRE2_CONVERT_UTF option should be set.
+PCRE2_CONVERT_NO_UTF_CHECK may also be set if you are sure the input is valid.
+One or more of the glob options, or one of the following POSIX options must be
+set to define the type of conversion that is required:
+<pre>
+  PCRE2_CONVERT_GLOB
+  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR
+  PCRE2_CONVERT_GLOB_NO_STARSTAR
+  PCRE2_CONVERT_POSIX_BASIC
+  PCRE2_CONVERT_POSIX_EXTENDED
+</pre>
+Details of the conversions are given below. The <b>buffer</b> and <b>blength</b>
+arguments define how the output is handled:
+</P>
+<P>
+If <b>buffer</b> is NULL, the function just returns the length of the converted
+pattern via <b>blength</b>. This is one less than the length of buffer needed,
+because a terminating zero is always added to the output.
+</P>
+<P>
+If <b>buffer</b> points to a NULL pointer, an output buffer is obtained using
+the allocator in the context or <b>malloc()</b> if no context is supplied. A
+pointer to this buffer is placed in the variable to which <b>buffer</b> points.
+When no longer needed the output buffer must be freed by calling
+<b>pcre2_converted_pattern_free()</b>.
+</P>
+<P>
+If <b>buffer</b> points to a non-NULL pointer, <b>blength</b> must be set to the
+actual length of the buffer provided (in code units).
+</P>
+<P>
+In all cases, after successful conversion, the variable pointed to by
+<b>blength</b> is updated to the length actually used (in code units), excluding
+the terminating zero that is always added.
+</P>
+<P>
+If an error occurs, the length (via <b>blength</b>) is set to the offset
+within the input pattern where the error was detected. Only gross syntax errors
+are caught; there are plenty of errors that will get passed on for
+<b>pcre2_compile()</b> to discover.
+</P>
+<P>
+The return from <b>pcre2_pattern_convert()</b> is zero on success or a non-zero
+PCRE2 error code. Note that PCRE2 error codes may be positive or negative:
+<b>pcre2_compile()</b> uses mostly positive codes and <b>pcre2_match()</b>
+negative ones; <b>pcre2_convert()</b> uses existing codes of both kinds. A
+textual error message can be obtained by calling
+<b>pcre2_get_error_message()</b>.
+</P>
+<br><a name="SEC4" href="#TOC1">CONVERTING GLOBS</a><br>
+<P>
+Globs are used to match file names, and consequently have the concept of a
+"path separator", which defaults to backslash under Windows and forward slash
+otherwise. If PCRE2_CONVERT_GLOB is set, the wildcards * and ? are not
+permitted to match separator characters, but the double-star (**) feature
+(which does match separators) is supported.
+</P>
+<P>
+PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR matches globs with wildcards allowed to
+match separator characters. PCRE2_GLOB_NO_STARSTAR matches globs with the
+double-star feature disabled. These options may be given together.
+</P>
+<br><a name="SEC5" href="#TOC1">CONVERTING POSIX PATTERNS</a><br>
+<P>
+POSIX defines two kinds of regular expression pattern: basic and extended.
+These can be processed by setting PCRE2_CONVERT_POSIX_BASIC or
+PCRE2_CONVERT_POSIX_EXTENDED, respectively.
+</P>
+<P>
+In POSIX patterns, backslash is not special in a character class. Unmatched
+closing parentheses are treated as literals.
+</P>
+<P>
+In basic patterns, ? + | {} and () must be escaped to be recognized
+as metacharacters outside a character class. If the first character in the
+pattern is * it is treated as a literal. ^ is a metacharacter only at the start
+of a branch.
+</P>
+<P>
+In extended patterns, a backslash not in a character class always
+makes the next character literal, whatever it is. There are no backreferences.
+</P>
+<P>
+Note: POSIX mandates that the longest possible match at the first matching
+position must be found. This is not what <b>pcre2_match()</b> does; it yields
+the first match that is found. An application can use <b>pcre2_dfa_match()</b>
+to find the longest match, but that does not support backreferences (but then
+neither do POSIX extended patterns).
+</P>
+<br><a name="SEC6" href="#TOC1">AUTHOR</a><br>
+<P>
+Philip Hazel
+<br>
+University Computing Service
+<br>
+Cambridge, England.
+<br>
+</P>
+<br><a name="SEC7" href="#TOC1">REVISION</a><br>
+<P>
+Last updated: 12 July 2017
+<br>
+Copyright &copy; 1997-2017 University of Cambridge.
+<br>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
diff --git a/dist2/doc/html/pcre2demo.html b/dist2/doc/html/pcre2demo.html
index d64e16b..72754d3 100644
--- a/dist2/doc/html/pcre2demo.html
+++ b/dist2/doc/html/pcre2demo.html
@@ -228,6 +228,21 @@
 if (rc == 0)
   printf("ovector was not big enough for all the captured substrings\n");
 
+/* We must guard against patterns such as /(?=.\K)/ that use \K in an assertion
+to set the start of a match later than its end. In this demonstration program,
+we just detect this case and give up. */
+
+if (ovector[0] &gt; ovector[1])
+  {
+  printf("\\K was used in an assertion to set the match start after its end.\n"
+    "From end to start the match was: %.*s\n", (int)(ovector[0] - ovector[1]),
+      (char *)(subject + ovector[1]));
+  printf("Run abandoned\n");
+  pcre2_match_data_free(match_data);
+  pcre2_code_free(re);
+  return 1;
+  }
+
 /* Show substrings stored in the output vector by number. Obviously, in a real
 application you might want to do things other than print them. */
 
@@ -355,6 +370,29 @@
     options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
     }
 
+  /* If the previous match was not an empty string, there is one tricky case to
+  consider. If a pattern contains \K within a lookbehind assertion at the
+  start, the end of the matched string can be at the offset where the match
+  started. Without special action, this leads to a loop that keeps on matching
+  the same substring. We must detect this case and arrange to move the start on
+  by one character. The pcre2_get_startchar() function returns the starting
+  offset that was passed to pcre2_match(). */
+
+  else
+    {
+    PCRE2_SIZE startchar = pcre2_get_startchar(match_data);
+    if (start_offset &lt;= startchar)
+      {
+      if (startchar &gt;= subject_length) break;   /* Reached end of subject.   */
+      start_offset = startchar + 1;             /* Advance by one character. */
+      if (utf8)                                 /* If UTF-8, it may be more  */
+        {                                       /*   than one code unit.     */
+        for (; start_offset &lt; subject_length; start_offset++)
+          if ((subject[start_offset] &amp; 0xc0) != 0x80) break;
+        }
+      }
+    }
+
   /* Run the next matching operation */
 
   rc = pcre2_match(
@@ -419,6 +457,21 @@
   if (rc == 0)
     printf("ovector was not big enough for all the captured substrings\n");
 
+  /* We must guard against patterns such as /(?=.\K)/ that use \K in an
+  assertion to set the start of a match later than its end. In this
+  demonstration program, we just detect this case and give up. */
+
+  if (ovector[0] &gt; ovector[1])
+    {
+    printf("\\K was used in an assertion to set the match start after its end.\n"
+      "From end to start the match was: %.*s\n", (int)(ovector[0] - ovector[1]),
+        (char *)(subject + ovector[1]));
+    printf("Run abandoned\n");
+    pcre2_match_data_free(match_data);
+    pcre2_code_free(re);
+    return 1;
+    }
+
   /* As before, show substrings stored in the output vector by number, and then
   also any named substrings. */
 
diff --git a/dist2/doc/html/pcre2grep.html b/dist2/doc/html/pcre2grep.html
index d02d365..625a467 100644
--- a/dist2/doc/html/pcre2grep.html
+++ b/dist2/doc/html/pcre2grep.html
@@ -22,7 +22,7 @@
 <li><a name="TOC7" href="#SEC7">NEWLINES</a>
 <li><a name="TOC8" href="#SEC8">OPTIONS COMPATIBILITY</a>
 <li><a name="TOC9" href="#SEC9">OPTIONS WITH DATA</a>
-<li><a name="TOC10" href="#SEC10">CALLING EXTERNAL SCRIPTS</a>
+<li><a name="TOC10" href="#SEC10">USING PCRE2'S CALLOUT FACILITY</a>
 <li><a name="TOC11" href="#SEC11">MATCHING ERRORS</a>
 <li><a name="TOC12" href="#SEC12">DIAGNOSTICS</a>
 <li><a name="TOC13" href="#SEC13">SEE ALSO</a>
@@ -80,11 +80,19 @@
 </P>
 <P>
 The amount of memory used for buffering files that are being scanned is
-controlled by a parameter that can be set by the <b>--buffer-size</b> option.
-The default value for this parameter is specified when <b>pcre2grep</b> is
-built, with the default default being 20K. A block of memory three times this
-size is used (to allow for buffering "before" and "after" lines). An error
-occurs if a line overflows the buffer.
+controlled by parameters that can be set by the <b>--buffer-size</b> and
+<b>--max-buffer-size</b> options. The first of these sets the size of buffer
+that is obtained at the start of processing. If an input file contains very
+long lines, a larger buffer may be needed; this is handled by automatically
+extending the buffer, up to the limit specified by <b>--max-buffer-size</b>. The
+default values for these parameters are specified when <b>pcre2grep</b> is
+built, with the default defaults being 20K and 1M respectively. An error occurs
+if a line is too long and the buffer can no longer be expanded.
+</P>
+<P>
+The block of memory that is actually used is three times the "buffer size", to
+allow for buffering "before" and "after" lines. If the buffer size is too
+small, fewer than requested "before" and "after" lines may be output.
 </P>
 <P>
 Patterns can be no longer than 8K or BUFSIZ bytes, whichever is the greater.
@@ -125,23 +133,27 @@
 <br><a name="SEC3" href="#TOC1">SUPPORT FOR COMPRESSED FILES</a><br>
 <P>
 It is possible to compile <b>pcre2grep</b> so that it uses <b>libz</b> or
-<b>libbz2</b> to read files whose names end in <b>.gz</b> or <b>.bz2</b>,
-respectively. You can find out whether your binary has support for one or both
-of these file types by running it with the <b>--help</b> option. If the
-appropriate support is not present, files are treated as plain text. The
-standard input is always so treated.
+<b>libbz2</b> to read compressed files whose names end in <b>.gz</b> or
+<b>.bz2</b>, respectively. You can find out whether your <b>pcre2grep</b> binary
+has support for one or both of these file types by running it with the
+<b>--help</b> option. If the appropriate support is not present, all files are
+treated as plain text. The standard input is always so treated. When input is
+from a compressed .gz or .bz2 file, the <b>--line-buffered</b> option is
+ignored.
 </P>
 <br><a name="SEC4" href="#TOC1">BINARY FILES</a><br>
 <P>
 By default, a file that contains a binary zero byte within the first 1024 bytes
-is identified as a binary file, and is processed specially. (GNU grep also
-identifies binary files in this manner.) See the <b>--binary-files</b> option
-for a means of changing the way binary files are handled.
+is identified as a binary file, and is processed specially. (GNU grep
+identifies binary files in this manner.) However, if the newline type is
+specified as "nul", that is, the line terminator is a binary zero, the test for
+a binary file is not applied. See the <b>--binary-files</b> option for a means
+of changing the way binary files are handled.
 </P>
 <br><a name="SEC5" href="#TOC1">OPTIONS</a><br>
 <P>
 The order in which some of the options appear can affect the output. For
-example, both the <b>-h</b> and <b>-l</b> options affect the printing of file
+example, both the <b>-H</b> and <b>-l</b> options affect the printing of file
 names. Whichever comes later in the command line will be the one that takes
 effect. Similarly, except where noted below, if an option is given twice, the
 later setting is used. Numerical values for options may be followed by K or M,
@@ -155,12 +167,13 @@
 </P>
 <P>
 <b>-A</b> <i>number</i>, <b>--after-context=</b><i>number</i>
-Output <i>number</i> lines of context after each matching line. If file names
-and/or line numbers are being output, a hyphen separator is used instead of a
-colon for the context lines. A line containing "--" is output between each
-group of lines, unless they are in fact contiguous in the input file. The value
-of <i>number</i> is expected to be relatively small. However, <b>pcre2grep</b>
-guarantees to have up to 8K of following text available for context output.
+Output up to <i>number</i> lines of context after each matching line. Fewer
+lines are output if the next match or the end of the file is reached, or if the
+processing buffer size has been set too small. If file names and/or line
+numbers are being output, a hyphen separator is used instead of a colon for the
+context lines. A line containing "--" is output between each group of lines,
+unless they are in fact contiguous in the input file. The value of <i>number</i>
+is expected to be relatively small. When <b>-c</b> is used, <b>-A</b> is ignored.
 </P>
 <P>
 <b>-a</b>, <b>--text</b>
@@ -169,12 +182,14 @@
 </P>
 <P>
 <b>-B</b> <i>number</i>, <b>--before-context=</b><i>number</i>
-Output <i>number</i> lines of context before each matching line. If file names
-and/or line numbers are being output, a hyphen separator is used instead of a
-colon for the context lines. A line containing "--" is output between each
-group of lines, unless they are in fact contiguous in the input file. The value
-of <i>number</i> is expected to be relatively small. However, <b>pcre2grep</b>
-guarantees to have up to 8K of preceding text available for context output.
+Output up to <i>number</i> lines of context before each matching line. Fewer
+lines are output if the previous match or the start of the file is within
+<i>number</i> lines, or if the processing buffer size has been set too small. If
+file names and/or line numbers are being output, a hyphen separator is used
+instead of a colon for the context lines. A line containing "--" is output
+between each group of lines, unless they are in fact contiguous in the input
+file. The value of <i>number</i> is expected to be relatively small. When
+<b>-c</b> is used, <b>-B</b> is ignored.
 </P>
 <P>
 <b>--binary-files=</b><i>word</i>
@@ -191,8 +206,9 @@
 </P>
 <P>
 <b>--buffer-size=</b><i>number</i>
-Set the parameter that controls how much memory is used for buffering files
-that are being scanned.
+Set the parameter that controls how much memory is obtained at the start of
+processing for buffering files that are being scanned. See also
+<b>--max-buffer-size</b> below.
 </P>
 <P>
 <b>-C</b> <i>number</i>, <b>--context=</b><i>number</i>
@@ -202,14 +218,16 @@
 <P>
 <b>-c</b>, <b>--count</b>
 Do not output lines from the files that are being scanned; instead output the
-number of matches (or non-matches if <b>-v</b> is used) that would otherwise
-have caused lines to be shown. By default, this count is the same as the number
-of suppressed lines, but if the <b>-M</b> (multiline) option is used (without
-<b>-v</b>), there may be more suppressed lines than the number of matches.
+number of lines that would have been shown, either because they matched, or, if
+<b>-v</b> is set, because they failed to match. By default, this count is
+exactly the same as the number of lines that would have been output, but if the
+<b>-M</b> (multiline) option is used (without <b>-v</b>), there may be more
+suppressed lines than the count (that is, the number of matches).
 <br>
 <br>
 If no lines are selected, the number zero is output. If several files are are
-being scanned, a count is output for each of them. However, if the
+being scanned, a count is output for each of them and the <b>-t</b> option can
+be used to cause a total to be output at the end. However, if the
 <b>--files-with-matches</b> option is also used, only those files whose counts
 are greater than zero are listed. When <b>-c</b> is used, the <b>-A</b>,
 <b>-B</b>, and <b>-C</b> options are ignored.
@@ -231,12 +249,23 @@
 just one, in order to colour them all.
 <br>
 <br>
-The colour that is used can be specified by setting the environment variable
-PCRE2GREP_COLOUR or PCRE2GREP_COLOR. The value of this variable should be a
-string of two numbers, separated by a semicolon. They are copied directly into
-the control string for setting colour on a terminal, so it is your
-responsibility to ensure that they make sense. If neither of the environment
-variables is set, the default is "1;31", which gives red.
+The colour that is used can be specified by setting one of the environment
+variables PCRE2GREP_COLOUR, PCRE2GREP_COLOR, PCREGREP_COLOUR, or
+PCREGREP_COLOR, which are checked in that order. If none of these are set,
+<b>pcre2grep</b> looks for GREP_COLORS or GREP_COLOR (in that order). The value
+of the variable should be a string of two numbers, separated by a semicolon,
+except in the case of GREP_COLORS, which must start with "ms=" or "mt="
+followed by two semicolon-separated colours, terminated by the end of the
+string or by a colon. If GREP_COLORS does not start with "ms=" or "mt=" it is
+ignored, and GREP_COLOR is checked.
+<br>
+<br>
+If the string obtained from one of the above variables contains any characters
+other than semicolon or digits, the setting is ignored and the default colour
+is used. The string is copied directly into the control string for setting
+colour on a terminal, so it is your responsibility to ensure that the values
+make sense. If no relevant environment variable is set, the default is "1;31",
+which gives red.
 </P>
 <P>
 <b>-D</b> <i>action</i>, <b>--devices=</b><i>action</i>
@@ -255,6 +284,10 @@
 end-of-file; in others it may provoke an error.
 </P>
 <P>
+<b>--depth-limit</b>=<i>number</i>
+See <b>--match-limit</b> below.
+</P>
+<P>
 <b>-e</b> <i>pattern</i>, <b>--regex=</b><i>pattern</i>, <b>--regexp=</b><i>pattern</i>
 Specify a pattern to be matched. This option can be used multiple times in
 order to specify several patterns. It can also be used as a way of specifying a
@@ -321,18 +354,18 @@
 </P>
 <P>
 <b>-f</b> <i>filename</i>, <b>--file=</b><i>filename</i>
-Read patterns from the file, one per line, and match them against
-each line of input. What constitutes a newline when reading the file is the
-operating system's default. The <b>--newline</b> option has no effect on this
-option. Trailing white space is removed from each line, and blank lines are
-ignored. An empty file contains no patterns and therefore matches nothing. See
-also the comments about multiple patterns versus a single pattern with
-alternatives in the description of <b>-e</b> above.
+Read patterns from the file, one per line, and match them against each line of
+input. What constitutes a newline when reading the file is the operating
+system's default. The <b>--newline</b> option has no effect on this option.
+Trailing white space is removed from each line, and blank lines are ignored. An
+empty file contains no patterns and therefore matches nothing. See also the
+comments about multiple patterns versus a single pattern with alternatives in
+the description of <b>-e</b> above.
 <br>
 <br>
-If this option is given more than once, all the specified files are
-read. A data line is output if any of the patterns match it. A file name can
-be given as "-" to refer to the standard input. When <b>-f</b> is used, patterns
+If this option is given more than once, all the specified files are read. A
+data line is output if any of the patterns match it. A file name can be given
+as "-" to refer to the standard input. When <b>-f</b> is used, patterns
 specified on the command line using <b>-e</b> may also be present; they are
 tested before the file's patterns. However, no other pattern is taken from the
 command line; all arguments are treated as the names of paths to be searched.
@@ -355,8 +388,8 @@
 offset from the start of the file and a length, separated by a comma. In this
 mode, no context is shown. That is, the <b>-A</b>, <b>-B</b>, and <b>-C</b>
 options are ignored. If there is more than one match in a line, each of them is
-shown separately. This option is mutually exclusive with <b>--line-offsets</b>
-and <b>--only-matching</b>.
+shown separately. This option is mutually exclusive with <b>--output</b>,
+<b>--line-offsets</b>, and <b>--only-matching</b>.
 </P>
 <P>
 <b>-H</b>, <b>--with-filename</b>
@@ -365,14 +398,20 @@
 For matching lines, the file name is followed by a colon; for context lines, a
 hyphen separator is used. If a line number is also being output, it follows the
 file name. When the <b>-M</b> option causes a pattern to match more than one
-line, only the first is preceded by the file name.
+line, only the first is preceded by the file name. This option overrides any
+previous <b>-h</b>, <b>-l</b>, or <b>-L</b> options.
 </P>
 <P>
 <b>-h</b>, <b>--no-filename</b>
 Suppress the output file names when searching multiple files. By default,
 file names are shown when multiple files are searched. For matching lines, the
 file name is followed by a colon; for context lines, a hyphen separator is used.
-If a line number is also being output, it follows the file name.
+If a line number is also being output, it follows the file name. This option
+overrides any previous <b>-H</b>, <b>-L</b>, or <b>-l</b> options.
+</P>
+<P>
+<b>--heap-limit</b>=<i>number</i>
+See <b>--match-limit</b> below.
 </P>
 <P>
 <b>--help</b>
@@ -425,17 +464,19 @@
 <b>-L</b>, <b>--files-without-match</b>
 Instead of outputting lines from the files, just output the names of the files
 that do not contain any lines that would have been output. Each file name is
-output once, on a separate line.
+output once, on a separate line. This option overrides any previous <b>-H</b>,
+<b>-h</b>, or <b>-l</b> options.
 </P>
 <P>
 <b>-l</b>, <b>--files-with-matches</b>
 Instead of outputting lines from the files, just output the names of the files
-containing lines that would have been output. Each file name is output
-once, on a separate line. Searching normally stops as soon as a matching line
-is found in a file. However, if the <b>-c</b> (count) option is also used,
-matching continues in order to obtain the correct count, and those files that
-have at least one match are listed along with their counts. Using this option
-with <b>-c</b> is a way of suppressing the listing of files with no matches.
+containing lines that would have been output. Each file name is output once, on
+a separate line. Searching normally stops as soon as a matching line is found
+in a file. However, if the <b>-c</b> (count) option is also used, matching
+continues in order to obtain the correct count, and those files that have at
+least one match are listed along with their counts. Using this option with
+<b>-c</b> is a way of suppressing the listing of files with no matches. This
+opeion overrides any previous <b>-H</b>, <b>-h</b>, or <b>-L</b> options.
 </P>
 <P>
 <b>--label</b>=<i>name</i>
@@ -445,14 +486,16 @@
 </P>
 <P>
 <b>--line-buffered</b>
-When this option is given, input is read and processed line by line, and the
-output is flushed after each write. By default, input is read in large chunks,
-unless <b>pcre2grep</b> can determine that it is reading from a terminal (which
-is currently possible only in Unix-like environments). Output to terminal is
-normally automatically flushed by the operating system. This option can be
-useful when the input or output is attached to a pipe and you do not want
-<b>pcre2grep</b> to buffer up large amounts of data. However, its use will
-affect performance, and the <b>-M</b> (multiline) option ceases to work.
+When this option is given, non-compressed input is read and processed line by
+line, and the output is flushed after each write. By default, input is read in
+large chunks, unless <b>pcre2grep</b> can determine that it is reading from a
+terminal (which is currently possible only in Unix-like environments). Output
+to terminal is normally automatically flushed by the operating system. This
+option can be useful when the input or output is attached to a pipe and you do
+not want <b>pcre2grep</b> to buffer up large amounts of data. However, its use
+will affect performance, and the <b>-M</b> (multiline) option ceases to work.
+When input is from a compressed .gz or .bz2 file, <b>--line-buffered</b> is
+ignored.
 </P>
 <P>
 <b>--line-offsets</b>
@@ -462,7 +505,8 @@
 offset and length are separated by a comma. In this mode, no context is shown.
 That is, the <b>-A</b>, <b>-B</b>, and <b>-C</b> options are ignored. If there is
 more than one match in a line, each of them is shown separately. This option is
-mutually exclusive with <b>--file-offsets</b> and <b>--only-matching</b>.
+mutually exclusive with <b>--output</b>, <b>--file-offsets</b>, and
+<b>--only-matching</b>.
 </P>
 <P>
 <b>--locale</b>=<i>locale-name</i>
@@ -473,51 +517,57 @@
 </P>
 <P>
 <b>--match-limit</b>=<i>number</i>
-Processing some regular expression patterns can require a very large amount of
-memory, leading in some cases to a program crash if not enough is available.
-Other patterns may take a very long time to search for all possible matching
-strings. The <b>pcre2_match()</b> function that is called by <b>pcre2grep</b> to
-do the matching has two parameters that can limit the resources that it uses.
+Processing some regular expression patterns may take a very long time to search
+for all possible matching strings. Others may require a very large amount of
+memory. There are three options that set resource limits for matching.
 <br>
 <br>
-The <b>--match-limit</b> option provides a means of limiting resource usage
-when processing patterns that are not going to match, but which have a very
-large number of possibilities in their search trees. The classic example is a
-pattern that uses nested unlimited repeats. Internally, PCRE2 uses a function
-called <b>match()</b> which it calls repeatedly (sometimes recursively). The
-limit set by <b>--match-limit</b> is imposed on the number of times this
-function is called during a match, which has the effect of limiting the amount
-of backtracking that can take place.
+The <b>--match-limit</b> option provides a means of limiting computing resource
+usage when processing patterns that are not going to match, but which have a
+very large number of possibilities in their search trees. The classic example
+is a pattern that uses nested unlimited repeats. Internally, PCRE2 has a
+counter that is incremented each time around its main processing loop. If the
+value set by <b>--match-limit</b> is reached, an error occurs.
 <br>
 <br>
-The <b>--recursion-limit</b> option is similar to <b>--match-limit</b>, but
-instead of limiting the total number of times that <b>match()</b> is called, it
-limits the depth of recursive calls, which in turn limits the amount of memory
-that can be used. The recursion depth is a smaller number than the total number
-of calls, because not all calls to <b>match()</b> are recursive. This limit is
-of use only if it is set smaller than <b>--match-limit</b>.
+The <b>--heap-limit</b> option specifies, as a number of kilobytes, the amount
+of heap memory that may be used for matching. Heap memory is needed only if
+matching the pattern requires a significant number of nested backtracking
+points to be remembered. This parameter can be set to zero to forbid the use of
+heap memory altogether.
+<br>
+<br>
+The <b>--depth-limit</b> option limits the depth of nested backtracking points,
+which indirectly limits the amount of memory that is used. The amount of memory
+needed for each backtracking point depends on the number of capturing
+parentheses in the pattern, so the amount of memory that is used before this
+limit acts varies from pattern to pattern. This limit is of use only if it is
+set smaller than <b>--match-limit</b>.
 <br>
 <br>
 There are no short forms for these options. The default settings are specified
-when the PCRE2 library is compiled, with the default default being 10 million.
+when the PCRE2 library is compiled, with the default defaults being very large
+and so effectively unlimited.
+</P>
+<P>
+\fB--max-buffer-size=<i>number</i>
+This limits the expansion of the processing buffer, whose initial size can be
+set by <b>--buffer-size</b>. The maximum buffer size is silently forced to be no
+smaller than the starting buffer size.
 </P>
 <P>
 <b>-M</b>, <b>--multiline</b>
-Allow patterns to match more than one line. When this option is given, patterns
-may usefully contain literal newline characters and internal occurrences of ^
-and $ characters. The output for a successful match may consist of more than
-one line. The first is the line in which the match started, and the last is the
-line in which the match ended. If the matched string ends with a newline
-sequence the output ends at the end of that line.
-<br>
-<br>
-When this option is set, the PCRE2 library is called in "multiline" mode. This
-allows a matched string to extend past the end of a line and continue on one or
-more subsequent lines. However, <b>pcre2grep</b> still processes the input line
-by line. Once a match has been handled, scanning restarts at the beginning of
-the next line, just as it does when <b>-M</b> is not present. This means that it
-is possible for the second or subsequent lines in a multiline match to be
-output again as part of another match.
+Allow patterns to match more than one line. When this option is set, the PCRE2
+library is called in "multiline" mode. This allows a matched string to extend
+past the end of a line and continue on one or more subsequent lines. Patterns
+used with <b>-M</b> may usefully contain literal newline characters and internal
+occurrences of ^ and $ characters. The output for a successful match may
+consist of more than one line. The first line is the line in which the match
+started, and the last line is the line in which the match ended. If the matched
+string ends with a newline sequence, the output ends at the end of that line.
+If <b>-v</b> is set, none of the lines in a multi-line match are output. Once a
+match has been handled, scanning restarts at the beginning of the line after
+the one in which the match ended.
 <br>
 <br>
 The newline sequence that separates multiple lines must be matched as part of
@@ -533,11 +583,8 @@
 <br>
 <br>
 There is a limit to the number of lines that can be matched, imposed by the way
-that <b>pcre2grep</b> buffers the input file as it scans it. However,
-<b>pcre2grep</b> ensures that at least 8K characters or the rest of the file
-(whichever is the shorter) are available for forward matching, and similarly
-the previous 8K characters (or all the previous characters, if fewer than 8K)
-are guaranteed to be available for lookbehind assertions. The <b>-M</b> option
+that <b>pcre2grep</b> buffers the input file as it scans it. With a sufficiently
+large processing buffer, this should not be a problem, but the <b>-M</b> option
 does not work when input is read line by line (see \fP--line-buffered\fP.)
 </P>
 <P>
@@ -581,16 +628,47 @@
 It should never be needed in normal use.
 </P>
 <P>
+<b>-O</b> <i>text</i>, <b>--output</b>=<i>text</i>
+When there is a match, instead of outputting the whole line that matched,
+output just the given text. This option is mutually exclusive with
+<b>--only-matching</b>, <b>--file-offsets</b>, and <b>--line-offsets</b>. Escape
+sequences starting with a dollar character may be used to insert the contents
+of the matched part of the line and/or captured substrings into the text.
+<br>
+<br>
+$&#60;digits&#62; or ${&#60;digits&#62;} is replaced by the captured
+substring of the given decimal number; zero substitutes the whole match. If
+the number is greater than the number of capturing substrings, or if the
+capture is unset, the replacement is empty.
+<br>
+<br>
+$a is replaced by bell; $b by backspace; $e by escape; $f by form feed; $n by
+newline; $r by carriage return; $t by tab; $v by vertical tab.
+<br>
+<br>
+$o&#60;digits&#62; is replaced by the character represented by the given octal
+number; up to three digits are processed.
+<br>
+<br>
+$x&#60;digits&#62; is replaced by the character represented by the given hexadecimal
+number; up to two digits are processed.
+<br>
+<br>
+Any other character is substituted by itself. In particular, $$ is replaced by
+a single dollar.
+</P>
+<P>
 <b>-o</b>, <b>--only-matching</b>
 Show only the part of the line that matched a pattern instead of the whole
 line. In this mode, no context is shown. That is, the <b>-A</b>, <b>-B</b>, and
 <b>-C</b> options are ignored. If there is more than one match in a line, each
-of them is shown separately. If <b>-o</b> is combined with <b>-v</b> (invert the
-sense of the match to find non-matching lines), no output is generated, but the
-return code is set appropriately. If the matched portion of the line is empty,
-nothing is output unless the file name or line number are being printed, in
-which case they are shown on an otherwise empty line. This option is mutually
-exclusive with <b>--file-offsets</b> and <b>--line-offsets</b>.
+of them is shown separately, on a separate line of output. If <b>-o</b> is
+combined with <b>-v</b> (invert the sense of the match to find non-matching
+lines), no output is generated, but the return code is set appropriately. If
+the matched portion of the line is empty, nothing is output unless the file
+name or line number are being printed, in which case they are shown on an
+otherwise empty line. This option is mutually exclusive with <b>--output</b>,
+<b>--file-offsets</b> and <b>--line-offsets</b>.
 </P>
 <P>
 <b>-o</b><i>number</i>, <b>--only-matching</b>=<i>number</i>
@@ -599,15 +677,16 @@
 equivalent to <b>-o</b> without a number. Because these options can be given
 without an argument (see above), if an argument is present, it must be given in
 the same shell item, for example, -o3 or --only-matching=2. The comments given
-for the non-argument case above also apply to this case. If the specified
+for the non-argument case above also apply to this option. If the specified
 capturing parentheses do not exist in the pattern, or were not set in the
 match, nothing is output unless the file name or line number are being output.
 <br>
 <br>
-If this option is given multiple times, multiple substrings are output, in the
-order the options are given. For example, -o3 -o1 -o3 causes the substrings
-matched by capturing parentheses 3 and 1 and then 3 again to be output. By
-default, there is no separator (but see the next option).
+If this option is given multiple times, multiple substrings are output for each
+match, in the order the options are given, and all on one line. For example,
+-o3 -o1 -o3 causes the substrings matched by capturing parentheses 3 and 1 and
+then 3 again to be output. By default, there is no separator (but see the next
+option).
 </P>
 <P>
 <b>--om-separator</b>=<i>text</i>
@@ -638,6 +717,18 @@
 found in other files.
 </P>
 <P>
+<b>-t</b>, <b>--total-count</b>
+This option is useful when scanning more than one file. If used on its own,
+<b>-t</b> suppresses all output except for a grand total number of matching
+lines (or non-matching lines if <b>-v</b> is used) in all the files. If <b>-t</b>
+is used with <b>-c</b>, a grand total is output except when the previous output
+is just one line. In other words, it is not output when just one file's count
+is listed. If file names are being output, the grand total is preceded by
+"TOTAL:". Otherwise, it appears as just another number. The <b>-t</b> option is
+ignored when used with <b>-L</b> (list files without matches), because the grand
+total would always be zero.
+</P>
+<P>
 <b>-u</b>, <b>--utf-8</b>
 Operate in UTF-8 mode. This option is available only if PCRE2 has been compiled
 with UTF-8 support. All patterns (including those for any <b>--exclude</b> and
@@ -657,17 +748,19 @@
 </P>
 <P>
 <b>-w</b>, <b>--word-regex</b>, <b>--word-regexp</b>
-Force the patterns to match only whole words. This is equivalent to having \b
-at the start and end of the pattern. This option applies only to the patterns
-that are matched against the contents of files; it does not apply to patterns
-specified by any of the <b>--include</b> or <b>--exclude</b> options.
+Force the patterns only to match "words". That is, there must be a word
+boundary at the start and end of each matched string. This is equivalent to
+having "\b(?:" at the start of each pattern, and ")\b" at the end. This
+option applies only to the patterns that are matched against the contents of
+files; it does not apply to patterns specified by any of the <b>--include</b> or
+<b>--exclude</b> options.
 </P>
 <P>
 <b>-x</b>, <b>--line-regex</b>, <b>--line-regexp</b>
-Force the patterns to be anchored (each must start matching at the beginning of
-a line) and in addition, require them to match entire lines. This is equivalent
-to having ^ and $ characters at the start and end of each alternative top-level
-branch in every pattern. This option applies only to the patterns that are
+Force the patterns to start matching only at the beginnings of lines, and in
+addition, require them to match entire lines. In multiline mode the match may
+be more than one line. This is equivalent to having "^(?:" at the start of each
+pattern and ")$" at the end. This option applies only to the patterns that are
 matched against the contents of files; it does not apply to patterns specified
 by any of the <b>--include</b> or <b>--exclude</b> options.
 </P>
@@ -696,10 +789,11 @@
 Many of the short and long forms of <b>pcre2grep</b>'s options are the same
 as in the GNU <b>grep</b> program. Any long option of the form
 <b>--xxx-regexp</b> (GNU terminology) is also available as <b>--xxx-regex</b>
-(PCRE2 terminology). However, the <b>--file-list</b>, <b>--file-offsets</b>,
-<b>--include-dir</b>, <b>--line-offsets</b>, <b>--locale</b>, <b>--match-limit</b>,
-<b>-M</b>, <b>--multiline</b>, <b>-N</b>, <b>--newline</b>, <b>--om-separator</b>,
-<b>--recursion-limit</b>, <b>-u</b>, and <b>--utf-8</b> options are specific to
+(PCRE2 terminology). However, the <b>--depth-limit</b>, <b>--file-list</b>,
+<b>--file-offsets</b>, <b>--heap-limit</b>, <b>--include-dir</b>,
+<b>--line-offsets</b>, <b>--locale</b>, <b>--match-limit</b>, <b>-M</b>,
+<b>--multiline</b>, <b>-N</b>, <b>--newline</b>, <b>--om-separator</b>,
+<b>--output</b>, <b>-u</b>, and <b>--utf-8</b> options are specific to
 <b>pcre2grep</b>, as is the use of the <b>--only-matching</b> option with a
 capturing parentheses number.
 </P>
@@ -742,23 +836,30 @@
 options does have data, it must be given in the first form, using an equals
 character. Otherwise <b>pcre2grep</b> will assume that it has no data.
 </P>
-<br><a name="SEC10" href="#TOC1">CALLING EXTERNAL SCRIPTS</a><br>
+<br><a name="SEC10" href="#TOC1">USING PCRE2'S CALLOUT FACILITY</a><br>
 <P>
-On non-Windows systems, <b>pcre2grep</b> has, by default, support for calling
-external programs or scripts during matching by making use of PCRE2's callout
-facility. However, this support can be disabled when <b>pcre2grep</b> is built.
-You can find out whether your binary has support for callouts by running it
-with the <b>--help</b> option. If the support is not enabled, all callouts in
+<b>pcre2grep</b> has, by default, support for calling external programs or
+scripts or echoing specific strings during matching by making use of PCRE2's
+callout facility. However, this support can be disabled when <b>pcre2grep</b> is
+built. You can find out whether your binary has support for callouts by running
+it with the <b>--help</b> option. If the support is not enabled, all callouts in
 patterns are ignored by <b>pcre2grep</b>.
 </P>
 <P>
 A callout in a PCRE2 pattern is of the form (?C&#60;arg&#62;) where the argument is
 either a number or a quoted string (see the
 <a href="pcre2callout.html"><b>pcre2callout</b></a>
-documentation for details). Numbered callouts are ignored by <b>pcre2grep</b>.
-String arguments are parsed as a list of substrings separated by pipe (vertical
-bar) characters. The first substring must be an executable name, with the
-following substrings specifying arguments:
+documentation for details). Numbered callouts are ignored by <b>pcre2grep</b>;
+only callouts with string arguments are useful.
+</P>
+<br><b>
+Calling external programs or scripts
+</b><br>
+<P>
+If the callout string does not start with a pipe (vertical bar) character, it
+is parsed into a list of substrings separated by pipe characters. The first
+substring must be an executable name, with the following substrings specifying
+arguments:
 <pre>
   executable_name|arg1|arg2|...
 </pre>
@@ -792,6 +893,19 @@
 the non-existence of the executable), a local matching failure occurs and the
 matcher backtracks in the normal way.
 </P>
+<br><b>
+Echoing a specific string
+</b><br>
+<P>
+If the callout string starts with a pipe (vertical bar) character, the rest of
+the string is written to the output, having been passed through the same escape
+processing as text from the --output option. This provides a simple echoing
+facility that avoids calling an external program or script. No terminator is
+added to the string, so if you want a newline, you must include it explicitly.
+Matching continues normally after the string is output. If you want to see only
+the callout output but not any output from an actual match, you should end the
+relevant pattern with (*FAIL).
+</P>
 <br><a name="SEC11" href="#TOC1">MATCHING ERRORS</a><br>
 <P>
 It is possible to supply a regular expression that takes a very long time to
@@ -804,9 +918,9 @@
 </P>
 <P>
 The <b>--match-limit</b> option of <b>pcre2grep</b> can be used to set the
-overall resource limit; there is a second option called <b>--recursion-limit</b>
-that sets a limit on the amount of memory (usually stack) that is used (see the
-discussion of these options above).
+overall resource limit. There are also other limits that affect the amount of
+memory used during matching; see the discussion of <b>--heap-limit</b> and
+<b>--depth-limit</b> above.
 </P>
 <br><a name="SEC12" href="#TOC1">DIAGNOSTICS</a><br>
 <P>
@@ -816,6 +930,10 @@
 <b>-s</b> option to suppress error messages about inaccessible files does not
 affect the return code.
 </P>
+<P>
+When run under VMS, the return code is placed in the symbol PCRE2GREP_RC
+because VMS does not distinguish between exit(0) and exit(1).
+</P>
 <br><a name="SEC13" href="#TOC1">SEE ALSO</a><br>
 <P>
 <b>pcre2pattern</b>(3), <b>pcre2syntax</b>(3), <b>pcre2callout</b>(3).
@@ -831,9 +949,9 @@
 </P>
 <br><a name="SEC15" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 19 June 2016
+Last updated: 13 November 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2jit.html b/dist2/doc/html/pcre2jit.html
index 4a6d4ff..c53d3d9 100644
--- a/dist2/doc/html/pcre2jit.html
+++ b/dist2/doc/html/pcre2jit.html
@@ -173,7 +173,7 @@
 The error code PCRE2_ERROR_MATCHLIMIT is returned by the JIT code if searching
 a very large pattern tree goes on for too long, as it is in the same
 circumstance when JIT is not used, but the details of exactly what is counted
-are not the same. The PCRE2_ERROR_RECURSIONLIMIT error code is never returned
+are not the same. The PCRE2_ERROR_DEPTHLIMIT error code is never returned
 when JIT matching is used.
 <a name="stackcontrol"></a></P>
 <br><a name="SEC6" href="#TOC1">CONTROLLING THE JIT STACK</a><br>
@@ -194,12 +194,8 @@
 pointer to an opaque structure of type <b>pcre2_jit_stack</b>, or NULL if there
 is an error. The <b>pcre2_jit_stack_free()</b> function is used to free a stack
 that is no longer needed. (For the technically minded: the address space is
-allocated by mmap or VirtualAlloc.)
-</P>
-<P>
-JIT uses far less memory for recursion than the interpretive code,
-and a maximum stack size of 512K to 1M should be more than enough for any
-pattern.
+allocated by mmap or VirtualAlloc.) A maximum stack size of 512K to 1M should
+be more than enough for any pattern.
 </P>
 <P>
 The <b>pcre2_jit_stack_assign()</b> function specifies which stack JIT code
@@ -436,9 +432,9 @@
 </P>
 <br><a name="SEC13" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 05 June 2016
+Last updated: 31 March 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2limits.html b/dist2/doc/html/pcre2limits.html
index e227a30..640fe3d 100644
--- a/dist2/doc/html/pcre2limits.html
+++ b/dist2/doc/html/pcre2limits.html
@@ -44,14 +44,6 @@
 and unset offsets.
 </P>
 <P>
-Note that when using the traditional matching function, PCRE2 uses recursion to
-handle subpatterns and indefinite repetition. This means that the available
-stack space may limit the size of a subject string that can be processed by
-certain patterns. For a discussion of stack issues, see the
-<a href="pcre2stack.html"><b>pcre2stack</b></a>
-documentation.
-</P>
-<P>
 All values in repeating quantifiers must be less than 65536.
 </P>
 <P>
@@ -61,14 +53,10 @@
 There is no limit to the number of parenthesized subpatterns, but there can be
 no more than 65535 capturing subpatterns. There is, however, a limit to the
 depth of nesting of parenthesized subpatterns of all kinds. This is imposed in
-order to limit the amount of system stack used at compile time. The limit can
-be specified when PCRE2 is built; the default is 250.
-</P>
-<P>
-There is a limit to the number of forward references to subsequent subpatterns
-of around 200,000. Repeated forward references with fixed upper limits, for
-example, (?2){0,100} when subpattern number 2 is to the right, are included in
-the count. There is no limit to the number of backward references.
+order to limit the amount of system stack used at compile time. The default
+limit can be specified when PCRE2 is built; the default default is 250. An
+application can change this limit by calling pcre2_set_parens_nest_limit() to
+set the limit in a compile context.
 </P>
 <P>
 The maximum length of name for a named subpattern is 32 code units, and the
@@ -76,7 +64,12 @@
 </P>
 <P>
 The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb
-is 255 for the 8-bit library and 65535 for the 16-bit and 32-bit libraries.
+is 255 code units for the 8-bit library and 65535 code units for the 16-bit and
+32-bit libraries.
+</P>
+<P>
+The maximum length of a string argument to a callout is the largest number a
+32-bit unsigned integer can hold.
 </P>
 <br><b>
 AUTHOR
@@ -93,9 +86,9 @@
 REVISION
 </b><br>
 <P>
-Last updated: 05 November 2015
+Last updated: 30 March 2017
 <br>
-Copyright &copy; 1997-2015 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2pattern.html b/dist2/doc/html/pcre2pattern.html
index 797690a..c495cba 100644
--- a/dist2/doc/html/pcre2pattern.html
+++ b/dist2/doc/html/pcre2pattern.html
@@ -170,35 +170,54 @@
 <b>pcre2_jit_compile()</b> is ignored.
 </P>
 <br><b>
-Setting match and recursion limits
+Setting match resource limits
 </b><br>
 <P>
-The caller of <b>pcre2_match()</b> can set a limit on the number of times the
-internal <b>match()</b> function is called and on the maximum depth of
-recursive calls. These facilities are provided to catch runaway matches that
-are provoked by patterns with huge matching trees (a typical example is a
-pattern with nested unlimited repeats) and to avoid running out of system stack
-by too much recursion. When one of these limits is reached, <b>pcre2_match()</b>
-gives an error return. The limits can also be set by items at the start of the
-pattern of the form
+The pcre2_match() function contains a counter that is incremented every time it
+goes round its main loop. The caller of <b>pcre2_match()</b> can set a limit on
+this counter, which therefore limits the amount of computing resource used for
+a match. The maximum depth of nested backtracking can also be limited; this
+indirectly restricts the amount of heap memory that is used, but there is also
+an explicit memory limit that can be set.
+</P>
+<P>
+These facilities are provided to catch runaway matches that are provoked by
+patterns with huge matching trees (a typical example is a pattern with nested
+unlimited repeats applied to a long string that does not match). When one of
+these limits is reached, <b>pcre2_match()</b> gives an error return. The limits
+can also be set by items at the start of the pattern of the form
 <pre>
+  (*LIMIT_HEAP=d)
   (*LIMIT_MATCH=d)
-  (*LIMIT_RECURSION=d)
+  (*LIMIT_DEPTH=d)
 </pre>
 where d is any number of decimal digits. However, the value of the setting must
 be less than the value set (or defaulted) by the caller of <b>pcre2_match()</b>
 for it to have any effect. In other words, the pattern writer can lower the
 limits set by the programmer, but not raise them. If there is more than one
 setting of one of these limits, the lower value is used.
+</P>
+<P>
+Prior to release 10.30, LIMIT_DEPTH was called LIMIT_RECURSION. This name is
+still recognized for backwards compatibility.
+</P>
+<P>
+The heap limit applies only when the <b>pcre2_match()</b> interpreter is used
+for matching. It does not apply to JIT or DFA matching. The match limit is used
+(but in a different way) when JIT is being used, or when
+<b>pcre2_dfa_match()</b> is called, to limit computing resource usage by those
+matching functions. The depth limit is ignored by JIT but is relevant for DFA
+matching, which uses function recursion for recursions within the pattern. In
+this case, the depth limit controls the amount of system stack that is used.
 <a name="newlines"></a></P>
 <br><b>
 Newline conventions
 </b><br>
 <P>
-PCRE2 supports five different conventions for indicating line breaks in
+PCRE2 supports six different conventions for indicating line breaks in
 strings: a single CR (carriage return) character, a single LF (linefeed)
-character, the two-character sequence CRLF, any of the three preceding, or any
-Unicode newline sequence. The
+character, the two-character sequence CRLF, any of the three preceding, any
+Unicode newline sequence, or the NUL character (binary zero). The
 <a href="pcre2api.html"><b>pcre2api</b></a>
 page has
 <a href="pcre2api.html#newlines">further discussion</a>
@@ -207,13 +226,14 @@
 </P>
 <P>
 It is also possible to specify a newline convention by starting a pattern
-string with one of the following five sequences:
+string with one of the following sequences:
 <pre>
   (*CR)        carriage return
   (*LF)        linefeed
   (*CRLF)      carriage return, followed by linefeed
   (*ANYCRLF)   any of the three above
   (*ANY)       all Unicode newline sequences
+  (*NUL)       the NUL character (binary zero)
 </pre>
 These override the default and the options given to the compiling function. For
 example, on a Unix system where LF is the default newline sequence, the pattern
@@ -229,8 +249,8 @@
 true. It also affects the interpretation of the dot metacharacter when
 PCRE2_DOTALL is not set, and the behaviour of \N. However, it does not affect
 what the \R escape sequence matches. By default, this is any Unicode newline
-sequence, for Perl compatibility. However, this can be changed; see the
-description of \R in the section entitled
+sequence, for Perl compatibility. However, this can be changed; see the next
+section and the description of \R in the section entitled
 <a href="#newlineseq">"Newline sequences"</a>
 below. A change of \R setting can be combined with a change of newline
 convention.
@@ -248,7 +268,7 @@
 <br><a name="SEC3" href="#TOC1">EBCDIC CHARACTER CODES</a><br>
 <P>
 PCRE2 can be compiled to run in an environment that uses EBCDIC as its
-character code rather than ASCII or Unicode (typically a mainframe system). In
+character code instead of ASCII or Unicode (typically a mainframe system). In
 the sections below, character code values are ASCII or Unicode; in an EBCDIC
 environment these characters may have different code values, and there are no
 code points greater than 255.
@@ -312,11 +332,11 @@
 both inside and outside character classes.
 </P>
 <P>
-For example, if you want to match a * character, you write \* in the pattern.
-This escaping action applies whether or not the following character would
-otherwise be interpreted as a metacharacter, so it is always safe to precede a
-non-alphanumeric with backslash to specify that it stands for itself. In
-particular, if you want to match a backslash, you write \\.
+For example, if you want to match a * character, you must write \* in the
+pattern. This escaping action applies whether or not the following character
+would otherwise be interpreted as a metacharacter, so it is always safe to
+precede a non-alphanumeric with backslash to specify that it stands for itself.
+In particular, if you want to match a backslash, you write \\.
 </P>
 <P>
 In a UTF mode, only ASCII numbers and letters have any special meaning after a
@@ -347,7 +367,7 @@
 by \E later in the pattern, the literal interpretation continues to the end of
 the pattern (that is, \E is assumed at the end). If the isolated \Q is inside
 a character class, this causes an error, because the character class is not
-terminated.
+terminated by a closing square bracket.
 <a name="digitsafterbackslash"></a></P>
 <br><b>
 Non-printing characters
@@ -379,32 +399,31 @@
 40) is inverted. Thus \cA to \cZ become hex 01 to hex 1A (A is 41, Z is 5A),
 but \c{ becomes hex 3B ({ is 7B), and \c; becomes hex 7B (; is 3B). If the
 code unit following \c has a value less than 32 or greater than 126, a
-compile-time error occurs. This locks out non-printable ASCII characters in all
-modes.
+compile-time error occurs.
 </P>
 <P>
 When PCRE2 is compiled in EBCDIC mode, \a, \e, \f, \n, \r, and \t
 generate the appropriate EBCDIC code values. The \c escape is processed
 as specified for Perl in the <b>perlebcdic</b> document. The only characters
 that are allowed after \c are A-Z, a-z, or one of @, [, \, ], ^, _, or ?. Any
-other character provokes a compile-time error. The sequence \@ encodes
-character code 0; the letters (in either case) encode characters 1-26 (hex 01
-to hex 1A); [, \, ], ^, and _ encode characters 27-31 (hex 1B to hex 1F), and
-\? becomes either 255 (hex FF) or 95 (hex 5F).
+other character provokes a compile-time error. The sequence \c@ encodes
+character code 0; after \c the letters (in either case) encode characters 1-26
+(hex 01 to hex 1A); [, \, ], ^, and _ encode characters 27-31 (hex 1B to hex
+1F), and \c? becomes either 255 (hex FF) or 95 (hex 5F).
 </P>
 <P>
-Thus, apart from \?, these escapes generate the same character code values as
+Thus, apart from \c?, these escapes generate the same character code values as
 they do in an ASCII environment, though the meanings of the values mostly
-differ. For example, \G always generates code value 7, which is BEL in ASCII
+differ. For example, \cG always generates code value 7, which is BEL in ASCII
 but DEL in EBCDIC.
 </P>
 <P>
-The sequence \? generates DEL (127, hex 7F) in an ASCII environment, but
+The sequence \c? generates DEL (127, hex 7F) in an ASCII environment, but
 because 127 is not a control character in EBCDIC, Perl makes it generate the
 APC character. Unfortunately, there are several variants of EBCDIC. In most of
 them the APC character has the value 255 (hex FF), but in the one Perl calls
 POSIX-BC its value is 95 (hex 5F). If certain other characters have POSIX-BC
-values, PCRE2 makes \? generate 95; otherwise it generates 255.
+values, PCRE2 makes \c? generate 95; otherwise it generates 255.
 </P>
 <P>
 After \0 up to two further octal digits are read. If there are fewer than two
@@ -471,9 +490,9 @@
 <P>
 If the PCRE2_ALT_BSUX option is set, the interpretation of \x is as just
 described only when it is followed by two hexadecimal digits. Otherwise, it
-matches a literal "x" character. In this mode mode, support for code points
-greater than 256 is provided by \u, which must be followed by four hexadecimal
-digits; otherwise it matches a literal "u" character.
+matches a literal "x" character. In this mode, support for code points greater
+than 256 is provided by \u, which must be followed by four hexadecimal digits;
+otherwise it matches a literal "u" character.
 </P>
 <P>
 Characters whose value is less than 256 can be defined by either of the two
@@ -488,15 +507,15 @@
 Characters that are specified using octal or hexadecimal numbers are
 limited to certain values, as follows:
 <pre>
-  8-bit non-UTF mode    less than 0x100
-  8-bit UTF-8 mode      less than 0x10ffff and a valid codepoint
-  16-bit non-UTF mode   less than 0x10000
-  16-bit UTF-16 mode    less than 0x10ffff and a valid codepoint
-  32-bit non-UTF mode   less than 0x100000000
-  32-bit UTF-32 mode    less than 0x10ffff and a valid codepoint
+  8-bit non-UTF mode    no greater than 0xff
+  16-bit non-UTF mode   no greater than 0xffff
+  32-bit non-UTF mode   no greater than 0xffffffff
+  All UTF modes         no greater than 0x10ffff and a valid codepoint
 </pre>
-Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called
-"surrogate" codepoints), and 0xffef.
+Invalid Unicode codepoints are all those in the range 0xd800 to 0xdfff (the
+so-called "surrogate" codepoints). The check for these can be disabled by the
+caller of <b>pcre2_compile()</b> by setting the option
+PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES.
 </P>
 <br><b>
 Escape sequences in character classes
@@ -520,15 +539,15 @@
 handler and used to modify the case of following characters. By default, PCRE2
 does not support these escape sequences. However, if the PCRE2_ALT_BSUX option
 is set, \U matches a "U" character, and \u can be used to define a character
-by code point, as described in the previous section.
+by code point, as described above.
 </P>
 <br><b>
 Absolute and relative back references
 </b><br>
 <P>
-The sequence \g followed by an unsigned or a negative number, optionally
-enclosed in braces, is an absolute or relative back reference. A named back
-reference can be coded as \g{name}. Back references are discussed
+The sequence \g followed by a signed or unsigned number, optionally enclosed
+in braces, is an absolute or relative back reference. A named back reference
+can be coded as \g{name}. Back references are discussed
 <a href="#backreferences">later,</a>
 following the discussion of
 <a href="#subpattern">parenthesized subpatterns.</a>
@@ -709,7 +728,9 @@
 sequences that match characters with specific properties are available. In
 8-bit non-UTF-8 mode, these sequences are of course limited to testing
 characters whose codepoints are less than 256, but they do work in this mode.
-The extra escape sequences are:
+In 32-bit non-UTF mode, codepoints greater than 0x10ffff (the Unicode limit)
+may be encountered. These are all treated as being in the Common script and
+with an unassigned type. The extra escape sequences are:
 <pre>
   \p{<i>xx</i>}   a character with the <i>xx</i> property
   \P{<i>xx</i>}   a character without the <i>xx</i> property
@@ -736,6 +757,7 @@
 "Common". The current list of scripts is:
 </P>
 <P>
+Adlam,
 Ahom,
 Anatolian_Hieroglyphs,
 Arabic,
@@ -746,6 +768,7 @@
 Bassa_Vah,
 Batak,
 Bengali,
+Bhaiksuki,
 Bopomofo,
 Brahmi,
 Braille,
@@ -807,6 +830,8 @@
 Malayalam,
 Mandaic,
 Manichaean,
+Marchen,
+Masaram_Gondi,
 Meetei_Mayek,
 Mende_Kikakui,
 Meroitic_Cursive,
@@ -819,7 +844,9 @@
 Myanmar,
 Nabataean,
 New_Tai_Lue,
+Newa,
 Nko,
+Nushu,
 Ogham,
 Ol_Chiki,
 Old_Hungarian,
@@ -830,6 +857,7 @@
 Old_South_Arabian,
 Old_Turkic,
 Oriya,
+Osage,
 Osmanya,
 Pahawh_Hmong,
 Palmyrene,
@@ -847,6 +875,7 @@
 SignWriting,
 Sinhala,
 Sora_Sompeng,
+Soyombo,
 Sundanese,
 Syloti_Nagri,
 Syriac,
@@ -857,6 +886,7 @@
 Tai_Viet,
 Takri,
 Tamil,
+Tangut,
 Telugu,
 Thaana,
 Thai,
@@ -866,7 +896,8 @@
 Ugaritic,
 Vai,
 Warang_Citi,
-Yi.
+Yi,
+Zanabazar_Square.
 </P>
 <P>
 Each character has exactly one Unicode general category property, specified by
@@ -972,9 +1003,12 @@
 <a href="#atomicgroup">(see below).</a>
 Unicode supports various kinds of composite character by giving each character
 a grapheme breaking property, and having rules that use these properties to
-define the boundaries of extended grapheme clusters. \X always matches at
-least one character. Then it decides whether to add additional characters
-according to the following rules for ending a cluster:
+define the boundaries of extended grapheme clusters. The rules are defined in
+Unicode Standard Annex 29, "Unicode Text Segmentation".
+</P>
+<P>
+\X always matches at least one character. Then it decides whether to add
+additional characters according to the following rules for ending a cluster:
 </P>
 <P>
 1. End at the end of the subject string.
@@ -989,13 +1023,27 @@
 character; an LVT or T character may be follwed only by a T character.
 </P>
 <P>
-4. Do not end before extending characters or spacing marks. Characters with
-the "mark" property always have the "extend" grapheme breaking property.
+4. Do not end before extending characters or spacing marks or the "zero-width
+joiner" characters. Characters with the "mark" property always have the
+"extend" grapheme breaking property.
 </P>
 <P>
 5. Do not end after prepend characters.
 </P>
 <P>
+6. Do not break within emoji modifier sequences (a base character followed by a
+modifier). Extending characters are allowed before the modifier.
+</P>
+<P>
+7. Do not break within emoji zwj sequences (zero-width jointer followed by
+"glue after ZWJ" or "base glue after ZWJ").
+</P>
+<P>
+8. Do not break within emoji flag sequences. That is, do not break between
+regional indicator (RI) characters if there are an odd number of RI characters
+before the break point.
+</P>
+<P>
 6. Otherwise, end the cluster.
 <a name="extraprops"></a></P>
 <br><b>
@@ -1326,13 +1374,33 @@
 class such as [^a] always matches one of these characters.
 </P>
 <P>
+The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v,
+\V, \w, and \W may appear in a character class, and add the characters that
+they match to the class. For example, [\dABCDEF] matches any hexadecimal
+digit. In UTF modes, the PCRE2_UCP option affects the meanings of \d, \s, \w
+and their upper case partners, just as it does when they appear outside a
+character class, as described in the section entitled
+<a href="#genericchartypes">"Generic character types"</a>
+above. The escape sequence \b has a different meaning inside a character
+class; it matches the backspace character. The sequences \B, \N, \R, and \X
+are not special inside a character class. Like any other unrecognized escape
+sequences, they cause an error.
+</P>
+<P>
 The minus (hyphen) character can be used to specify a range of characters in a
 character class. For example, [d-m] matches any letter between d and m,
 inclusive. If a minus character is required in a class, it must be escaped with
 a backslash or appear in a position where it cannot be interpreted as
-indicating a range, typically as the first or last character in the class, or
-immediately after a range. For example, [b-d-z] matches letters in the range b
-to d, a hyphen character, or z.
+indicating a range, typically as the first or last character in the class,
+or immediately after a range. For example, [b-d-z] matches letters in the range
+b to d, a hyphen character, or z.
+</P>
+<P>
+Perl treats a hyphen as a literal if it appears before or after a POSIX class
+(see below) or before or after a character type escape such as as \d or \H.
+However, unless the hyphen is the last character in the class, Perl outputs a
+warning in its warning mode, as this is most likely a user error. As PCRE2 has
+no facility for warning, an error is given in these cases.
 </P>
 <P>
 It is not possible to have the literal character "]" as the end character of a
@@ -1344,16 +1412,14 @@
 "]" can also be used to end a range.
 </P>
 <P>
-An error is generated if a POSIX character class (see below) or an escape
-sequence other than one that defines a single character appears at a point
-where a range ending character is expected. For example, [z-\xff] is valid,
-but [A-\d] and [A-[:digit:]] are not.
-</P>
-<P>
 Ranges normally include all code points between the start and end characters,
 inclusive. They can also be used for code points specified numerically, for
 example [\000-\037]. Ranges can include any characters that are valid for the
-current mode.
+current mode. In any UTF mode, the so-called "surrogate" characters (those
+whose code points lie between 0xd800 and 0xdfff inclusive) may not be specified
+explicitly by default (the PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES option disables
+this check). However, ranges such as [\x{d7ff}-\x{e000}], which include the
+surrogates, are always permitted.
 </P>
 <P>
 There is a special case in EBCDIC environments for ranges whose end points are
@@ -1372,19 +1438,6 @@
 characters in both cases.
 </P>
 <P>
-The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v,
-\V, \w, and \W may appear in a character class, and add the characters that
-they match to the class. For example, [\dABCDEF] matches any hexadecimal
-digit. In UTF modes, the PCRE2_UCP option affects the meanings of \d, \s, \w
-and their upper case partners, just as it does when they appear outside a
-character class, as described in the section entitled
-<a href="#genericchartypes">"Generic character types"</a>
-above. The escape sequence \b has a different meaning inside a character
-class; it matches the backspace character. The sequences \B, \N, \R, and \X
-are not special inside a character class. Like any other unrecognized escape
-sequences, they cause an error.
-</P>
-<P>
 A circumflex can conveniently be used with the upper case character types to
 specify a more restricted set of characters than the matching lower case type.
 For example, the class [^\W_] matches any letter or digit, but not underscore,
@@ -1526,20 +1579,26 @@
 </P>
 <br><a name="SEC13" href="#TOC1">INTERNAL OPTION SETTING</a><br>
 <P>
-The settings of the PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL, and
-PCRE2_EXTENDED options (which are Perl-compatible) can be changed from within
-the pattern by a sequence of Perl option letters enclosed between "(?" and ")".
-The option letters are
+The settings of the PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL,
+PCRE2_EXTENDED, PCRE2_EXTENDED_MORE, and PCRE2_NO_AUTO_CAPTURE options (which
+are Perl-compatible) can be changed from within the pattern by a sequence of
+Perl option letters enclosed between "(?" and ")". The option letters are
 <pre>
   i  for PCRE2_CASELESS
   m  for PCRE2_MULTILINE
+  n  for PCRE2_NO_AUTO_CAPTURE
   s  for PCRE2_DOTALL
   x  for PCRE2_EXTENDED
+  xx for PCRE2_EXTENDED_MORE
 </pre>
 For example, (?im) sets caseless, multiline matching. It is also possible to
-unset these options by preceding the letter with a hyphen, and a combined
-setting and unsetting such as (?im-sx), which sets PCRE2_CASELESS and
-PCRE2_MULTILINE while unsetting PCRE2_DOTALL and PCRE2_EXTENDED, is also
+unset these options by preceding the letter with a hyphen. The two "extended"
+options are not independent; unsetting either one cancels the effects of both
+of them.
+</P>
+<P>
+A combined setting and unsetting such as (?im-sx), which sets PCRE2_CASELESS
+and PCRE2_MULTILINE while unsetting PCRE2_DOTALL and PCRE2_EXTENDED, is also
 permitted. If a letter appears both before and after the hyphen, the option is
 unset. An empty options setting "(?)" is allowed. Needless to say, it has no
 effect.
@@ -1552,13 +1611,8 @@
 <P>
 When one of these option changes occurs at top level (that is, not inside
 subpattern parentheses), the change applies to the remainder of the pattern
-that follows. If the change is placed right at the start of a pattern, PCRE2
-extracts it into the global options (and it will therefore show up in data
-extracted by the <b>pcre2_pattern_info()</b> function).
-</P>
-<P>
-An option change within a subpattern (see below for a description of
-subpatterns) affects only that part of the subpattern that follows it, so
+that follows. An option change within a subpattern (see below for a description
+of subpatterns) affects only that part of the subpattern that follows it, so
 <pre>
   (a(?i)b)c
 </pre>
@@ -2093,9 +2147,9 @@
 </P>
 <P>
 Another way of avoiding the ambiguity inherent in the use of digits following a
-backslash is to use the \g escape sequence. This escape must be followed by an
-unsigned number or a negative number, optionally enclosed in braces. These
-examples are all identical:
+backslash is to use the \g escape sequence. This escape must be followed by a
+signed or unsigned number, optionally enclosed in braces. These examples are
+all identical:
 <pre>
   (ring), \1
   (ring), \g1
@@ -2103,8 +2157,7 @@
 </pre>
 An unsigned number specifies an absolute reference without the ambiguity that
 is present in the older syntax. It is also useful when literal digits follow
-the reference. A negative number is a relative reference. Consider this
-example:
+the reference. A signed number is a relative reference. Consider this example:
 <pre>
   (abc(def)ghi)\g{-1}
 </pre>
@@ -2115,6 +2168,11 @@
 joining together fragments that contain references within themselves.
 </P>
 <P>
+The sequence \g{+1} is a reference to the next capturing subpattern. This kind
+of forward reference can be useful it patterns that repeat. Perl does not
+support the use of + in this way.
+</P>
+<P>
 A back reference matches whatever actually matched the capturing subpattern in
 the current subject string, rather than anything matching the subpattern
 itself (see
@@ -2203,15 +2261,27 @@
 <P>
 More complicated assertions are coded as subpatterns. There are two kinds:
 those that look ahead of the current position in the subject string, and those
-that look behind it. An assertion subpattern is matched in the normal way,
-except that it does not cause the current matching position to be changed.
+that look behind it, and in each case an assertion may be positive (must
+succeed for matching to continue) or negative (must not succeed for matching to
+continue). An assertion subpattern is matched in the normal way, except that,
+when matching continues afterwards, the matching position in the subject string
+is as it was at the start of the assertion.
 </P>
 <P>
-Assertion subpatterns are not capturing subpatterns. If such an assertion
-contains capturing subpatterns within it, these are counted for the purposes of
+Assertion subpatterns are not capturing subpatterns. If an assertion contains
+capturing subpatterns within it, these are counted for the purposes of
 numbering the capturing subpatterns in the whole pattern. However, substring
-capturing is carried out only for positive assertions. (Perl sometimes, but not
-always, does do capturing in negative assertions.)
+capturing is carried out only for positive assertions that succeed, that is,
+one of their branches matches, so matching continues after the assertion. If
+all branches of a positive assertion fail to match, nothing is captured, and
+control is passed to the previous backtracking point.
+</P>
+<P>
+No capturing is done for a negative assertion unless it is being used as a
+condition in a
+<a href="#subpatternsassubroutines">conditional subpattern</a>
+(see the discussion below). Matching continues after a non-conditional negative
+assertion only if all its branches fail to match.
 </P>
 <P>
 For compatibility with Perl, most assertion subpatterns may be repeated; though
@@ -2310,18 +2380,31 @@
 assertion fails.
 </P>
 <P>
-In a UTF mode, PCRE2 does not allow the \C escape (which matches a single code
-unit even in a UTF mode) to appear in lookbehind assertions, because it makes
-it impossible to calculate the length of the lookbehind. The \X and \R
-escapes, which can match different numbers of code units, are also not
-permitted.
+In UTF-8 and UTF-16 modes, PCRE2 does not allow the \C escape (which matches a
+single code unit even in a UTF mode) to appear in lookbehind assertions,
+because it makes it impossible to calculate the length of the lookbehind. The
+\X and \R escapes, which can match different numbers of code units, are never
+permitted in lookbehinds.
 </P>
 <P>
 <a href="#subpatternsassubroutines">"Subroutine"</a>
 calls (see below) such as (?2) or (?&X) are permitted in lookbehinds, as long
-as the subpattern matches a fixed-length string.
-<a href="#recursion">Recursion,</a>
-however, is not supported.
+as the subpattern matches a fixed-length string. However,
+<a href="#recursion">recursion,</a>
+that is, a "subroutine" call into a group that is already active,
+is not supported.
+</P>
+<P>
+Perl does not support back references in lookbehinds. PCRE2 does support them,
+but only if certain conditions are met. The PCRE2_MATCH_UNSET_BACKREF option
+must not be set, there must be no use of (?| in the pattern (it creates
+duplicate subpattern numbers), and if the back reference is by name, the name
+must be unique. Of course, the referenced subpattern must itself be of fixed
+length. The following pattern matches words containing at least two characters
+that begin and end with the same character:
+<pre>
+   \b(\w)\w++(?&#60;=\1)
+</PRE>
 </P>
 <P>
 Possessive quantifiers can be used in conjunction with lookbehind assertions to
@@ -2459,7 +2542,9 @@
 <P>
 Perl uses the syntax (?(&#60;name&#62;)...) or (?('name')...) to test for a used
 subpattern by name. For compatibility with earlier versions of PCRE1, which had
-this facility before Perl, the syntax (?(name)...) is also recognized.
+this facility before Perl, the syntax (?(name)...) is also recognized. Note,
+however, that undelimited names consisting of the letter R followed by digits
+are ambiguous (see the following section).
 </P>
 <P>
 Rewriting the above example to use a named subpattern gives this:
@@ -2474,30 +2559,52 @@
 Checking for pattern recursion
 </b><br>
 <P>
-If the condition is the string (R), and there is no subpattern with the name R,
-the condition is true if a recursive call to the whole pattern or any
-subpattern has been made. If digits or a name preceded by ampersand follow the
-letter R, for example:
+"Recursion" in this sense refers to any subroutine-like call from one part of
+the pattern to another, whether or not it is actually recursive. See the
+sections entitled
+<a href="#recursion">"Recursive patterns"</a>
+and
+<a href="#subpatternsassubroutines">"Subpatterns as subroutines"</a>
+below for details of recursion and subpattern calls.
+</P>
+<P>
+If a condition is the string (R), and there is no subpattern with the name R,
+the condition is true if matching is currently in a recursion or subroutine
+call to the whole pattern or any subpattern. If digits follow the letter R, and
+there is no subpattern with that name, the condition is true if the most recent
+call is into a subpattern with the given number, which must exist somewhere in
+the overall pattern. This is a contrived example that is equivalent to a+b:
 <pre>
-  (?(R3)...) or (?(R&name)...)
+  ((?(R1)a+|(?1)b))
 </pre>
-the condition is true if the most recent recursion is into a subpattern whose
-number or name is given. This condition does not check the entire recursion
-stack. If the name used in a condition of this kind is a duplicate, the test is
-applied to all subpatterns of the same name, and is true if any one of them is
-the most recent recursion.
+However, in both cases, if there is a subpattern with a matching name, the
+condition tests for its being set, as described in the section above, instead
+of testing for recursion. For example, creating a group with the name R1 by
+adding (?&#60;R1&#62;) to the above pattern completely changes its meaning.
+</P>
+<P>
+If a name preceded by ampersand follows the letter R, for example:
+<pre>
+  (?(R&name)...)
+</pre>
+the condition is true if the most recent recursion is into a subpattern of that
+name (which must exist within the pattern).
+</P>
+<P>
+This condition does not check the entire recursion stack. It tests only the
+current level. If the name used in a condition of this kind is a duplicate, the
+test is applied to all subpatterns of the same name, and is true if any one of
+them is the most recent recursion.
 </P>
 <P>
 At "top level", all these recursion test conditions are false.
-<a href="#recursion">The syntax for recursive patterns</a>
-is described below.
 <a name="subdefine"></a></P>
 <br><b>
 Defining subpatterns for use by reference only
 </b><br>
 <P>
-If the condition is the string (DEFINE), and there is no subpattern with the
-name DEFINE, the condition is always false. In this case, there may be only one
+If the condition is the string (DEFINE), the condition is always false, even if
+there is a group with the name DEFINE. In this case, there may be only one
 alternative in the subpattern. It is always skipped if control reaches this
 point in the pattern; the idea of DEFINE is that it can be used to define
 subroutines that can be referenced from elsewhere. (The use of
@@ -2552,6 +2659,13 @@
 subject is matched against the first alternative; otherwise it is matched
 against the second. This pattern matches strings in one of the two forms
 dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.
+</P>
+<P>
+When an assertion that is a condition contains capturing subpatterns, any
+capturing that occurs in a matching branch is retained afterwards, for both
+positive and negative assertions, because matching always continues after the
+assertion, whether it succeeds or fails. (Compare non-conditional assertions,
+when captures are retained only for positive assertions that succeed.)
 <a name="comments"></a></P>
 <br><a name="SEC22" href="#TOC1">COMMENTS</a><br>
 <P>
@@ -2724,93 +2838,57 @@
 Differences in recursion processing between PCRE2 and Perl
 </b><br>
 <P>
-Recursion processing in PCRE2 differs from Perl in two important ways. In PCRE2
-(like Python, but unlike Perl), a recursive subpattern call is always treated
-as an atomic group. That is, once it has matched some of the subject string, it
-is never re-entered, even if it contains untried alternatives and there is a
-subsequent matching failure. This can be illustrated by the following pattern,
-which purports to match a palindromic string that contains an odd number of
-characters (for example, "a", "aba", "abcba", "abcdcba"):
-<pre>
-  ^(.|(.)(?1)\2)$
-</pre>
-The idea is that it either matches a single character, or two identical
-characters surrounding a sub-palindrome. In Perl, this pattern works; in PCRE2
-it does not if the pattern is longer than three characters. Consider the
-subject string "abcba":
+Some former differences between PCRE2 and Perl no longer exist.
 </P>
 <P>
-At the top level, the first character is matched, but as it is not at the end
-of the string, the first alternative fails; the second alternative is taken
-and the recursion kicks in. The recursive call to subpattern 1 successfully
-matches the next character ("b"). (Note that the beginning and end of line
-tests are not part of the recursion).
+Before release 10.30, recursion processing in PCRE2 differed from Perl in that
+a recursive subpattern call was always treated as an atomic group. That is,
+once it had matched some of the subject string, it was never re-entered, even
+if it contained untried alternatives and there was a subsequent matching
+failure. (Historical note: PCRE implemented recursion before Perl did.)
 </P>
 <P>
-Back at the top level, the next character ("c") is compared with what
-subpattern 2 matched, which was "a". This fails. Because the recursion is
-treated as an atomic group, there are now no backtracking points, and so the
-entire match fails. (Perl is able, at this point, to re-enter the recursion and
-try the second alternative.) However, if the pattern is written with the
-alternatives in the other order, things are different:
-<pre>
-  ^((.)(?1)\2|.)$
-</pre>
-This time, the recursing alternative is tried first, and continues to recurse
-until it runs out of characters, at which point the recursion fails. But this
-time we do have another alternative to try at the higher level. That is the big
-difference: in the previous case the remaining alternative is at a deeper
-recursion level, which PCRE2 cannot use.
+Starting with release 10.30, recursive subroutine calls are no longer treated
+as atomic. That is, they can be re-entered to try unused alternatives if there
+is a matching failure later in the pattern. This is now compatible with the way
+Perl works. If you want a subroutine call to be atomic, you must explicitly
+enclose it in an atomic group.
 </P>
 <P>
-To change the pattern so that it matches all palindromic strings, not just
-those with an odd number of characters, it is tempting to change the pattern to
-this:
+Supporting backtracking into recursions simplifies certain types of recursive
+pattern. For example, this pattern matches palindromic strings:
 <pre>
   ^((.)(?1)\2|.?)$
 </pre>
-Again, this works in Perl, but not in PCRE2, and for the same reason. When a
-deeper recursion has matched a single character, it cannot be entered again in
-order to match an empty string. The solution is to separate the two cases, and
-write out the odd and even cases as alternatives at the higher level:
+The second branch in the group matches a single central character in the
+palindrome when there are an odd number of characters, or nothing when there
+are an even number of characters, but in order to work it has to be able to try
+the second case when the rest of the pattern match fails. If you want to match
+typical palindromic phrases, the pattern has to ignore all non-word characters,
+which can be done like this:
 <pre>
-  ^(?:((.)(?1)\2|)|((.)(?3)\4|.))
-</pre>
-If you want to match typical palindromic phrases, the pattern has to ignore all
-non-word characters, which can be done like this:
-<pre>
-  ^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$
+  ^\W*+((.)\W*+(?1)\W*+\2|\W*+.?)\W*+$
 </pre>
 If run with the PCRE2_CASELESS option, this pattern matches phrases such as "A
-man, a plan, a canal: Panama!" and it works in both PCRE2 and Perl. Note the
-use of the possessive quantifier *+ to avoid backtracking into sequences of
-non-word characters. Without this, PCRE2 takes a great deal longer (ten times
-or more) to match typical phrases, and Perl takes so long that you think it has
-gone into a loop.
+man, a plan, a canal: Panama!". Note the use of the possessive quantifier *+ to
+avoid backtracking into sequences of non-word characters. Without this, PCRE2
+takes a great deal longer (ten times or more) to match typical phrases, and
+Perl takes so long that you think it has gone into a loop.
 </P>
 <P>
-<b>WARNING</b>: The palindrome-matching patterns above work only if the subject
-string does not start with a palindrome that is shorter than the entire string.
-For example, although "abcba" is correctly matched, if the subject is "ababa",
-PCRE2 finds the palindrome "aba" at the start, then fails at top level because
-the end of the string does not follow. Once again, it cannot jump back into the
-recursion to try other alternatives, so the entire match fails.
-</P>
-<P>
-The second way in which PCRE2 and Perl differ in their recursion processing is
-in the handling of captured values. In Perl, when a subpattern is called
-recursively or as a subpattern (see the next section), it has no access to any
-values that were captured outside the recursion, whereas in PCRE2 these values
-can be referenced. Consider this pattern:
+Another way in which PCRE2 and Perl used to differ in their recursion
+processing is in the handling of captured values. Formerly in Perl, when a
+subpattern was called recursively or as a subpattern (see the next section), it
+had no access to any values that were captured outside the recursion, whereas
+in PCRE2 these values can be referenced. Consider this pattern:
 <pre>
   ^(.)(\1|a(?2))
 </pre>
-In PCRE2, this pattern matches "bab". The first capturing parentheses match "b",
-then in the second group, when the back reference \1 fails to match "b", the
-second alternative matches "a" and then recurses. In the recursion, \1 does
-now match "b" and so the whole match succeeds. In Perl, the pattern fails to
-match because inside the recursive call \1 cannot access the externally set
-value.
+This pattern matches "bab". The first capturing parentheses match "b", then in
+the second group, when the back reference \1 fails to match "b", the second
+alternative matches "a" and then recurses. In the recursion, \1 does now match
+"b" and so the whole match succeeds. This match used to fail in Perl, but in
+later versions (I tried 5.024) it now works.
 <a name="subpatternsassubroutines"></a></P>
 <br><a name="SEC24" href="#TOC1">SUBPATTERNS AS SUBROUTINES</a><br>
 <P>
@@ -2837,11 +2915,10 @@
 strings. Another example is given in the discussion of DEFINE above.
 </P>
 <P>
-All subroutine calls, whether recursive or not, are always treated as atomic
-groups. That is, once a subroutine has matched some of the subject string, it
-is never re-entered, even if it contains untried alternatives and there is a
-subsequent matching failure. Any capturing parentheses that are set during the
-subroutine call revert to their previous values afterwards.
+Like recursions, subroutine calls used to be treated as atomic, but this
+changed at PCRE2 release 10.30, so backtracking into subroutine calls can now
+occur. However, any capturing parentheses that are set during the subroutine
+call revert to their previous values afterwards.
 </P>
 <P>
 Processing options such as case-independence are fixed when a subpattern is
@@ -2949,28 +3026,31 @@
 <a name="backtrackcontrol"></a></P>
 <br><a name="SEC27" href="#TOC1">BACKTRACKING CONTROL</a><br>
 <P>
-Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which
-are still described in the Perl documentation as "experimental and subject to
-change or removal in a future version of Perl". It goes on to say: "Their usage
-in production code should be noted to avoid problems during upgrades." The same
-remarks apply to the PCRE2 features described in this section.
-</P>
-<P>
-The new verbs make use of what was previously invalid syntax: an opening
-parenthesis followed by an asterisk. They are generally of the form (*VERB) or
-(*VERB:NAME). Some verbs take either form, possibly behaving differently
-depending on whether or not a name is present.
+There are a number of special "Backtracking Control Verbs" (to use Perl's
+terminology) that modify the behaviour of backtracking during matching. They
+are generally of the form (*VERB) or (*VERB:NAME). Some verbs take either form,
+possibly behaving differently depending on whether or not a name is present.
 </P>
 <P>
 By default, for compatibility with Perl, a name is any sequence of characters
 that does not include a closing parenthesis. The name is not processed in
 any way, and it is not possible to include a closing parenthesis in the name.
-However, if the PCRE2_ALT_VERBNAMES option is set, normal backslash processing
-is applied to verb names and only an unescaped closing parenthesis terminates
-the name. A closing parenthesis can be included in a name either as \) or
-between \Q and \E. If the PCRE2_EXTENDED option is set, unescaped whitespace
-in verb names is skipped and #-comments are recognized, exactly as in the rest
-of the pattern.
+This can be changed by setting the PCRE2_ALT_VERBNAMES option, but the result
+is no longer Perl-compatible.
+</P>
+<P>
+When PCRE2_ALT_VERBNAMES is set, backslash processing is applied to verb names
+and only an unescaped closing parenthesis terminates the name. However, the
+only backslash items that are permitted are \Q, \E, and sequences such as
+\x{100} that define character code points. Character type escapes such as \d
+are faulted.
+</P>
+<P>
+A closing parenthesis can be included in a name either as \) or between \Q
+and \E. In addition to backslash processing, if the PCRE2_EXTENDED option is
+also set, unescaped whitespace in verb names is skipped, and #-comments are
+recognized, exactly as in the rest of the pattern. PCRE2_EXTENDED does not
+affect verb names unless PCRE2_ALT_VERBNAMES is also set.
 </P>
 <P>
 The maximum length of a name is 255 in the 8-bit library and 65535 in the
@@ -2981,7 +3061,7 @@
 <P>
 Since these verbs are specifically related to backtracking, most of them can be
 used only when the pattern is to be matched using the traditional matching
-function, because these use a backtracking algorithm. With the exception of
+function, because that uses a backtracking algorithm. With the exception of
 (*FAIL), which behaves like a failing negative assertion, the backtracking
 control verbs cause an error if encountered by the DFA matching function.
 </P>
@@ -3119,11 +3199,11 @@
 The following verbs do nothing when they are encountered. Matching continues
 with what follows, but if there is no subsequent match, causing a backtrack to
 the verb, a failure is forced. That is, backtracking cannot pass to the left of
-the verb. However, when one of these verbs appears inside an atomic group
-(which includes any group that is called as a subroutine) or in an assertion
-that is true, its effect is confined to that group, because once the group has
-been matched, there is never any backtracking into it. In this situation,
-backtracking has to jump to the left of the entire atomic group or assertion.
+the verb. However, when one of these verbs appears inside an atomic group or in
+an assertion that is true, its effect is confined to that group, because once
+the group has been matched, there is never any backtracking into it. In this
+situation, backtracking has to jump to the left of the entire atomic group or
+assertion.
 </P>
 <P>
 These verbs differ in exactly what kind of failure occurs when backtracking
@@ -3187,8 +3267,8 @@
 as (*COMMIT).
 </P>
 <P>
-The behaviour of (*PRUNE:NAME) is the not the same as (*MARK:NAME)(*PRUNE).
-It is like (*MARK:NAME) in that the name is remembered for passing back to the
+The behaviour of (*PRUNE:NAME) is not the same as (*MARK:NAME)(*PRUNE). It is
+like (*MARK:NAME) in that the name is remembered for passing back to the
 caller. However, (*SKIP:NAME) searches only for names set with (*MARK),
 ignoring those set by (*PRUNE) or (*THEN).
 <pre>
@@ -3329,28 +3409,34 @@
 Backtracking verbs in assertions
 </b><br>
 <P>
-(*FAIL) in an assertion has its normal effect: it forces an immediate
-backtrack.
+(*FAIL) in any assertion has its normal effect: it forces an immediate
+backtrack. The behaviour of the other backtracking verbs depends on whether or
+not the assertion is standalone or acting as the condition in a conditional
+subpattern.
 </P>
 <P>
-(*ACCEPT) in a positive assertion causes the assertion to succeed without any
-further processing. In a negative assertion, (*ACCEPT) causes the assertion to
-fail without any further processing.
+(*ACCEPT) in a standalone positive assertion causes the assertion to succeed
+without any further processing; captured strings are retained. In a standalone
+negative assertion, (*ACCEPT) causes the assertion to fail without any further
+processing; captured substrings are discarded.
+</P>
+<P>
+If the assertion is a condition, (*ACCEPT) causes the condition to be true for
+a positive assertion and false for a negative one; captured substrings are
+retained in both cases.
+</P>
+<P>
+The effect of (*THEN) is not allowed to escape beyond an assertion. If there
+are no more branches to try, (*THEN) causes a positive assertion to be false,
+and a negative assertion to be true.
 </P>
 <P>
 The other backtracking verbs are not treated specially if they appear in a
-positive assertion. In particular, (*THEN) skips to the next alternative in the
-innermost enclosing group that has alternations, whether or not this is within
-the assertion.
-</P>
-<P>
-Negative assertions are, however, different, in order to ensure that changing a
-positive assertion into a negative assertion changes its result. Backtracking
-into (*COMMIT), (*SKIP), or (*PRUNE) causes a negative assertion to be true,
-without considering any further alternative branches in the assertion.
-Backtracking into (*THEN) causes it to skip to the next enclosing alternative
-within the assertion (the normal behaviour), but if the assertion does not have
-such an alternative, (*THEN) behaves like (*PRUNE).
+standalone positive assertion. In a conditional positive assertion,
+backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes the condition to be
+false. However, for both standalone and conditional negative assertions,
+backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes the assertion to be
+true, without considering any further alternative branches.
 <a name="btsub"></a></P>
 <br><b>
 Backtracking verbs in subroutines
@@ -3393,9 +3479,9 @@
 </P>
 <br><a name="SEC30" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 20 June 2016
+Last updated: 12 September 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2perform.html b/dist2/doc/html/pcre2perform.html
index ac9d23c..28f4f73 100644
--- a/dist2/doc/html/pcre2perform.html
+++ b/dist2/doc/html/pcre2perform.html
@@ -15,7 +15,7 @@
 <ul>
 <li><a name="TOC1" href="#SEC1">PCRE2 PERFORMANCE</a>
 <li><a name="TOC2" href="#SEC2">COMPILED PATTERN MEMORY USAGE</a>
-<li><a name="TOC3" href="#SEC3">STACK USAGE AT RUN TIME</a>
+<li><a name="TOC3" href="#SEC3">STACK AND HEAP USAGE AT RUN TIME</a>
 <li><a name="TOC4" href="#SEC4">PROCESSING TIME</a>
 <li><a name="TOC5" href="#SEC5">AUTHOR</a>
 <li><a name="TOC6" href="#SEC6">REVISION</a>
@@ -29,11 +29,11 @@
 <br><a name="SEC2" href="#TOC1">COMPILED PATTERN MEMORY USAGE</a><br>
 <P>
 Patterns are compiled by PCRE2 into a reasonably efficient interpretive code,
-so that most simple patterns do not use much memory. However, there is one case
-where the memory usage of a compiled pattern can be unexpectedly large. If a
-parenthesized subpattern has a quantifier with a minimum greater than 1 and/or
-a limited maximum, the whole subpattern is repeated in the compiled code. For
-example, the pattern
+so that most simple patterns do not use much memory for storing the compiled
+version. However, there is one case where the memory usage of a compiled
+pattern can be unexpectedly large. If a parenthesized subpattern has a
+quantifier with a minimum greater than 1 and/or a limited maximum, the whole
+subpattern is repeated in the compiled code. For example, the pattern
 <pre>
   (abc|def){2,4}
 </pre>
@@ -52,13 +52,13 @@
 <pre>
   ((ab){1,1000}c){1,3}
 </pre>
-uses 51K bytes when compiled using the 8-bit library. When PCRE2 is compiled
-with its default internal pointer size of two bytes, the size limit on a
-compiled pattern is 64K code units in the 8-bit and 16-bit libraries, and this
-is reached with the above pattern if the outer repetition is increased from 3
-to 4. PCRE2 can be compiled to use larger internal pointers and thus handle
-larger compiled patterns, but it is better to try to rewrite your pattern to
-use less memory if you can.
+uses over 50K bytes when compiled using the 8-bit library. When PCRE2 is
+compiled with its default internal pointer size of two bytes, the size limit on
+a compiled pattern is 64K code units in the 8-bit and 16-bit libraries, and
+this is reached with the above pattern if the outer repetition is increased
+from 3 to 4. PCRE2 can be compiled to use larger internal pointers and thus
+handle larger compiled patterns, but it is better to try to rewrite your
+pattern to use less memory if you can.
 </P>
 <P>
 One way of reducing the memory usage for such patterns is to make use of
@@ -68,25 +68,34 @@
 <pre>
   ((ab)(?2){0,999}c)(?1){0,2}
 </pre>
-reduces the memory requirements to 18K, and indeed it remains under 20K even
-with the outer repetition increased to 100. However, this pattern is not
-exactly equivalent, because the "subroutine" calls are treated as
-<a href="pcre2pattern.html#atomicgroup">atomic groups</a>
-into which there can be no backtracking if there is a subsequent matching
-failure. Therefore, PCRE2 cannot do this kind of rewriting automatically.
-Furthermore, there is a noticeable loss of speed when executing the modified
-pattern. Nevertheless, if the atomic grouping is not a problem and the loss of
-speed is acceptable, this kind of rewriting will allow you to process patterns
-that PCRE2 cannot otherwise handle.
+reduces the memory requirements to around 16K, and indeed it remains under 20K
+even with the outer repetition increased to 100. However, this kind of pattern
+is not always exactly equivalent, because any captures within subroutine calls
+are lost when the subroutine completes. If this is not a problem, this kind of
+rewriting will allow you to process patterns that PCRE2 cannot otherwise
+handle. The matching performance of the two different versions of the pattern
+are roughly the same. (This applies from release 10.30 - things were different
+in earlier releases.)
 </P>
-<br><a name="SEC3" href="#TOC1">STACK USAGE AT RUN TIME</a><br>
+<br><a name="SEC3" href="#TOC1">STACK AND HEAP USAGE AT RUN TIME</a><br>
 <P>
-When <b>pcre2_match()</b> is used for matching, certain kinds of pattern can
-cause it to use large amounts of the process stack. In some environments the
-default process stack is quite small, and if it runs out the result is often
-SIGSEGV. Rewriting your pattern can often help. The
-<a href="pcre2stack.html"><b>pcre2stack</b></a>
-documentation discusses this issue in detail.
+From release 10.30, the interpretive (non-JIT) version of <b>pcre2_match()</b>
+uses very little system stack at run time. In earlier releases recursive
+function calls could use a great deal of stack, and this could cause problems,
+but this usage has been eliminated. Backtracking positions are now explicitly
+remembered in memory frames controlled by the code. An initial 20K vector of
+frames is allocated on the system stack (enough for about 100 frames for small
+patterns), but if this is insufficient, heap memory is used. The amount of heap
+memory can be limited; if the limit is set to zero, only the initial stack
+vector is used. Rewriting patterns to be time-efficient, as described below,
+may also reduce the memory requirements.
+</P>
+<P>
+In contrast to <b>pcre2_match()</b>, <b>pcre2_dfa_match()</b> does use recursive
+function calls, but only for processing atomic groups, lookaround assertions,
+and recursion within the pattern. Too much nested recursion may cause stack
+issues. The "match depth" parameter can be used to limit the depth of function
+recursion in <b>pcre2_dfa_match()</b>.
 </P>
 <br><a name="SEC4" href="#TOC1">PROCESSING TIME</a><br>
 <P>
@@ -175,7 +184,54 @@
 </P>
 <P>
 In many cases, the solution to this kind of performance issue is to use an
-atomic group or a possessive quantifier.
+atomic group or a possessive quantifier. This can often reduce memory
+requirements as well. As another example, consider this pattern:
+<pre>
+  ([^&#60;]|&#60;(?!inet))+
+</pre>
+It matches from wherever it starts until it encounters "&#60;inet" or the end of
+the data, and is the kind of pattern that might be used when processing an XML
+file. Each iteration of the outer parentheses matches either one character that
+is not "&#60;" or a "&#60;" that is not followed by "inet". However, each time a
+parenthesis is processed, a backtracking position is passed, so this
+formulation uses a memory frame for each matched character. For a long string,
+a lot of memory is required. Consider now this rewritten pattern, which matches
+exactly the same strings:
+<pre>
+  ([^&#60;]++|&#60;(?!inet))+
+</pre>
+This runs much faster, because sequences of characters that do not contain "&#60;"
+are "swallowed" in one item inside the parentheses, and a possessive quantifier
+is used to stop any backtracking into the runs of non-"&#60;" characters. This
+version also uses a lot less memory because entry to a new set of parentheses
+happens only when a "&#60;" character that is not followed by "inet" is encountered
+(and we assume this is relatively rare).
+</P>
+<P>
+This example shows that one way of optimizing performance when matching long
+subject strings is to write repeated parenthesized subpatterns to match more
+than one character whenever possible.
+</P>
+<br><b>
+SETTING RESOURCE LIMITS
+</b><br>
+<P>
+You can set limits on the amount of processing that takes place when matching,
+and on the amount of heap memory that is used. The default values of the limits
+are very large, and unlikely ever to operate. They can be changed when PCRE2 is
+built, and they can also be set when <b>pcre2_match()</b> or
+<b>pcre2_dfa_match()</b> is called. For details of these interfaces, see the
+<a href="pcre2build.html"><b>pcre2build</b></a>
+documentation and the section entitled
+<a href="pcre2api.html#matchcontext">"The match context"</a>
+in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+documentation.
+</P>
+<P>
+The <b>pcre2test</b> test program has a modifier called "find_limits" which, if
+applied to a subject line, causes it to find the smallest limits that allow a
+pattern to match. This is done by repeatedly matching with different limits.
 </P>
 <br><a name="SEC5" href="#TOC1">AUTHOR</a><br>
 <P>
@@ -188,9 +244,9 @@
 </P>
 <br><a name="SEC6" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 02 January 2015
+Last updated: 08 April 2017
 <br>
-Copyright &copy; 1997-2015 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2posix.html b/dist2/doc/html/pcre2posix.html
index 1d5fe63..8a4431c 100644
--- a/dist2/doc/html/pcre2posix.html
+++ b/dist2/doc/html/pcre2posix.html
@@ -69,7 +69,7 @@
 <P>
 There are also some options that are not defined by POSIX. These have been
 added at the request of users who want to make use of certain PCRE2-specific
-features via the POSIX calling interface.
+features via the POSIX calling interface or to add BSD or GNU functionality.
 </P>
 <P>
 When PCRE2 is called via these functions, it is only the API that is POSIX-like
@@ -91,10 +91,11 @@
 <br><a name="SEC3" href="#TOC1">COMPILING A PATTERN</a><br>
 <P>
 The function <b>regcomp()</b> is called to compile a pattern into an
-internal form. The pattern is a C string terminated by a binary zero, and
-is passed in the argument <i>pattern</i>. The <i>preg</i> argument is a pointer
-to a <b>regex_t</b> structure that is used as a base for storing information
-about the compiled regular expression.
+internal form. By default, the pattern is a C string terminated by a binary
+zero (but see REG_PEND below). The <i>preg</i> argument is a pointer to a
+<b>regex_t</b> structure that is used as a base for storing information about
+the compiled regular expression. (It is also used for input when REG_PEND is
+set.)
 </P>
 <P>
 The argument <i>cflags</i> is either zero, or contains one or more of the bits
@@ -117,6 +118,14 @@
 compilation to the native function. Note that this does <i>not</i> mimic the
 defined POSIX behaviour for REG_NEWLINE (see the following section).
 <pre>
+  REG_NOSPEC
+</pre>
+The PCRE2_LITERAL option is set when the regular expression is passed for
+compilation to the native function. This disables all meta characters in the
+pattern, causing it to be treated as a literal string. The only other options
+that are allowed with REG_NOSPEC are REG_ICASE, REG_NOSUB, REG_PEND, and
+REG_UTF. Note that REG_NOSPEC is not part of the POSIX standard.
+<pre>
   REG_NOSUB
 </pre>
 When a pattern that is compiled with this flag is passed to <b>regexec()</b> for
@@ -125,6 +134,16 @@
 to set the PCRE2_NO_AUTO_CAPTURE compile option, but this no longer happens
 because it disables the use of back references.
 <pre>
+  REG_PEND
+</pre>
+If this option is set, the <b>reg_endp</b> field in the <i>preg</i> structure
+(which has the type const char *) must be set to point to the character beyond
+the end of the pattern before calling <b>regcomp()</b>. The pattern itself may
+now contain binary zeroes, which are treated as data characters. Without
+REG_PEND, a binary zero terminates the pattern and the <b>re_endp</b> field is
+ignored. This is a GNU extension to the POSIX standard and should be used with
+caution in software intended to be portable to other systems.
+<pre>
   REG_UCP
 </pre>
 The PCRE2_UCP option is set when the regular expression is passed for
@@ -156,9 +175,10 @@
 </P>
 <P>
 The yield of <b>regcomp()</b> is zero on success, and non-zero otherwise. The
-<i>preg</i> structure is filled in on success, and one member of the structure
-is public: <i>re_nsub</i> contains the number of capturing subpatterns in
-the regular expression. Various error codes are defined in the header file.
+<i>preg</i> structure is filled in on success, and one other member of the
+structure (as well as <i>re_endp</i>) is public: <i>re_nsub</i> contains the
+number of capturing subpatterns in the regular expression. Various error codes
+are defined in the header file.
 </P>
 <P>
 NOTE: If the yield of <b>regcomp()</b> is non-zero, you must not attempt to
@@ -228,15 +248,26 @@
 <pre>
   REG_STARTEND
 </pre>
-The string is considered to start at <i>string</i> + <i>pmatch[0].rm_so</i> and
-to have a terminating NUL located at <i>string</i> + <i>pmatch[0].rm_eo</i>
-(there need not actually be a NUL at that location), regardless of the value of
-<i>nmatch</i>. This is a BSD extension, compatible with but not specified by
-IEEE Standard 1003.2 (POSIX.2), and should be used with caution in software
-intended to be portable to other systems. Note that a non-zero <i>rm_so</i> does
-not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not
-how it is matched. Setting REG_STARTEND and passing <i>pmatch</i> as NULL are
-mutually exclusive; the error REG_INVARG is returned.
+When this option is set, the subject string is starts at <i>string</i> +
+<i>pmatch[0].rm_so</i> and ends at <i>string</i> + <i>pmatch[0].rm_eo</i>, which
+should point to the first character beyond the string. There may be binary
+zeroes within the subject string, and indeed, using REG_STARTEND is the only
+way to pass a subject string that contains a binary zero.
+</P>
+<P>
+Whatever the value of <i>pmatch[0].rm_so</i>, the offsets of the matched string
+and any captured substrings are still given relative to the start of
+<i>string</i> itself. (Before PCRE2 release 10.30 these were given relative to
+<i>string</i> + <i>pmatch[0].rm_so</i>, but this differs from other
+implementations.)
+</P>
+<P>
+This is a BSD extension, compatible with but not specified by IEEE Standard
+1003.2 (POSIX.2), and should be used with caution in software intended to be
+portable to other systems. Note that a non-zero <i>rm_so</i> does not imply
+REG_NOTBOL; REG_STARTEND affects only the location and length of the string,
+not how it is matched. Setting REG_STARTEND and passing <i>pmatch</i> as NULL
+are mutually exclusive; the error REG_INVARG is returned.
 </P>
 <P>
 If the pattern was compiled with the REG_NOSUB flag, no data about any matched
@@ -291,9 +322,9 @@
 </P>
 <br><a name="SEC9" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 31 January 2016
+Last updated: 15 June 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2serialize.html b/dist2/doc/html/pcre2serialize.html
index edf415a..813b25a 100644
--- a/dist2/doc/html/pcre2serialize.html
+++ b/dist2/doc/html/pcre2serialize.html
@@ -55,7 +55,10 @@
 within individual applications. As such, the data supplied to
 <b>pcre2_serialize_decode()</b> is expected to be trusted data, not data from
 arbitrary external sources. There is only some simple consistency checking, not
-complete validation of what is being re-loaded.
+complete validation of what is being re-loaded. Corrupted data may cause
+undefined results. For example, if the length field of a pattern in the
+serialized data is corrupted, the deserializing code may read beyond the end of
+the byte stream that is passed to it.
 </P>
 <br><a name="SEC3" href="#TOC1">SAVING COMPILED PATTERNS</a><br>
 <P>
@@ -190,9 +193,9 @@
 </P>
 <br><a name="SEC6" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 24 May 2016
+Last updated: 21 March 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2stack.html b/dist2/doc/html/pcre2stack.html
deleted file mode 100644
index 2942c7a..0000000
--- a/dist2/doc/html/pcre2stack.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<html>
-<head>
-<title>pcre2stack specification</title>
-</head>
-<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
-<h1>pcre2stack man page</h1>
-<p>
-Return to the <a href="index.html">PCRE2 index page</a>.
-</p>
-<p>
-This page is part of the PCRE2 HTML documentation. It was generated
-automatically from the original man page. If there is any nonsense in it,
-please consult the man page, in case the conversion went wrong.
-<br>
-<br><b>
-PCRE2 DISCUSSION OF STACK USAGE
-</b><br>
-<P>
-When you call <b>pcre2_match()</b>, it makes use of an internal function called
-<b>match()</b>. This calls itself recursively at branch points in the pattern,
-in order to remember the state of the match so that it can back up and try a
-different alternative after a failure. As matching proceeds deeper and deeper
-into the tree of possibilities, the recursion depth increases. The
-<b>match()</b> function is also called in other circumstances, for example,
-whenever a parenthesized sub-pattern is entered, and in certain cases of
-repetition.
-</P>
-<P>
-Not all calls of <b>match()</b> increase the recursion depth; for an item such
-as a* it may be called several times at the same level, after matching
-different numbers of a's. Furthermore, in a number of cases where the result of
-the recursive call would immediately be passed back as the result of the
-current call (a "tail recursion"), the function is just restarted instead.
-</P>
-<P>
-Each time the internal <b>match()</b> function is called recursively, it uses
-memory from the process stack. For certain kinds of pattern and data, very
-large amounts of stack may be needed, despite the recognition of "tail
-recursion". Note that if PCRE2 is compiled with the -fsanitize=address option
-of the GCC compiler, the stack requirements are greatly increased.
-</P>
-<P>
-The above comments apply when <b>pcre2_match()</b> is run in its normal
-interpretive manner. If the compiled pattern was processed by
-<b>pcre2_jit_compile()</b>, and just-in-time compiling was successful, and the
-options passed to <b>pcre2_match()</b> were not incompatible, the matching
-process uses the JIT-compiled code instead of the <b>match()</b> function. In
-this case, the memory requirements are handled entirely differently. See the
-<a href="pcre2jit.html"><b>pcre2jit</b></a>
-documentation for details.
-</P>
-<P>
-The <b>pcre2_dfa_match()</b> function operates in a different way to
-<b>pcre2_match()</b>, and uses recursion only when there is a regular expression
-recursion or subroutine call in the pattern. This includes the processing of
-assertion and "once-only" subpatterns, which are handled like subroutine calls.
-Normally, these are never very deep, and the limit on the complexity of
-<b>pcre2_dfa_match()</b> is controlled by the amount of workspace it is given.
-However, it is possible to write patterns with runaway infinite recursions;
-such patterns will cause <b>pcre2_dfa_match()</b> to run out of stack. At
-present, there is no protection against this.
-</P>
-<P>
-The comments that follow do NOT apply to <b>pcre2_dfa_match()</b>; they are
-relevant only for <b>pcre2_match()</b> without the JIT optimization.
-</P>
-<br><b>
-Reducing <b>pcre2_match()</b>'s stack usage
-</b><br>
-<P>
-You can often reduce the amount of recursion, and therefore the
-amount of stack used, by modifying the pattern that is being matched. Consider,
-for example, this pattern:
-<pre>
-  ([^&#60;]|&#60;(?!inet))+
-</pre>
-It matches from wherever it starts until it encounters "&#60;inet" or the end of
-the data, and is the kind of pattern that might be used when processing an XML
-file. Each iteration of the outer parentheses matches either one character that
-is not "&#60;" or a "&#60;" that is not followed by "inet". However, each time a
-parenthesis is processed, a recursion occurs, so this formulation uses a stack
-frame for each matched character. For a long string, a lot of stack is
-required. Consider now this rewritten pattern, which matches exactly the same
-strings:
-<pre>
-  ([^&#60;]++|&#60;(?!inet))+
-</pre>
-This uses very much less stack, because runs of characters that do not contain
-"&#60;" are "swallowed" in one item inside the parentheses. Recursion happens only
-when a "&#60;" character that is not followed by "inet" is encountered (and we
-assume this is relatively rare). A possessive quantifier is used to stop any
-backtracking into the runs of non-"&#60;" characters, but that is not related to
-stack usage.
-</P>
-<P>
-This example shows that one way of avoiding stack problems when matching long
-subject strings is to write repeated parenthesized subpatterns to match more
-than one character whenever possible.
-</P>
-<br><b>
-Compiling PCRE2 to use heap instead of stack for <b>pcre2_match()</b>
-</b><br>
-<P>
-In environments where stack memory is constrained, you might want to compile
-PCRE2 to use heap memory instead of stack for remembering back-up points when
-<b>pcre2_match()</b> is running. This makes it run more slowly, however. Details
-of how to do this are given in the
-<a href="pcre2build.html"><b>pcre2build</b></a>
-documentation. When built in this way, instead of using the stack, PCRE2
-gets memory for remembering backup points from the heap. By default, the memory
-is obtained by calling the system <b>malloc()</b> function, but you can arrange
-to supply your own memory management function. For details, see the section
-entitled
-<a href="pcre2api.html#matchcontext">"The match context"</a>
-in the
-<a href="pcre2api.html"><b>pcre2api</b></a>
-documentation. Since the block sizes are always the same, it may be possible to
-implement customized a memory handler that is more efficient than the standard
-function. The memory blocks obtained for this purpose are retained and re-used
-if possible while <b>pcre2_match()</b> is running. They are all freed just
-before it exits.
-</P>
-<br><b>
-Limiting <b>pcre2_match()</b>'s stack usage
-</b><br>
-<P>
-You can set limits on the number of times the internal <b>match()</b> function
-is called, both in total and recursively. If a limit is exceeded,
-<b>pcre2_match()</b> returns an error code. Setting suitable limits should
-prevent it from running out of stack. The default values of the limits are very
-large, and unlikely ever to operate. They can be changed when PCRE2 is built,
-and they can also be set when <b>pcre2_match()</b> is called. For details of
-these interfaces, see the
-<a href="pcre2build.html"><b>pcre2build</b></a>
-documentation and the section entitled
-<a href="pcre2api.html#matchcontext">"The match context"</a>
-in the
-<a href="pcre2api.html"><b>pcre2api</b></a>
-documentation.
-</P>
-<P>
-As a very rough rule of thumb, you should reckon on about 500 bytes per
-recursion. Thus, if you want to limit your stack usage to 8Mb, you should set
-the limit at 16000 recursions. A 64Mb stack, on the other hand, can support
-around 128000 recursions.
-</P>
-<P>
-The <b>pcre2test</b> test program has a modifier called "find_limits" which, if
-applied to a subject line, causes it to find the smallest limits that allow a a
-pattern to match. This is done by calling <b>pcre2_match()</b> repeatedly with
-different limits.
-</P>
-<br><b>
-Changing stack size in Unix-like systems
-</b><br>
-<P>
-In Unix-like environments, there is not often a problem with the stack unless
-very long strings are involved, though the default limit on stack size varies
-from system to system. Values from 8Mb to 64Mb are common. You can find your
-default limit by running the command:
-<pre>
-  ulimit -s
-</pre>
-Unfortunately, the effect of running out of stack is often SIGSEGV, though
-sometimes a more explicit error message is given. You can normally increase the
-limit on stack size by code such as this:
-<pre>
-  struct rlimit rlim;
-  getrlimit(RLIMIT_STACK, &rlim);
-  rlim.rlim_cur = 100*1024*1024;
-  setrlimit(RLIMIT_STACK, &rlim);
-</pre>
-This reads the current limits (soft and hard) using <b>getrlimit()</b>, then
-attempts to increase the soft limit to 100Mb using <b>setrlimit()</b>. You must
-do this before calling <b>pcre2_match()</b>.
-</P>
-<br><b>
-Changing stack size in Mac OS X
-</b><br>
-<P>
-Using <b>setrlimit()</b>, as described above, should also work on Mac OS X. It
-is also possible to set a stack size when linking a program. There is a
-discussion about stack sizes in Mac OS X at this web site:
-<a href="http://developer.apple.com/qa/qa2005/qa1419.html">http://developer.apple.com/qa/qa2005/qa1419.html.</a>
-</P>
-<br><b>
-AUTHOR
-</b><br>
-<P>
-Philip Hazel
-<br>
-University Computing Service
-<br>
-Cambridge, England.
-<br>
-</P>
-<br><b>
-REVISION
-</b><br>
-<P>
-Last updated: 21 November 2014
-<br>
-Copyright &copy; 1997-2014 University of Cambridge.
-<br>
-<p>
-Return to the <a href="index.html">PCRE2 index page</a>.
-</p>
diff --git a/dist2/doc/html/pcre2syntax.html b/dist2/doc/html/pcre2syntax.html
index 7fdc0dc..9098f47 100644
--- a/dist2/doc/html/pcre2syntax.html
+++ b/dist2/doc/html/pcre2syntax.html
@@ -430,18 +430,21 @@
   (?i)            caseless
   (?J)            allow duplicate names
   (?m)            multiline
+  (?n)            no auto capture
   (?s)            single line (dotall)
   (?U)            default ungreedy (lazy)
-  (?x)            extended (ignore white space)
+  (?x)            extended: ignore white space except in classes
+  (?xx)           as (?x) but also ignore space and tab in classes
   (?-...)         unset option(s)
 </pre>
 The following are recognized only at the very start of a pattern or after one
 of the newline or \R options with similar syntax. More than one of them may
-appear.
+appear. For the first three, d is a decimal number.
 <pre>
-  (*LIMIT_MATCH=d) set the match limit to d (decimal number)
-  (*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
-  (*NOTEMPTY)     set PCRE2_NOTEMPTY when matching
+  (*LIMIT_DEPTH=d) set the backtracking limit to d
+  (*LIMIT_HEAP=d)  set the heap size limit to d kilobytes
+  (*LIMIT_MATCH=d) set the match limit to d
+  (*NOTEMPTY)      set PCRE2_NOTEMPTY when matching
   (*NOTEMPTY_ATSTART) set PCRE2_NOTEMPTY_ATSTART when matching
   (*NO_AUTO_POSSESS) no auto-possessification (PCRE2_NO_AUTO_POSSESS)
   (*NO_DOTSTAR_ANCHOR) no .* anchoring (PCRE2_NO_DOTSTAR_ANCHOR)
@@ -450,10 +453,11 @@
   (*UTF)          set appropriate UTF mode for the library in use
   (*UCP)          set PCRE2_UCP (use Unicode properties for \d etc)
 </pre>
-Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of the
-limits set by the caller of pcre2_match(), not increase them. The application
-can lock out the use of (*UTF) and (*UCP) by setting the PCRE2_NEVER_UTF or
-PCRE2_NEVER_UCP options, respectively, at compile time.
+Note that LIMIT_DEPTH, LIMIT_HEAP, and LIMIT_MATCH can only reduce the value of
+the limits set by the caller of <b>pcre2_match()</b> or <b>pcre2_dfa_match()</b>,
+not increase them. LIMIT_RECURSION is an obsolete synonym for LIMIT_DEPTH. The
+application can lock out the use of (*UTF) and (*UCP) by setting the
+PCRE2_NEVER_UTF or PCRE2_NEVER_UCP options, respectively, at compile time.
 </P>
 <br><a name="SEC17" href="#TOC1">NEWLINE CONVENTION</a><br>
 <P>
@@ -465,6 +469,7 @@
   (*CRLF)         carriage return followed by linefeed
   (*ANYCRLF)      all three of the above
   (*ANY)          any Unicode newline sequence
+  (*NUL)          the NUL character (binary zero)
 </PRE>
 </P>
 <br><a name="SEC18" href="#TOC1">WHAT \R MATCHES</a><br>
@@ -492,6 +497,9 @@
   \n              reference by number (can be ambiguous)
   \gn             reference by number
   \g{n}           reference by number
+  \g+n            relative reference by number (PCRE2 extension)
+  \g-n            relative reference by number
+  \g{+n}          relative reference by number (PCRE2 extension)
   \g{-n}          relative reference by number
   \k&#60;name&#62;        reference by name (Perl)
   \k'name'        reference by name (Perl)
@@ -530,14 +538,17 @@
   (?(-n)              relative reference condition
   (?(&#60;name&#62;)          named reference condition (Perl)
   (?('name')          named reference condition (Perl)
-  (?(name)            named reference condition (PCRE2)
+  (?(name)            named reference condition (PCRE2, deprecated)
   (?(R)               overall recursion condition
-  (?(Rn)              specific group recursion condition
-  (?(R&name)          specific recursion condition
+  (?(Rn)              specific numbered group recursion condition
+  (?(R&name)          specific named group recursion condition
   (?(DEFINE)          define subpattern for reference
   (?(VERSION[&#62;]=n.m)  test PCRE2 version
   (?(assert)          assertion condition
-</PRE>
+</pre>
+Note the ambiguity of (?(R) and (?(Rn) which might be named reference
+conditions or recursion tests. Such a condition is interpreted as a reference
+condition if the relevant named group exists.
 </P>
 <br><a name="SEC23" href="#TOC1">BACKTRACKING CONTROL</a><br>
 <P>
@@ -589,9 +600,9 @@
 </P>
 <br><a name="SEC27" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 16 October 2015
+Last updated: 17 June 2017
 <br>
-Copyright &copy; 1997-2015 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2test.html b/dist2/doc/html/pcre2test.html
index 17b308e..7d98d90 100644
--- a/dist2/doc/html/pcre2test.html
+++ b/dist2/doc/html/pcre2test.html
@@ -61,7 +61,7 @@
 <P>
 As the original fairly simple PCRE library evolved, it acquired many different
 features, and as a result, the original <b>pcretest</b> program ended up with a
-lot of options in a messy, arcane syntax, for testing all the features. The
+lot of options in a messy, arcane syntax for testing all the features. The
 move to the new PCRE2 API provided an opportunity to re-implement the test
 program as <b>pcre2test</b>, with a cleaner modifier syntax. Nevertheless, there
 are still many obscure modifiers, some of which are specifically designed for
@@ -77,32 +77,62 @@
 all three of these libraries may be simultaneously installed. The
 <b>pcre2test</b> program can be used to test all the libraries. However, its own
 input and output are always in 8-bit format. When testing the 16-bit or 32-bit
-libraries, patterns and subject strings are converted to 16- or 32-bit format
-before being passed to the library functions. Results are converted back to
-8-bit code units for output.
+libraries, patterns and subject strings are converted to 16-bit or 32-bit
+format before being passed to the library functions. Results are converted back
+to 8-bit code units for output.
 </P>
 <P>
 In the rest of this document, the names of library functions and structures
 are given in generic form, for example, <b>pcre_compile()</b>. The actual
 names used in the libraries have a suffix _8, _16, or _32, as appropriate.
-</P>
+<a name="inputencoding"></a></P>
 <br><a name="SEC3" href="#TOC1">INPUT ENCODING</a><br>
 <P>
 Input to <b>pcre2test</b> is processed line by line, either by calling the C
-library's <b>fgets()</b> function, or via the <b>libreadline</b> library (see
-below). The input is processed using using C's string functions, so must not
-contain binary zeroes, even though in Unix-like environments, <b>fgets()</b>
-treats any bytes other than newline as data characters. In some Windows
-environments character 26 (hex 1A) causes an immediate end of file, and no
-further data is read.
+library's <b>fgets()</b> function, or via the <b>libreadline</b> library. In some
+Windows environments character 26 (hex 1A) causes an immediate end of file, and
+no further data is read, so this character should be avoided unless you really
+want that action.
 </P>
 <P>
-For maximum portability, therefore, it is safest to avoid non-printing
-characters in <b>pcre2test</b> input files. There is a facility for specifying
-some or all of a pattern's characters as hexadecimal pairs, thus making it
-possible to include binary zeroes in a pattern for testing purposes. Subject
-lines are processed for backslash escapes, which makes it possible to include
-any data value.
+The input is processed using using C's string functions, so must not
+contain binary zeros, even though in Unix-like environments, <b>fgets()</b>
+treats any bytes other than newline as data characters. An error is generated
+if a binary zero is encountered. By default subject lines are processed for
+backslash escapes, which makes it possible to include any data value in strings
+that are passed to the library for matching. For patterns, there is a facility
+for specifying some or all of the 8-bit input characters as hexadecimal pairs,
+which makes it possible to include binary zeros.
+</P>
+<br><b>
+Input for the 16-bit and 32-bit libraries
+</b><br>
+<P>
+When testing the 16-bit or 32-bit libraries, there is a need to be able to
+generate character code points greater than 255 in the strings that are passed
+to the library. For subject lines, backslash escapes can be used. In addition,
+when the <b>utf</b> modifier (see
+<a href="#optionmodifiers">"Setting compilation options"</a>
+below) is set, the pattern and any following subject lines are interpreted as
+UTF-8 strings and translated to UTF-16 or UTF-32 as appropriate.
+</P>
+<P>
+For non-UTF testing of wide characters, the <b>utf8_input</b> modifier can be
+used. This is mutually exclusive with <b>utf</b>, and is allowed only in 16-bit
+or 32-bit mode. It causes the pattern and following subject lines to be treated
+as UTF-8 according to the original definition (RFC 2279), which allows for
+character values up to 0x7fffffff. Each character is placed in one 16-bit or
+32-bit code unit (in the 16-bit case, values greater than 0xffff cause an error
+to occur).
+</P>
+<P>
+UTF-8 (in its original definition) is not capable of encoding values greater
+than 0x7fffffff, but such values can be handled by the 32-bit library. When
+testing this library in non-UTF mode with <b>utf8_input</b> set, if any
+character is preceded by the byte 0xff (which is an illegal byte in UTF-8)
+0x80000000 is added to the character's value. This is the only way of passing
+such code points in a pattern string. For subject strings, using an escape
+sequence is preferable.
 </P>
 <br><a name="SEC4" href="#TOC1">COMMAND LINE OPTIONS</a><br>
 <P>
@@ -124,15 +154,27 @@
 has not been built, this option causes an error.
 </P>
 <P>
+<b>-ac</b>
+Behave as if each pattern has the <b>auto_callout</b> modifier, that is, insert
+automatic callouts into every pattern that is compiled.
+</P>
+<P>
+<b>-AC</b>
+As for <b>-ac</b>, but in addition behave as if each subject line has the
+<b>callout_extra</b> modifier, that is, show additional information from
+callouts.
+</P>
+<P>
 <b>-b</b>
-Behave as if each pattern has the <b>/fullbincode</b> modifier; the full
+Behave as if each pattern has the <b>fullbincode</b> modifier; the full
 internal binary form of the pattern is output after compilation.
 </P>
 <P>
 <b>-C</b>
 Output the version number of the PCRE2 library, and all available information
 about the optional features that are included, and then exit with zero exit
-code. All other options are ignored.
+code. All other options are ignored. If both -C and -LM are present, whichever
+is first is recognized.
 </P>
 <P>
 <b>-C</b> <i>option</i>
@@ -147,7 +189,7 @@
   linksize   the configured internal link size (2, 3, or 4)
                exit code is set to the link size
   newline    the default newline setting:
-               CR, LF, CRLF, ANYCRLF, or ANY
+               CR, LF, CRLF, ANYCRLF, ANY, or NUL
                exit code is always 0
   bsr        the default setting for what \R matches:
                ANYCRLF or ANY
@@ -191,7 +233,7 @@
 </P>
 <P>
 <b>-i</b>
-Behave as if each pattern has the <b>/info</b> modifier; information about the
+Behave as if each pattern has the <b>info</b> modifier; information about the
 compiled pattern is given after compilation.
 </P>
 <P>
@@ -200,6 +242,18 @@
 compilation, each pattern is passed to the just-in-time compiler, if available.
 </P>
 <P>
+<b>-jitverify</b>
+Behave as if each pattern line has the <b>jitverify</b> modifier; after
+successful compilation, each pattern is passed to the just-in-time compiler, if
+available, and the use of JIT is verified.
+</P>
+<P>
+<b>-LM</b>
+List modifiers: write a list of available pattern and subject modifiers to the
+standard output, then exit with zero exit code. All other options are ignored.
+If both -C and -LM are present, whichever is first is recognized.
+</P>
+<P>
 \fB-pattern\fB <i>modifier-list</i>
 Behave as if each pattern line contains the given modifiers.
 </P>
@@ -326,8 +380,8 @@
 </P>
 <P>
 The #newline_default command specifies a list of newline types that are
-acceptable as the default. The types must be one of CR, LF, CRLF, ANYCRLF, or
-ANY (in upper or lower case), for example:
+acceptable as the default. The types must be one of CR, LF, CRLF, ANYCRLF,
+ANY, or NUL (in upper or lower case), for example:
 <pre>
   #newline_default LF Any anyCRLF
 </pre>
@@ -341,8 +395,9 @@
 <P>
 When the POSIX API is being tested there is no way to override the default
 newline convention, though it is possible to set the newline convention from
-within the pattern. A warning is given if the <b>posix</b> modifier is used when
-<b>#newline_default</b> would set a default for the non-POSIX API.
+within the pattern. A warning is given if the <b>posix</b> or <b>posix_nosub</b>
+modifier is used when <b>#newline_default</b> would set a default for the
+non-POSIX API.
 <pre>
   #pattern &#60;modifier-list&#62;
 </pre>
@@ -438,8 +493,9 @@
 <P>
 Before each subject line is passed to <b>pcre2_match()</b> or
 <b>pcre2_dfa_match()</b>, leading and trailing white space is removed, and the
-line is scanned for backslash escapes. The following provide a means of
-encoding non-printing characters in a visible way:
+line is scanned for backslash escapes, unless the <b>subject_literal</b>
+modifier was set for the pattern. The following provide a means of encoding
+non-printing characters in a visible way:
 <pre>
   \a         alarm (BEL, \x07)
   \b         backspace (\x08)
@@ -507,6 +563,12 @@
 list), it is ignored. This gives a way of passing an empty line as data, since
 a real empty line terminates the data input.
 </P>
+<P>
+If the <b>subject_literal</b> modifier is set for a pattern, all subject lines
+that follow are treated as literals, with no special treatment of backslashes.
+No replication is possible, and any subject modifiers must be set as defaults
+by a <b>#subject</b> command.
+</P>
 <br><a name="SEC10" href="#TOC1">PATTERN MODIFIERS</a><br>
 <P>
 There are several types of modifier that can appear in pattern lines. Except
@@ -518,29 +580,42 @@
 Setting compilation options
 </b><br>
 <P>
-The following modifiers set options for <b>pcre2_compile()</b>. The most common
-ones have single-letter abbreviations. See
+The following modifiers set options for <b>pcre2_compile()</b>. Most of them set
+bits in the options argument of that function, but those whose names start with
+PCRE2_EXTRA are additional options that are set in the compile context. For the
+main options, there are some single-letter abbreviations that are the same as
+Perl options. There is special handling for /x: if a second x is present,
+PCRE2_EXTENDED is converted into PCRE2_EXTENDED_MORE as in Perl. A third
+appearance adds PCRE2_EXTENDED as well, though this makes no difference to the
+way <b>pcre2_compile()</b> behaves. See
 <a href="pcre2api.html"><b>pcre2api</b></a>
-for a description of their effects.
+for a description of the effects of these options.
 <pre>
       allow_empty_class         set PCRE2_ALLOW_EMPTY_CLASS
+      allow_surrogate_escapes   set PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES
       alt_bsux                  set PCRE2_ALT_BSUX
       alt_circumflex            set PCRE2_ALT_CIRCUMFLEX
       alt_verbnames             set PCRE2_ALT_VERBNAMES
       anchored                  set PCRE2_ANCHORED
       auto_callout              set PCRE2_AUTO_CALLOUT
+      bad_escape_is_literal     set PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
   /i  caseless                  set PCRE2_CASELESS
       dollar_endonly            set PCRE2_DOLLAR_ENDONLY
   /s  dotall                    set PCRE2_DOTALL
       dupnames                  set PCRE2_DUPNAMES
+      endanchored               set PCRE2_ENDANCHORED
   /x  extended                  set PCRE2_EXTENDED
+  /xx extended_more             set PCRE2_EXTENDED_MORE
       firstline                 set PCRE2_FIRSTLINE
+      literal                   set PCRE2_LITERAL
+      match_line                set PCRE2_EXTRA_MATCH_LINE
       match_unset_backref       set PCRE2_MATCH_UNSET_BACKREF
+      match_word                set PCRE2_EXTRA_MATCH_WORD
   /m  multiline                 set PCRE2_MULTILINE
       never_backslash_c         set PCRE2_NEVER_BACKSLASH_C
       never_ucp                 set PCRE2_NEVER_UCP
       never_utf                 set PCRE2_NEVER_UTF
-      no_auto_capture           set PCRE2_NO_AUTO_CAPTURE
+  /n  no_auto_capture           set PCRE2_NO_AUTO_CAPTURE
       no_auto_possess           set PCRE2_NO_AUTO_POSSESS
       no_dotstar_anchor         set PCRE2_NO_DOTSTAR_ANCHOR
       no_start_optimize         set PCRE2_NO_START_OPTIMIZE
@@ -553,19 +628,27 @@
 As well as turning on the PCRE2_UTF option, the <b>utf</b> modifier causes all
 non-printing characters in output strings to be printed using the \x{hh...}
 notation. Otherwise, those less than 0x100 are output in hex without the curly
-brackets.
+brackets. Setting <b>utf</b> in 16-bit or 32-bit mode also causes pattern and
+subject strings to be translated to UTF-16 or UTF-32, respectively, before
+being passed to library functions.
 <a name="controlmodifiers"></a></P>
 <br><b>
 Setting compilation controls
 </b><br>
 <P>
 The following modifiers affect the compilation process or request information
-about the pattern:
+about the pattern. There are single-letter abbreviations for some that are
+heavily used in the test files.
 <pre>
       bsr=[anycrlf|unicode]     specify \R handling
   /B  bincode                   show binary code without lengths
       callout_info              show callout information
+      convert=&#60;options&#62;         request foreign pattern conversion
+      convert_glob_escape=c     set glob escape character
+      convert_glob_separator=c  set glob separator character
+      convert_length            set convert buffer length
       debug                     same as info,fullbincode
+      framesize                 show matching frame size
       fullbincode               show binary code with lengths
   /I  info                      show info about compiled pattern
       hex                       unquoted characters are hexadecimal
@@ -583,7 +666,10 @@
       push                      push compiled pattern onto the stack
       pushcopy                  push a copy onto the stack
       stackguard=&#60;number&#62;       test the stackguard feature
+      subject_literal           treat all subject lines as literal
       tables=[0|1|2]            select internal tables
+      use_length                do not zero-terminate the pattern
+      utf8_input                treat input as UTF-8
 </pre>
 The effects of these modifiers are described in the following sections.
 </P>
@@ -599,7 +685,7 @@
 <P>
 The <b>newline</b> modifier specifies which characters are to be interpreted as
 newlines, both in the pattern and in subject lines. The type must be one of CR,
-LF, CRLF, ANYCRLF, or ANY (in upper or lower case).
+LF, CRLF, ANYCRLF, ANY, or NUL (in upper or lower case).
 </P>
 <br><b>
 Information about a pattern
@@ -651,6 +737,11 @@
 ending code units are recorded.
 </P>
 <P>
+The <b>framesize</b> modifier shows the size, in bytes, of the storage frames
+used by <b>pcre2_match()</b> for handling backtracking. The size depends on the
+number of capturing parentheses in the pattern.
+</P>
+<P>
 The <b>callout_info</b> modifier requests information about all the callouts in
 the pattern. A list of them is output at the end of any other information that
 is requested. For each callout, either its number or string is given, followed
@@ -684,13 +775,36 @@
   /ab "literal" 32/hex
 </pre>
 Either single or double quotes may be used. There is no way of including
-the delimiter within a substring.
+the delimiter within a substring. The <b>hex</b> and <b>expand</b> modifiers are
+mutually exclusive.
+</P>
+<br><b>
+Specifying the pattern's length
+</b><br>
+<P>
+By default, patterns are passed to the compiling functions as zero-terminated
+strings but can be passed by length instead of being zero-terminated. The
+<b>use_length</b> modifier causes this to happen. Using a length happens
+automatically (whether or not <b>use_length</b> is set) when <b>hex</b> is set,
+because patterns specified in hexadecimal may contain binary zeros.
 </P>
 <P>
-By default, <b>pcre2test</b> passes patterns as zero-terminated strings to
-<b>pcre2_compile()</b>, giving the length as PCRE2_ZERO_TERMINATED. However, for
-patterns specified with the <b>hex</b> modifier, the actual length of the
-pattern is passed.
+If <b>hex</b> or <b>use_length</b> is used with the POSIX wrapper API (see
+<a href="#posixwrapper">"Using the POSIX wrapper API"</a>
+below), the REG_PEND extension is used to pass the pattern's length.
+</P>
+<br><b>
+Specifying wide characters in 16-bit and 32-bit modes
+</b><br>
+<P>
+In 16-bit and 32-bit modes, all input is automatically treated as UTF-8 and
+translated to UTF-16 or UTF-32 when the <b>utf</b> modifier is set. For testing
+the 16-bit and 32-bit libraries in non-UTF mode, the <b>utf8_input</b> modifier
+can be used. It is mutually exclusive with <b>utf</b>. Input lines are
+interpreted as UTF-8 as a means of specifying wide characters. More details are
+given in
+<a href="#inputencoding">"Input encoding"</a>
+above.
 </P>
 <br><b>
 Generating long repetitive patterns
@@ -708,7 +822,8 @@
 example, \[AB]{6000} is expanded to "ABAB..." 6000 times. This construction
 cannot be nested. An initial "\[" sequence is recognized only if "]{" followed
 by decimal digits and "}" is found later in the pattern. If not, the characters
-remain in the pattern unaltered.
+remain in the pattern unaltered. The <b>expand</b> and <b>hex</b> modifiers are
+mutually exclusive.
 </P>
 <P>
 If part of an expanded pattern looks like an expansion, but is really part of
@@ -737,7 +852,7 @@
 for details of how these options are specified for each match attempt.
 </P>
 <P>
-JIT compilation is requested by the <b>/jit</b> pattern modifier, which may
+JIT compilation is requested by the <b>jit</b> pattern modifier, which may
 optionally be followed by an equals sign and a number in the range 0 to 7.
 The three bits that make up the number specify which of the three JIT operating
 modes are to be compiled:
@@ -746,7 +861,7 @@
   2  compile JIT code for soft partial matching
   4  compile JIT code for hard partial matching
 </pre>
-The possible values for the <b>/jit</b> modifier are therefore:
+The possible values for the <b>jit</b> modifier are therefore:
 <pre>
   0  disable JIT
   1  normal matching only
@@ -761,7 +876,7 @@
 PCRE2_PARTIAL_HARD option set. Note that such a call may return a complete
 match; the options enable the possibility of a partial match, but do not
 require it. Note also that if you request JIT compilation only for partial
-matching (for example, /jit=2) but do not set the <b>partial</b> modifier on a
+matching (for example, jit=2) but do not set the <b>partial</b> modifier on a
 subject line, that match will not use JIT code because none was compiled for
 non-partial matching.
 </P>
@@ -792,14 +907,14 @@
 Setting a locale
 </b><br>
 <P>
-The <b>/locale</b> modifier must specify the name of a locale, for example:
+The <b>locale</b> modifier must specify the name of a locale, for example:
 <pre>
   /pattern/locale=fr_FR
 </pre>
 The given locale is set, <b>pcre2_maketables()</b> is called to build a set of
 character tables for the locale, and this is then passed to
 <b>pcre2_compile()</b> when compiling the regular expression. The same tables
-are used when matching the following subject lines. The <b>/locale</b> modifier
+are used when matching the following subject lines. The <b>locale</b> modifier
 applies only to the pattern on which it appears, but can be given in a
 <b>#pattern</b> command if a default is needed. Setting a locale and alternate
 character tables are mutually exclusive.
@@ -808,7 +923,7 @@
 Showing pattern memory
 </b><br>
 <P>
-The <b>/memory</b> modifier causes the size in bytes of the memory used to hold
+The <b>memory</b> modifier causes the size in bytes of the memory used to hold
 the compiled pattern to be output. This does not include the size of the
 <b>pcre2_code</b> block; it is just the actual compiled data. If the pattern is
 subsequently passed to the JIT compiler, the size of the JIT compiled code is
@@ -838,12 +953,12 @@
 length of pattern that <b>pcre2_compile()</b> will accept. Breaching the limit
 causes a compilation error. The default is the largest number a PCRE2_SIZE
 variable can hold (essentially unlimited).
-</P>
+<a name="posixwrapper"></a></P>
 <br><b>
 Using the POSIX wrapper API
 </b><br>
 <P>
-The <b>/posix</b> and <b>posix_nosub</b> modifiers cause <b>pcre2test</b> to call
+The <b>posix</b> and <b>posix_nosub</b> modifiers cause <b>pcre2test</b> to call
 PCRE2 via the POSIX wrapper API rather than its native API. When
 <b>posix_nosub</b> is used, the POSIX option REG_NOSUB is passed to
 <b>regcomp()</b>. The POSIX wrapper supports only the 8-bit library. Note that
@@ -873,11 +988,16 @@
 below. All other modifiers are either ignored, with a warning message, or cause
 an error.
 </P>
+<P>
+The pattern is passed to <b>regcomp()</b> as a zero-terminated string by
+default, but if the <b>use_length</b> or <b>hex</b> modifiers are set, the
+REG_PEND extension is used to pass it by length.
+</P>
 <br><b>
 Testing the stack guard feature
 </b><br>
 <P>
-The <b>/stackguard</b> modifier is used to test the use of
+The <b>stackguard</b> modifier is used to test the use of
 <b>pcre2_set_compile_recursion_guard()</b>, a function that is provided to
 enable stack availability to be checked during compilation (see the
 <a href="pcre2api.html"><b>pcre2api</b></a>
@@ -892,7 +1012,7 @@
 Using alternative character tables
 </b><br>
 <P>
-The value specified for the <b>/tables</b> modifier must be one of the digits 0,
+The value specified for the <b>tables</b> modifier must be one of the digits 0,
 1, or 2. It causes a specific set of built-in character tables to be passed to
 <b>pcre2_compile()</b>. This is used in the PCRE2 tests to check behaviour with
 different character tables. The digit specifies the tables as follows:
@@ -910,17 +1030,19 @@
 Setting certain match controls
 </b><br>
 <P>
-The following modifiers are really subject modifiers, and are described below.
-However, they may be included in a pattern's modifier list, in which case they
-are applied to every subject line that is processed with that pattern. They may
-not appear in <b>#pattern</b> commands. These modifiers do not affect the
-compilation process.
+The following modifiers are really subject modifiers, and are described under
+"Subject Modifiers" below. However, they may be included in a pattern's
+modifier list, in which case they are applied to every subject line that is
+processed with that pattern. These modifiers do not affect the compilation
+process.
 <pre>
       aftertext                  show text after match
       allaftertext               show text after captures
       allcaptures                show all captures
       allusedtext                show all consulted text
+      altglobal                  alternative global matching
   /g  global                     global matching
+      jitstack=&#60;n&#62;               set size of JIT stack
       mark                       show mark values
       replace=&#60;string&#62;           specify a replacement string
       startchar                  show starting character when relevant
@@ -933,6 +1055,15 @@
 defaults, set them in a <b>#subject</b> command.
 </P>
 <br><b>
+Specifying literal subject lines
+</b><br>
+<P>
+If the <b>subject_literal</b> modifier is present on a pattern, all the subject
+lines that it matches are taken as literal strings, with no interpretation of
+backslashes. It is not possible to set subject modifiers on such lines, but any
+that are set as defaults by a <b>#subject</b> command are recognized.
+</P>
+<br><b>
 Saving a compiled pattern
 </b><br>
 <P>
@@ -941,7 +1072,8 @@
 line to contain a new pattern (or a command) instead of a subject line. This
 facility is used when saving compiled patterns to a file, as described in the
 section entitled "Saving and restoring compiled patterns"
-<a href="#saverestore">below. If <b>pushcopy</b> is used instead of <b>push</b>, a copy of the compiled</a>
+<a href="#saverestore">below.</a>
+If <b>pushcopy</b> is used instead of <b>push</b>, a copy of the compiled
 pattern is stacked, leaving the original as current, ready to match the
 following input lines. This provides a way of testing the
 <b>pcre2_code_copy()</b> function.
@@ -951,6 +1083,41 @@
 <b>replace</b>, which causes an error. Note that <b>jitverify</b>, which is
 allowed, does not carry through to any subsequent matching that uses a stacked
 pattern.
+</P>
+<br><b>
+Testing foreign pattern conversion
+</b><br>
+<P>
+The experimental foreign pattern conversion functions in PCRE2 can be tested by
+setting the <b>convert</b> modifier. Its argument is a colon-separated list of
+options, which set the equivalent option for the <b>pcre2_pattern_convert()</b>
+function:
+<pre>
+  glob                    PCRE2_CONVERT_GLOB
+  glob_no_starstar        PCRE2_CONVERT_GLOB_NO_STARSTAR
+  glob_no_wild_separator  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR
+  posix_basic             PCRE2_CONVERT_POSIX_BASIC
+  posix_extended          PCRE2_CONVERT_POSIX_EXTENDED
+  unset                   Unset all options
+</pre>
+The "unset" value is useful for turning off a default that has been set by a
+<b>#pattern</b> command. When one of these options is set, the input pattern is
+passed to <b>pcre2_pattern_convert()</b>. If the conversion is successful, the
+result is reflected in the output and then passed to <b>pcre2_compile()</b>. The
+normal <b>utf</b> and <b>no_utf_check</b> options, if set, cause the
+PCRE2_CONVERT_UTF and PCRE2_CONVERT_NO_UTF_CHECK options to be passed to
+<b>pcre2_pattern_convert()</b>.
+</P>
+<P>
+By default, the conversion function is allowed to allocate a buffer for its
+output. However, if the <b>convert_length</b> modifier is set to a value greater
+than zero, <b>pcre2test</b> passes a buffer of the given length. This makes it
+possible to test the length check.
+</P>
+<P>
+The <b>convert_glob_escape</b> and <b>convert_glob_separator</b> modifiers can be
+used to specify the escape and separator characters for glob processing,
+overriding the defaults, which are operating-system dependent.
 <a name="subjectmodifiers"></a></P>
 <br><a name="SEC11" href="#TOC1">SUBJECT MODIFIERS</a><br>
 <P>
@@ -967,6 +1134,7 @@
 for a description of their effects.
 <pre>
       anchored                  set PCRE2_ANCHORED
+      endanchored               set PCRE2_ENDANCHORED
       dfa_restart               set PCRE2_DFA_RESTART
       dfa_shortest              set PCRE2_DFA_SHORTEST
       no_jit                    set PCRE2_NO_JIT
@@ -982,11 +1150,26 @@
 appear frequently in tests.
 </P>
 <P>
-If the <b>/posix</b> modifier was present on the pattern, causing the POSIX
-wrapper API to be used, the only option-setting modifiers that have any effect
-are <b>notbol</b>, <b>notempty</b>, and <b>noteol</b>, causing REG_NOTBOL,
-REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to <b>regexec()</b>.
-The other modifiers are ignored, with a warning message.
+If the <b>posix</b> or <b>posix_nosub</b> modifier was present on the pattern,
+causing the POSIX wrapper API to be used, the only option-setting modifiers
+that have any effect are <b>notbol</b>, <b>notempty</b>, and <b>noteol</b>,
+causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to
+<b>regexec()</b>. The other modifiers are ignored, with a warning message.
+</P>
+<P>
+There is one additional modifier that can be used with the POSIX wrapper. It is
+ignored (with a warning) if used for non-POSIX matching.
+<pre>
+      posix_startend=&#60;n&#62;[:&#60;m&#62;]
+</pre>
+This causes the subject string to be passed to <b>regexec()</b> using the
+REG_STARTEND option, which uses offsets to specify which part of the string is
+searched. If only one number is given, the end offset is passed as the end of
+the subject string. For more detail of REG_STARTEND, see the
+<a href="pcre2posix.html"><b>pcre2posix</b></a>
+documentation. If the subject string contains binary zeros (coded as escapes
+such as \x{00} because <b>pcre2test</b> does not support actual binary zeros in
+its input), you must use <b>posix_startend</b> to specify its length.
 </P>
 <br><b>
 Setting match controls
@@ -1004,23 +1187,28 @@
       altglobal                  alternative global matching
       callout_capture            show captures at callout time
       callout_data=&#60;n&#62;           set a value to pass via callouts
+      callout_error=&#60;n&#62;[:&#60;m&#62;]    control callout error
+      callout_extra              show extra callout information
       callout_fail=&#60;n&#62;[:&#60;m&#62;]     control callout failure
+      callout_no_where           do not show position of a callout
       callout_none               do not supply a callout function
       copy=&#60;number or name&#62;      copy captured substring
+      depth_limit=&#60;n&#62;            set a depth limit
       dfa                        use <b>pcre2_dfa_match()</b>
-      find_limits                find match and recursion limits
+      find_limits                find match and depth limits
       get=&#60;number or name&#62;       extract captured substring
       getall                     extract all captured substrings
   /g  global                     global matching
+      heap_limit=&#60;n&#62;             set a limit on heap memory
       jitstack=&#60;n&#62;               set size of JIT stack
       mark                       show mark values
       match_limit=&#60;n&#62;            set a match limit
-      memory                     show memory usage
+      memory                     show heap memory usage
       null_context               match with a NULL context
       offset=&#60;n&#62;                 set starting offset
       offset_limit=&#60;n&#62;           set offset limit
       ovector=&#60;n&#62;                set size of output vector
-      recursion_limit=&#60;n&#62;        set a recursion limit
+      recursion_limit=&#60;n&#62;        obsolete synonym for depth_limit
       replace=&#60;string&#62;           specify a replacement string
       startchar                  show startchar when relevant
       startoffset=&#60;n&#62;            same as offset=&#60;n&#62;
@@ -1098,29 +1286,17 @@
 </b><br>
 <P>
 A callout function is supplied when <b>pcre2test</b> calls the library matching
-functions, unless <b>callout_none</b> is specified. If <b>callout_capture</b> is
-set, the current captured groups are output when a callout occurs.
-</P>
-<P>
-The <b>callout_fail</b> modifier can be given one or two numbers. If there is
-only one number, 1 is returned instead of 0 when a callout of that number is
-reached. If two numbers are given, 1 is returned when callout &#60;n&#62; is reached
-for the &#60;m&#62;th time. Note that callouts with string arguments are always given
-the number zero. See "Callouts" below for a description of the output when a
-callout it taken.
-</P>
-<P>
-The <b>callout_data</b> modifier can be given an unsigned or a negative number.
-This is set as the "user data" that is passed to the matching function, and
-passed back when the callout function is invoked. Any value other than zero is
-used as a return from <b>pcre2test</b>'s callout function.
+functions, unless <b>callout_none</b> is specified. Its behaviour can be
+controlled by various modifiers listed above whose names begin with
+<b>callout_</b>. Details are given in the section entitled "Callouts"
+<a href="#callouts">below.</a>
 </P>
 <br><b>
 Finding all matches in a string
 </b><br>
 <P>
 Searching for all possible matches within a subject can be requested by the
-<b>global</b> or <b>/altglobal</b> modifier. After finding a match, the matching
+<b>global</b> or <b>altglobal</b> modifier. After finding a match, the matching
 function is called again to search the remainder of the subject. The difference
 between <b>global</b> and <b>altglobal</b> is that the former uses the
 <i>start_offset</i> argument to <b>pcre2_match()</b> or <b>pcre2_dfa_match()</b>
@@ -1242,41 +1418,47 @@
 <P>
 The <b>jitstack</b> modifier provides a way of setting the maximum stack size
 that is used by the just-in-time optimization code. It is ignored if JIT
-optimization is not being used. The value is a number of kilobytes. Providing a
-stack that is larger than the default 32K is necessary only for very
-complicated patterns.
+optimization is not being used. The value is a number of kilobytes. Setting
+zero reverts to the default of 32K. Providing a stack that is larger than the
+default is necessary only for very complicated patterns. If <b>jitstack</b> is
+set non-zero on a subject line it overrides any value that was set on the
+pattern.
 </P>
 <br><b>
-Setting match and recursion limits
+Setting heap, match, and depth limits
 </b><br>
 <P>
-The <b>match_limit</b> and <b>recursion_limit</b> modifiers set the appropriate
-limits in the match context. These values are ignored when the
+The <b>heap_limit</b>, <b>match_limit</b>, and <b>depth_limit</b> modifiers set
+the appropriate limits in the match context. These values are ignored when the
 <b>find_limits</b> modifier is specified.
 </P>
 <br><b>
 Finding minimum limits
 </b><br>
 <P>
-If the <b>find_limits</b> modifier is present, <b>pcre2test</b> calls
-<b>pcre2_match()</b> several times, setting different values in the match
-context via <b>pcre2_set_match_limit()</b> and <b>pcre2_set_recursion_limit()</b>
-until it finds the minimum values for each parameter that allow
-<b>pcre2_match()</b> to complete without error.
+If the <b>find_limits</b> modifier is present on a subject line, <b>pcre2test</b>
+calls the relevant matching function several times, setting different values in
+the match context via <b>pcre2_set_heap_limit(), \fBpcre2_set_match_limit()</b>,
+or <b>pcre2_set_depth_limit()</b> until it finds the minimum values for each
+parameter that allows the match to complete without error.
 </P>
 <P>
 If JIT is being used, only the match limit is relevant. If DFA matching is
-being used, neither limit is relevant, and this modifier is ignored (with a
-warning message).
+being used, only the depth limit is relevant.
 </P>
 <P>
 The <i>match_limit</i> number is a measure of the amount of backtracking
 that takes place, and learning the minimum value can be instructive. For most
 simple matches, the number is quite small, but for patterns with very large
 numbers of matching possibilities, it can become large very quickly with
-increasing length of subject string. The <i>match_limit_recursion</i> number is
-a measure of how much stack (or, if PCRE2 is compiled with NO_RECURSE, how much
-heap) memory is needed to complete the match attempt.
+increasing length of subject string.
+</P>
+<P>
+For non-DFA matching, the minimum <i>depth_limit</i> number is a measure of how
+much nested backtracking happens (that is, how deeply the pattern's tree is
+searched). In the case of DFA matching, <i>depth_limit</i> controls the depth of
+recursive calls of the internal function that is used for handling pattern
+recursion, lookaround assertions, and atomic groups.
 </P>
 <br><b>
 Showing MARK names
@@ -1292,8 +1474,15 @@
 Showing memory usage
 </b><br>
 <P>
-The <b>memory</b> modifier causes <b>pcre2test</b> to log all memory allocation
-and freeing calls that occur during a match operation.
+The <b>memory</b> modifier causes <b>pcre2test</b> to log the sizes of all heap
+memory allocation and freeing calls that occur during a call to
+<b>pcre2_match()</b>. These occur only when a match requires a bigger vector
+than the default for remembering backtracking points. In many cases there will
+be no heap memory used and therefore no additional output. No heap memory is
+allocated during matching with <b>pcre2_dfa_match</b> or with JIT, so in those
+cases the <b>memory</b> modifier never has any effect. For this modifier to
+work, the <b>null_context</b> modifier must not be set on both the pattern and
+the subject, though it can be set on one or the other.
 </P>
 <br><b>
 Setting a starting offset
@@ -1337,8 +1526,8 @@
 By default, the subject string is passed to a native API matching function with
 its correct length. In order to test the facility for passing a zero-terminated
 string, the <b>zero_terminate</b> modifier is provided. It causes the length to
-be passed as PCRE2_ZERO_TERMINATED. (When matching via the POSIX interface,
-this modifier has no effect, as there is no facility for passing a length.)
+be passed as PCRE2_ZERO_TERMINATED. When matching via the POSIX interface,
+this modifier is ignored, with a warning.
 </P>
 <P>
 When testing <b>pcre2_substitute()</b>, this modifier also has the effect of
@@ -1393,7 +1582,7 @@
 an example of an interactive <b>pcre2test</b> run.
 <pre>
   $ pcre2test
-  PCRE2 version 9.00 2014-05-10
+  PCRE2 version 10.22 2016-07-29
 
     re&#62; /^abc(\d+)/
   data&#62; abc123
@@ -1420,7 +1609,7 @@
 If the strings contain any non-printing characters, they are output as \xhh
 escapes if the value is less than 256 and UTF mode is not set. Otherwise they
 are output as \x{hh...} escapes. See below for the definition of non-printing
-characters. If the <b>/aftertext</b> modifier is set, the output for substring
+characters. If the <b>aftertext</b> modifier is set, the output for substring
 0 is followed by the the rest of the subject string, identified by "0+" like
 this:
 <pre>
@@ -1508,28 +1697,14 @@
 For further information about partial matching, see the
 <a href="pcre2partial.html"><b>pcre2partial</b></a>
 documentation.
-</P>
+<a name="callouts"></a></P>
 <br><a name="SEC16" href="#TOC1">CALLOUTS</a><br>
 <P>
 If the pattern contains any callout requests, <b>pcre2test</b>'s callout
-function is called during matching unless <b>callout_none</b> is specified.
-This works with both matching functions.
-</P>
-<P>
-The callout function in <b>pcre2test</b> returns zero (carry on matching) by
-default, but you can use a <b>callout_fail</b> modifier in a subject line (as
-described above) to change this and other parameters of the callout.
-</P>
-<P>
-Inserting callouts can be helpful when using <b>pcre2test</b> to check
-complicated regular expressions. For further information about callouts, see
-the
-<a href="pcre2callout.html"><b>pcre2callout</b></a>
-documentation.
-</P>
-<P>
-The output for callouts with numerical arguments and those with string
-arguments is slightly different.
+function is called during matching unless <b>callout_none</b> is specified. This
+works with both matching functions, and with JIT, though there are some
+differences in behaviour. The output for callouts with numerical arguments and
+those with string arguments is slightly different.
 </P>
 <br><b>
 Callouts with numerical arguments
@@ -1551,7 +1726,7 @@
 </P>
 <P>
 Callouts numbered 255 are assumed to be automatic callouts, inserted as a
-result of the <b>/auto_callout</b> pattern modifier. In this case, instead of
+result of the <b>auto_callout</b> pattern modifier. In this case, instead of
 showing the callout number, the offset in the pattern, preceded by a plus, is
 output. For example:
 <pre>
@@ -1604,6 +1779,107 @@
 
 </PRE>
 </P>
+<br><b>
+Callout modifiers
+</b><br>
+<P>
+The callout function in <b>pcre2test</b> returns zero (carry on matching) by
+default, but you can use a <b>callout_fail</b> modifier in a subject line to
+change this and other parameters of the callout (see below).
+</P>
+<P>
+If the <b>callout_capture</b> modifier is set, the current captured groups are
+output when a callout occurs. This is useful only for non-DFA matching, as
+<b>pcre2_dfa_match()</b> does not support capturing, so no captures are ever
+shown.
+</P>
+<P>
+The normal callout output, showing the callout number or pattern offset (as
+described above) is suppressed if the <b>callout_no_where</b> modifier is set.
+</P>
+<P>
+When using the interpretive matching function <b>pcre2_match()</b> without JIT,
+setting the <b>callout_extra</b> modifier causes additional output from
+<b>pcre2test</b>'s callout function to be generated. For the first callout in a
+match attempt at a new starting position in the subject, "New match attempt" is
+output. If there has been a backtrack since the last callout (or start of
+matching if this is the first callout), "Backtrack" is output, followed by "No
+other matching paths" if the backtrack ended the previous match attempt. For
+example:
+<pre>
+   re&#62; /(a+)b/auto_callout,no_start_optimize,no_auto_possess
+  data&#62; aac\=callout_extra
+  New match attempt
+  ---&#62;aac
+   +0 ^       (
+   +1 ^       a+
+   +3 ^ ^     )
+   +4 ^ ^     b
+  Backtrack
+  ---&#62;aac
+   +3 ^^      )
+   +4 ^^      b
+  Backtrack
+  No other matching paths
+  New match attempt
+  ---&#62;aac
+   +0  ^      (
+   +1  ^      a+
+   +3  ^^     )
+   +4  ^^     b
+  Backtrack
+  No other matching paths
+  New match attempt
+  ---&#62;aac
+   +0   ^     (
+   +1   ^     a+
+  Backtrack
+  No other matching paths
+  New match attempt
+  ---&#62;aac
+   +0    ^    (
+   +1    ^    a+
+  No match
+</pre>
+Notice that various optimizations must be turned off if you want all possible
+matching paths to be scanned. If <b>no_start_optimize</b> is not used, there is
+an immediate "no match", without any callouts, because the starting
+optimization fails to find "b" in the subject, which it knows must be present
+for any match. If <b>no_auto_possess</b> is not used, the "a+" item is turned
+into "a++", which reduces the number of backtracks.
+</P>
+<P>
+The <b>callout_extra</b> modifier has no effect if used with the DFA matching
+function, or with JIT.
+</P>
+<br><b>
+Return values from callouts
+</b><br>
+<P>
+The default return from the callout function is zero, which allows matching to
+continue. The <b>callout_fail</b> modifier can be given one or two numbers. If
+there is only one number, 1 is returned instead of 0 (causing matching to
+backtrack) when a callout of that number is reached. If two numbers (&#60;n&#62;:&#60;m&#62;)
+are given, 1 is returned when callout &#60;n&#62; is reached and there have been at
+least &#60;m&#62; callouts. The <b>callout_error</b> modifier is similar, except that
+PCRE2_ERROR_CALLOUT is returned, causing the entire matching process to be
+aborted. If both these modifiers are set for the same callout number,
+<b>callout_error</b> takes precedence. Note that callouts with string arguments
+are always given the number zero.
+</P>
+<P>
+The <b>callout_data</b> modifier can be given an unsigned or a negative number.
+This is set as the "user data" that is passed to the matching function, and
+passed back when the callout function is invoked. Any value other than zero is
+used as a return from <b>pcre2test</b>'s callout function.
+</P>
+<P>
+Inserting callouts can be helpful when using <b>pcre2test</b> to check
+complicated regular expressions. For further information about callouts, see
+the
+<a href="pcre2callout.html"><b>pcre2callout</b></a>
+documentation.
+</P>
 <br><a name="SEC17" href="#TOC1">NON-PRINTING CHARACTERS</a><br>
 <P>
 When <b>pcre2test</b> is outputting text in the compiled version of a pattern,
@@ -1613,7 +1889,7 @@
 <P>
 When <b>pcre2test</b> is outputting text that is a matched part of a subject
 string, it behaves in the same way, unless a different locale has been set for
-the pattern (using the <b>/locale</b> modifier). In this case, the
+the pattern (using the <b>locale</b> modifier). In this case, the
 <b>isprint()</b> function is used to distinguish printing and non-printing
 characters.
 <a name="saverestore"></a></P>
@@ -1706,9 +1982,9 @@
 </P>
 <br><a name="SEC21" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 06 July 2016
+Last updated: 21 December 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/html/pcre2unicode.html b/dist2/doc/html/pcre2unicode.html
index 6ca367f..448a221 100644
--- a/dist2/doc/html/pcre2unicode.html
+++ b/dist2/doc/html/pcre2unicode.html
@@ -47,7 +47,7 @@
 documentation. Only the short names for properties are supported. For example,
 \p{L} matches a letter. Its Perl synonym, \p{Letter}, is not supported.
 Furthermore, in Perl, many properties may optionally be prefixed by "Is", for
-compatibility with Perl 5.6. PCRE does not support this.
+compatibility with Perl 5.6. PCRE2 does not support this.
 </P>
 <br><b>
 WIDE CHARACTERS AND UTF MODES
@@ -109,10 +109,15 @@
 \H, \v, and \V) do match all the appropriate Unicode characters, whether or
 not PCRE2_UCP is set.
 </P>
+<br><b>
+CASE-EQUIVALENCE IN UTF MODES
+</b><br>
 <P>
-Case-insensitive matching in UTF mode makes use of Unicode properties. A few
-Unicode characters such as Greek sigma have more than two codepoints that are
-case-equivalent, and these are treated as such.
+Case-insensitive matching in a UTF mode makes use of Unicode properties except
+for characters whose code points are less than 128 and that have at most two
+case-equivalent values. For these, a direct table lookup is used for speed. A
+few Unicode characters such as Greek sigma have more than two codepoints that
+are case-equivalent, and these are treated as such.
 </P>
 <br><b>
 VALIDITY OF UTF STRINGS
@@ -173,6 +178,15 @@
 <P>
 If you pass an invalid UTF string when PCRE2_NO_UTF_CHECK is set, the result
 is undefined and your program may crash or loop indefinitely.
+</P>
+<P>
+Note that setting PCRE2_NO_UTF_CHECK at compile time does not disable the error
+that is given if an escape sequence for an invalid Unicode code point is
+encountered in the pattern. If you want to allow escape sequences such as
+\x{d800} (a surrogate code point) you can set the
+PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES extra option. However, this is possible
+only in UTF-8 and UTF-32 modes, because these values are not representable in
+UTF-16.
 <a name="utf8strings"></a></P>
 <br><b>
 Errors in UTF-8 strings
@@ -280,9 +294,9 @@
 REVISION
 </b><br>
 <P>
-Last updated: 03 July 2016
+Last updated: 17 May 2017
 <br>
-Copyright &copy; 1997-2016 University of Cambridge.
+Copyright &copy; 1997-2017 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
diff --git a/dist2/doc/index.html.src b/dist2/doc/index.html.src
index 703c298..b9393d9 100644
--- a/dist2/doc/index.html.src
+++ b/dist2/doc/index.html.src
@@ -35,6 +35,9 @@
 <tr><td><a href="pcre2compat.html">pcre2compat</a></td>
     <td>&nbsp;&nbsp;Compability with Perl</td></tr>
 
+<tr><td><a href="pcre2convert.html">pcre2convert</a></td>
+    <td>&nbsp;&nbsp;Experimental foreign pattern conversion functions</td></tr>
+
 <tr><td><a href="pcre2demo.html">pcre2demo</a></td>
     <td>&nbsp;&nbsp;A demonstration C program that uses the PCRE2 library</td></tr>
 
@@ -68,9 +71,6 @@
 <tr><td><a href="pcre2serialize.html">pcre2serialize</a></td>
     <td>&nbsp;&nbsp;Serializing functions for saving precompiled patterns</td></tr>
 
-<tr><td><a href="pcre2stack.html">pcre2stack</a></td>
-    <td>&nbsp;&nbsp;Discussion of PCRE2's stack usage</td></tr>
-
 <tr><td><a href="pcre2syntax.html">pcre2syntax</a></td>
     <td>&nbsp;&nbsp;Syntax quick-reference summary</td></tr>
 
@@ -94,6 +94,9 @@
 <tr><td><a href="pcre2_code_copy.html">pcre2_code_copy</a></td>
     <td>&nbsp;&nbsp;Copy a compiled pattern</td></tr>
 
+<tr><td><a href="pcre2_code_copy_with_tables.html">pcre2_code_copy_with_tables</a></td>
+    <td>&nbsp;&nbsp;Copy a compiled pattern and its character tables</td></tr>
+
 <tr><td><a href="pcre2_code_free.html">pcre2_code_free</a></td>
     <td>&nbsp;&nbsp;Free a compiled pattern</td></tr>
 
@@ -112,6 +115,18 @@
 <tr><td><a href="pcre2_config.html">pcre2_config</a></td>
     <td>&nbsp;&nbsp;Show build-time configuration options</td></tr>
 
+<tr><td><a href="pcre2_convert_context_copy.html">pcre2_convert_context_copy</a></td>
+    <td>&nbsp;&nbsp;Copy a convert context</td></tr>
+
+<tr><td><a href="pcre2_convert_context_create.html">pcre2_convert_context_create</a></td>
+    <td>&nbsp;&nbsp;Create a convert context</td></tr>
+
+<tr><td><a href="pcre2_convert_context_free.html">pcre2_convert_context_free</a></td>
+    <td>&nbsp;&nbsp;Free a convert context</td></tr>
+
+<tr><td><a href="pcre2_converted_pattern_free.html">pcre2_converted_pattern_free</a></td>
+    <td>&nbsp;&nbsp;Free converted foreign pattern</td></tr>
+
 <tr><td><a href="pcre2_dfa_match.html">pcre2_dfa_match</a></td>
     <td>&nbsp;&nbsp;Match a compiled pattern to a subject string
     (DFA algorithm; <i>not</i> Perl compatible)</td></tr>
@@ -183,6 +198,9 @@
 <tr><td><a href="pcre2_match_data_free.html">pcre2_match_data_free</a></td>
     <td>&nbsp;&nbsp;Free a match data block</td></tr>
 
+<tr><td><a href="pcre2_pattern_convert.html">pcre2_pattern_convert</a></td>
+    <td>&nbsp;&nbsp;Experimental foreign pattern converter</td></tr>
+
 <tr><td><a href="pcre2_pattern_info.html">pcre2_pattern_info</a></td>
     <td>&nbsp;&nbsp;Extract information about a pattern</td></tr>
 
@@ -207,9 +225,24 @@
 <tr><td><a href="pcre2_set_character_tables.html">pcre2_set_character_tables</a></td>
     <td>&nbsp;&nbsp;Set character tables</td></tr>
 
+<tr><td><a href="pcre2_set_compile_extra_options.html">pcre2_set_compile_extra_options</a></td>
+    <td>&nbsp;&nbsp;Set compile time extra options</td></tr>
+
 <tr><td><a href="pcre2_set_compile_recursion_guard.html">pcre2_set_compile_recursion_guard</a></td>
     <td>&nbsp;&nbsp;Set up a compile recursion guard function</td></tr>
 
+<tr><td><a href="pcre2_set_depth_limit.html">pcre2_set_depth_limit</a></td>
+    <td>&nbsp;&nbsp;Set the match backtracking depth limit</td></tr>
+
+<tr><td><a href="pcre2_set_glob_escape.html">pcre2_set_glob_escape</a></td>
+    <td>&nbsp;&nbsp;Set glob escape character</td></tr>
+
+<tr><td><a href="pcre2_set_glob_separator.html">pcre2_set_glob_separator</a></td>
+    <td>&nbsp;&nbsp;Set glob separator character</td></tr>
+
+<tr><td><a href="pcre2_set_heap_limit.html">pcre2_set_heap_limit</a></td>
+    <td>&nbsp;&nbsp;Set the match backtracking heap limit</td></tr>
+
 <tr><td><a href="pcre2_set_match_limit.html">pcre2_set_match_limit</a></td>
     <td>&nbsp;&nbsp;Set the match limit</td></tr>
 
@@ -226,10 +259,10 @@
     <td>&nbsp;&nbsp;Set the parentheses nesting limit</td></tr>
 
 <tr><td><a href="pcre2_set_recursion_limit.html">pcre2_set_recursion_limit</a></td>
-    <td>&nbsp;&nbsp;Set the match recursion limit</td></tr>
+    <td>&nbsp;&nbsp;Obsolete: use pcre2_set_depth_limit</td></tr>
 
 <tr><td><a href="pcre2_set_recursion_memory_management.html">pcre2_set_recursion_memory_management</a></td>
-    <td>&nbsp;&nbsp;Set match recursion memory management</td></tr>
+    <td>&nbsp;&nbsp;Obsolete function that (from 10.30 onwards) does nothing</td></tr>
 
 <tr><td><a href="pcre2_substitute.html">pcre2_substitute</a></td>
     <td>&nbsp;&nbsp;Match a compiled pattern to a subject string and do
diff --git a/dist2/doc/pcre2.3 b/dist2/doc/pcre2.3
index 9a84ce3..83a7655 100644
--- a/dist2/doc/pcre2.3
+++ b/dist2/doc/pcre2.3
@@ -1,4 +1,4 @@
-.TH PCRE2 3 "16 October 2015" "PCRE2 10.21"
+.TH PCRE2 3 "01 April 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH INTRODUCTION
@@ -104,7 +104,7 @@
 One way of guarding against this possibility is to use the
 \fBpcre2_pattern_info()\fP function to check the compiled pattern's options for
 PCRE2_UTF. Alternatively, you can set the PCRE2_NEVER_UTF option when calling
-\fBpcre2_compile()\fP. This causes an compile time error if a pattern contains
+\fBpcre2_compile()\fP. This causes a compile time error if the pattern contains
 a UTF-setting sequence.
 .P
 The use of Unicode properties for character types such as \ed can also be
@@ -130,7 +130,8 @@
 .\" HREF
 \fBpcre2api\fP
 .\"
-page.
+page. There is a similar function called \fBpcre2_set_depth_limit()\fP that can
+be used to restrict the amount of memory that is used.
 .
 .
 .SH "USER DOCUMENTATION"
@@ -163,7 +164,6 @@
   pcre2perform       discussion of performance issues
   pcre2posix         the POSIX-compatible C API for the 8-bit library
   pcre2sample        discussion of the pcre2demo program
-  pcre2stack         discussion of stack usage
   pcre2syntax        quick syntax reference
   pcre2test          description of the \fBpcre2test\fP command
   pcre2unicode       discussion of Unicode and UTF support
@@ -189,6 +189,6 @@
 .rs
 .sp
 .nf
-Last updated: 16 October 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 01 April 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2.txt b/dist2/doc/pcre2.txt
index 8f4e8a1..79d94e3 100644
--- a/dist2/doc/pcre2.txt
+++ b/dist2/doc/pcre2.txt
@@ -89,8 +89,8 @@
        One  way  of guarding against this possibility is to use the pcre2_pat-
        tern_info() function  to  check  the  compiled  pattern's  options  for
        PCRE2_UTF.  Alternatively,  you can set the PCRE2_NEVER_UTF option when
-       calling pcre2_compile(). This causes an compile time error if a pattern
-       contains a UTF-setting sequence.
+       calling pcre2_compile(). This causes a compile time error if  the  pat-
+       tern contains a UTF-setting sequence.
 
        The  use  of Unicode properties for character types such as \d can also
        be enabled from within the pattern, by specifying "(*UCP)".  This  fea-
@@ -112,7 +112,9 @@
        has a very large search tree against a string that  will  never  match.
        Nested  unlimited repeats in a pattern are a common example. PCRE2 pro-
        vides some protection against  this:  see  the  pcre2_set_match_limit()
-       function in the pcre2api page.
+       function  in  the  pcre2api  page.  There  is a similar function called
+       pcre2_set_depth_limit() that can be used to restrict the amount of mem-
+       ory that is used.
 
 
 USER DOCUMENTATION
@@ -144,7 +146,6 @@
          pcre2perform       discussion of performance issues
          pcre2posix         the POSIX-compatible C API for the 8-bit library
          pcre2sample        discussion of the pcre2demo program
-         pcre2stack         discussion of stack usage
          pcre2syntax        quick syntax reference
          pcre2test          description of the pcre2test command
          pcre2unicode       discussion of Unicode and UTF support
@@ -166,8 +167,8 @@
 
 REVISION
 
-       Last updated: 16 October 2015
-       Copyright (c) 1997-2015 University of Cambridge.
+       Last updated: 01 April 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -180,9 +181,9 @@
 
        #include <pcre2.h>
 
-       PCRE2  is  a  new API for PCRE. This document contains a description of
-       all its functions. See the pcre2 document for an overview  of  all  the
-       PCRE2 documentation.
+       PCRE2  is  a  new API for PCRE, starting at release 10.0. This document
+       contains a description of all its native functions. See the pcre2 docu-
+       ment for an overview of all the PCRE2 documentation.
 
 
 PCRE2 NATIVE API BASIC FUNCTIONS
@@ -252,6 +253,9 @@
        int pcre2_set_character_tables(pcre2_compile_context *ccontext,
          const unsigned char *tables);
 
+       int pcre2_set_compile_extra_options(pcre2_compile_context *ccontext,
+         uint32_t extra_options);
+
        int pcre2_set_max_pattern_length(pcre2_compile_context *ccontext,
          PCRE2_SIZE value);
 
@@ -279,19 +283,17 @@
          int (*callout_function)(pcre2_callout_block *, void *),
          void *callout_data);
 
-       int pcre2_set_match_limit(pcre2_match_context *mcontext,
-         uint32_t value);
-
        int pcre2_set_offset_limit(pcre2_match_context *mcontext,
          PCRE2_SIZE value);
 
-       int pcre2_set_recursion_limit(pcre2_match_context *mcontext,
+       int pcre2_set_heap_limit(pcre2_match_context *mcontext,
          uint32_t value);
 
-       int pcre2_set_recursion_memory_management(
-         pcre2_match_context *mcontext,
-         void *(*private_malloc)(PCRE2_SIZE, void *),
-         void (*private_free)(void *, void *), void *memory_data);
+       int pcre2_set_match_limit(pcre2_match_context *mcontext,
+         uint32_t value);
+
+       int pcre2_set_depth_limit(pcre2_match_context *mcontext,
+         uint32_t value);
 
 
 PCRE2 NATIVE API STRING EXTRACTION FUNCTIONS
@@ -379,6 +381,8 @@
 
        pcre2_code *pcre2_code_copy(const pcre2_code *code);
 
+       pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *code);
+
        int pcre2_get_error_message(int errorcode, PCRE2_UCHAR *buffer,
          PCRE2_SIZE bufflen);
 
@@ -393,19 +397,64 @@
        int pcre2_config(uint32_t what, void *where);
 
 
+PCRE2 NATIVE API OBSOLETE FUNCTIONS
+
+       int pcre2_set_recursion_limit(pcre2_match_context *mcontext,
+         uint32_t value);
+
+       int pcre2_set_recursion_memory_management(
+         pcre2_match_context *mcontext,
+         void *(*private_malloc)(PCRE2_SIZE, void *),
+         void (*private_free)(void *, void *), void *memory_data);
+
+       These  functions became obsolete at release 10.30 and are retained only
+       for backward compatibility. They should not be used in  new  code.  The
+       first  is  replaced by pcre2_set_depth_limit(); the second is no longer
+       needed and has no effect (it always returns zero).
+
+
+PCRE2 EXPERIMENTAL PATTERN CONVERSION FUNCTIONS
+
+       pcre2_convert_context *pcre2_convert_context_create(
+         pcre2_general_context *gcontext);
+
+       pcre2_convert_context *pcre2_convert_context_copy(
+         pcre2_convert_context *cvcontext);
+
+       void pcre2_convert_context_free(pcre2_convert_context *cvcontext);
+
+       int pcre2_set_glob_escape(pcre2_convert_context *cvcontext,
+         uint32_t escape_char);
+
+       int pcre2_set_glob_separator(pcre2_convert_context *cvcontext,
+         uint32_t separator_char);
+
+       int pcre2_pattern_convert(PCRE2_SPTR pattern, PCRE2_SIZE length,
+         uint32_t options, PCRE2_UCHAR **buffer,
+         PCRE2_SIZE *blength, pcre2_convert_context *cvcontext);
+
+       void pcre2_converted_pattern_free(PCRE2_UCHAR *converted_pattern);
+
+       These functions provide a way of  converting  non-PCRE2  patterns  into
+       patterns  that  can  be  processed by pcre2_compile(). This facility is
+       experimental and may be changed in future releases. At present, "globs"
+       and  POSIX  basic  and  extended patterns can be converted. Details are
+       given in the pcre2convert documentation.
+
+
 PCRE2 8-BIT, 16-BIT, AND 32-BIT LIBRARIES
 
-       There  are  three PCRE2 libraries, supporting 8-bit, 16-bit, and 32-bit
-       code units, respectively. However,  there  is  just  one  header  file,
-       pcre2.h.   This  contains the function prototypes and other definitions
+       There are three PCRE2 libraries, supporting 8-bit, 16-bit,  and  32-bit
+       code  units,  respectively.  However,  there  is  just one header file,
+       pcre2.h.  This contains the function prototypes and  other  definitions
        for all three libraries. One, two, or all three can be installed simul-
-       taneously.  On  Unix-like  systems the libraries are called libpcre2-8,
+       taneously. On Unix-like systems the libraries  are  called  libpcre2-8,
        libpcre2-16, and libpcre2-32, and they can also co-exist with the orig-
        inal PCRE libraries.
 
-       Character  strings are passed to and from a PCRE2 library as a sequence
-       of unsigned integers in code units  of  the  appropriate  width.  Every
-       PCRE2  function  comes  in three different forms, one for each library,
+       Character strings are passed to and from a PCRE2 library as a  sequence
+       of  unsigned  integers  in  code  units of the appropriate width. Every
+       PCRE2 function comes in three different forms, one  for  each  library,
        for example:
 
          pcre2_compile_8()
@@ -417,72 +466,79 @@
          PCRE2_UCHAR8, PCRE2_UCHAR16, PCRE2_UCHAR32
          PCRE2_SPTR8,  PCRE2_SPTR16,  PCRE2_SPTR32
 
-       The UCHAR types define unsigned code units of the  appropriate  widths.
-       For  example,  PCRE2_UCHAR16 is usually defined as `uint16_t'. The SPTR
-       types are constant pointers to the equivalent  UCHAR  types,  that  is,
+       The  UCHAR  types define unsigned code units of the appropriate widths.
+       For example, PCRE2_UCHAR16 is usually defined as `uint16_t'.  The  SPTR
+       types  are  constant  pointers  to the equivalent UCHAR types, that is,
        they are pointers to vectors of unsigned code units.
 
-       Many  applications use only one code unit width. For their convenience,
+       Many applications use only one code unit width. For their  convenience,
        macros are defined whose names are the generic forms such as pcre2_com-
-       pile()  and  PCRE2_SPTR.  These  macros  use  the  value  of  the macro
-       PCRE2_CODE_UNIT_WIDTH to generate the appropriate width-specific  func-
+       pile() and  PCRE2_SPTR.  These  macros  use  the  value  of  the  macro
+       PCRE2_CODE_UNIT_WIDTH  to generate the appropriate width-specific func-
        tion and macro names.  PCRE2_CODE_UNIT_WIDTH is not defined by default.
-       An application must define it to be  8,  16,  or  32  before  including
+       An  application  must  define  it  to  be 8, 16, or 32 before including
        pcre2.h in order to make use of the generic names.
 
-       Applications  that use more than one code unit width can be linked with
-       more than one PCRE2 library, but must define  PCRE2_CODE_UNIT_WIDTH  to
-       be  0  before  including pcre2.h, and then use the real function names.
-       Any code that is to be included in an environment where  the  value  of
-       PCRE2_CODE_UNIT_WIDTH  is  unknown  should  also  use the real function
+       Applications that use more than one code unit width can be linked  with
+       more  than  one PCRE2 library, but must define PCRE2_CODE_UNIT_WIDTH to
+       be 0 before including pcre2.h, and then use the  real  function  names.
+       Any  code  that  is to be included in an environment where the value of
+       PCRE2_CODE_UNIT_WIDTH is unknown should  also  use  the  real  function
        names. (Unfortunately, it is not possible in C code to save and restore
        the value of a macro.)
 
-       If  PCRE2_CODE_UNIT_WIDTH  is  not  defined before including pcre2.h, a
+       If PCRE2_CODE_UNIT_WIDTH is not defined  before  including  pcre2.h,  a
        compiler error occurs.
 
-       When using multiple libraries in an application,  you  must  take  care
-       when  processing  any  particular  pattern to use only functions from a
-       single library.  For example, if you want to run a match using  a  pat-
-       tern  that  was  compiled  with pcre2_compile_16(), you must do so with
-       pcre2_match_16(), not pcre2_match_8().
+       When  using  multiple  libraries  in an application, you must take care
+       when processing any particular pattern to use  only  functions  from  a
+       single  library.   For example, if you want to run a match using a pat-
+       tern that was compiled with pcre2_compile_16(), you  must  do  so  with
+       pcre2_match_16(), not pcre2_match_8() or pcre2_match_32().
 
-       In the function summaries above, and in the rest of this  document  and
-       other  PCRE2  documents,  functions  and data types are described using
-       their generic names, without the 8, 16, or 32 suffix.
+       In  the  function summaries above, and in the rest of this document and
+       other PCRE2 documents, functions and data  types  are  described  using
+       their generic names, without the _8, _16, or _32 suffix.
 
 
 PCRE2 API OVERVIEW
 
-       PCRE2 has its own native API, which  is  described  in  this  document.
+       PCRE2  has  its  own  native  API, which is described in this document.
        There are also some wrapper functions for the 8-bit library that corre-
-       spond to the POSIX regular expression API, but they do not give  access
-       to all the functionality. They are described in the pcre2posix documen-
-       tation. Both these APIs define a set of C function calls.
+       spond  to the POSIX regular expression API, but they do not give access
+       to all the functionality of PCRE2. They are described in the pcre2posix
+       documentation. Both these APIs define a set of C function calls.
 
-       The native API C data types, function prototypes,  option  values,  and
-       error codes are defined in the header file pcre2.h, which contains def-
-       initions of PCRE2_MAJOR and PCRE2_MINOR, the major  and  minor  release
-       numbers  for the library. Applications can use these to include support
+       The  native  API  C data types, function prototypes, option values, and
+       error codes are defined in the header file pcre2.h, which also contains
+       definitions of PCRE2_MAJOR and PCRE2_MINOR, the major and minor release
+       numbers for the library. Applications can use these to include  support
        for different releases of PCRE2.
 
        In a Windows environment, if you want to statically link an application
-       program  against  a non-dll PCRE2 library, you must define PCRE2_STATIC
+       program against a non-dll PCRE2 library, you must  define  PCRE2_STATIC
        before including pcre2.h.
 
-       The functions pcre2_compile(), and pcre2_match() are used for compiling
-       and  matching regular expressions in a Perl-compatible manner. A sample
+       The  functions pcre2_compile() and pcre2_match() are used for compiling
+       and matching regular expressions in a Perl-compatible manner. A  sample
        program that demonstrates the simplest way of using them is provided in
        the file called pcre2demo.c in the PCRE2 source distribution. A listing
-       of this program is  given  in  the  pcre2demo  documentation,  and  the
+       of  this  program  is  given  in  the  pcre2demo documentation, and the
        pcre2sample documentation describes how to compile and run it.
 
-       Just-in-time  compiler support is an optional feature of PCRE2 that can
-       be built in appropriate hardware environments. It greatly speeds up the
-       matching  performance of many patterns. Programs can request that it be
-       used if available, by calling pcre2_jit_compile() after a  pattern  has
-       been successfully compiled by pcre2_compile(). This does nothing if JIT
-       support is not available.
+       The compiling and matching functions recognize various options that are
+       passed as bits in an options argument. There are also some more compli-
+       cated  parameters  such  as  custom  memory  management  functions  and
+       resource  limits  that  are passed in "contexts" (which are just memory
+       blocks, described below). Simple applications do not need to  make  use
+       of contexts.
+
+       Just-in-time  (JIT)  compiler  support  is an optional feature of PCRE2
+       that can be built in  appropriate  hardware  environments.  It  greatly
+       speeds  up  the  matching  performance  of  many patterns. Programs can
+       request that it be used if  available  by  calling  pcre2_jit_compile()
+       after a pattern has been successfully compiled by pcre2_compile(). This
+       does nothing if JIT support is not available.
 
        More complicated programs might need to  make  use  of  the  specialist
        functions    pcre2_jit_stack_create(),    pcre2_jit_stack_free(),   and
@@ -491,20 +547,21 @@
 
        JIT matching is automatically used by pcre2_match() if it is available,
        unless the PCRE2_NO_JIT option is set. There is also a direct interface
-       for  JIT  matching,  which gives improved performance. The JIT-specific
-       functions are discussed in the pcre2jit documentation.
+       for  JIT  matching,  which gives improved performance at the expense of
+       less sanity checking. The JIT-specific functions are discussed  in  the
+       pcre2jit documentation.
 
-       A second matching function, pcre2_dfa_match(), which is  not  Perl-com-
-       patible,  is  also  provided.  This  uses a different algorithm for the
-       matching. The alternative algorithm finds all possible  matches  (at  a
-       given  point  in  the subject), and scans the subject just once (unless
-       there are lookbehind assertions).  However,  this  algorithm  does  not
-       return  captured  substrings.  A  description of the two matching algo-
-       rithms  and  their  advantages  and  disadvantages  is  given  in   the
-       pcre2matching    documentation.   There   is   no   JIT   support   for
+       A  second  matching function, pcre2_dfa_match(), which is not Perl-com-
+       patible, is also provided. This uses  a  different  algorithm  for  the
+       matching.  The  alternative  algorithm finds all possible matches (at a
+       given point in the subject), and scans the subject  just  once  (unless
+       there  are  lookaround  assertions).  However,  this algorithm does not
+       return captured substrings. A description of  the  two  matching  algo-
+       rithms   and  their  advantages  and  disadvantages  is  given  in  the
+       pcre2matching   documentation.   There   is   no   JIT   support    for
        pcre2_dfa_match().
 
-       In addition to the main compiling and  matching  functions,  there  are
+       In  addition  to  the  main compiling and matching functions, there are
        convenience functions for extracting captured substrings from a subject
        string that has been matched by pcre2_match(). They are:
 
@@ -518,74 +575,74 @@
          pcre2_substring_nametable_scan()
          pcre2_substring_number_from_name()
 
-       pcre2_substring_free() and pcre2_substring_list_free()  are  also  pro-
-       vided, to free the memory used for extracted strings.
+       pcre2_substring_free()  and  pcre2_substring_list_free()  are also pro-
+       vided, to free memory used for extracted strings.
 
-       The  function  pcre2_substitute()  can be called to match a pattern and
-       return a copy of the subject string with substitutions for  parts  that
+       The function pcre2_substitute() can be called to match  a  pattern  and
+       return  a  copy of the subject string with substitutions for parts that
        were matched.
 
-       Functions  whose  names begin with pcre2_serialize_ are used for saving
+       Functions whose names begin with pcre2_serialize_ are used  for  saving
        compiled patterns on disc or elsewhere, and reloading them later.
 
-       Finally, there are functions for finding out information about  a  com-
-       piled  pattern  (pcre2_pattern_info()) and about the configuration with
+       Finally,  there  are functions for finding out information about a com-
+       piled pattern (pcre2_pattern_info()) and about the  configuration  with
        which PCRE2 was built (pcre2_config()).
 
-       Functions with names ending with _free() are used  for  freeing  memory
-       blocks  of  various  sorts.  In all cases, if one of these functions is
+       Functions  with  names  ending with _free() are used for freeing memory
+       blocks of various sorts. In all cases, if one  of  these  functions  is
        called with a NULL argument, it does nothing.
 
 
 STRING LENGTHS AND OFFSETS
 
-       The PCRE2 API uses string lengths and  offsets  into  strings  of  code
-       units  in  several  places. These values are always of type PCRE2_SIZE,
-       which is an unsigned integer type, currently always defined as  size_t.
-       The  largest  value  that  can  be  stored  in  such  a  type  (that is
-       ~(PCRE2_SIZE)0) is reserved as a special indicator for  zero-terminated
-       strings  and  unset offsets.  Therefore, the longest string that can be
+       The  PCRE2  API  uses  string  lengths and offsets into strings of code
+       units in several places. These values are always  of  type  PCRE2_SIZE,
+       which  is an unsigned integer type, currently always defined as size_t.
+       The largest  value  that  can  be  stored  in  such  a  type  (that  is
+       ~(PCRE2_SIZE)0)  is reserved as a special indicator for zero-terminated
+       strings and unset offsets.  Therefore, the longest string that  can  be
        handled is one less than this maximum.
 
 
 NEWLINES
 
        PCRE2 supports five different conventions for indicating line breaks in
-       strings:  a  single  CR (carriage return) character, a single LF (line-
+       strings: a single CR (carriage return) character, a  single  LF  (line-
        feed) character, the two-character sequence CRLF, any of the three pre-
-       ceding,  or any Unicode newline sequence. The Unicode newline sequences
-       are the three just mentioned, plus the single characters  VT  (vertical
+       ceding, or any Unicode newline sequence. The Unicode newline  sequences
+       are  the  three just mentioned, plus the single characters VT (vertical
        tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line
        separator, U+2028), and PS (paragraph separator, U+2029).
 
-       Each of the first three conventions is used by at least  one  operating
+       Each  of  the first three conventions is used by at least one operating
        system as its standard newline sequence. When PCRE2 is built, a default
-       can be specified.  The default default is LF, which is the  Unix  stan-
-       dard.  However, the newline convention can be changed by an application
+       can  be  specified.  The default default is LF, which is the Unix stan-
+       dard. However, the newline convention can be changed by an  application
        when calling pcre2_compile(), or it can be specified by special text at
        the start of the pattern itself; this overrides any other settings. See
        the pcre2pattern page for details of the special character sequences.
 
-       In the PCRE2 documentation the word "newline"  is  used  to  mean  "the
+       In  the  PCRE2  documentation  the  word "newline" is used to mean "the
        character or pair of characters that indicate a line break". The choice
-       of newline convention affects the handling of the dot, circumflex,  and
+       of  newline convention affects the handling of the dot, circumflex, and
        dollar metacharacters, the handling of #-comments in /x mode, and, when
-       CRLF is a recognized line ending sequence, the match position  advance-
+       CRLF  is a recognized line ending sequence, the match position advance-
        ment for a non-anchored pattern. There is more detail about this in the
        section on pcre2_match() options below.
 
-       The choice of newline convention does not affect the interpretation  of
+       The  choice of newline convention does not affect the interpretation of
        the \n or \r escape sequences, nor does it affect what \R matches; this
        has its own separate convention.
 
 
 MULTITHREADING
 
-       In a multithreaded application it is important to keep  thread-specific
-       data  separate  from data that can be shared between threads. The PCRE2
-       library code itself is thread-safe: it contains  no  static  or  global
-       variables.  The  API  is  designed to be fairly simple for non-threaded
-       applications while at the same time ensuring that multithreaded  appli-
+       In  a multithreaded application it is important to keep thread-specific
+       data separate from data that can be shared between threads.  The  PCRE2
+       library  code  itself  is  thread-safe: it contains no static or global
+       variables. The API is designed to be  fairly  simple  for  non-threaded
+       applications  while at the same time ensuring that multithreaded appli-
        cations can use it.
 
        There are several different blocks of data that are used to pass infor-
@@ -593,19 +650,19 @@
 
    The compiled pattern
 
-       A pointer to the compiled form of a pattern is  returned  to  the  user
+       A  pointer  to  the  compiled form of a pattern is returned to the user
        when pcre2_compile() is successful. The data in the compiled pattern is
-       fixed, and does not change when the pattern is matched.  Therefore,  it
-       is  thread-safe, that is, the same compiled pattern can be used by more
+       fixed,  and  does not change when the pattern is matched. Therefore, it
+       is thread-safe, that is, the same compiled pattern can be used by  more
        than one thread simultaneously. For example, an application can compile
        all its patterns at the start, before forking off multiple threads that
-       use them. However, if the just-in-time optimization  feature  is  being
-       used,  it  needs  separate  memory stack areas for each thread. See the
-       pcre2jit documentation for more details.
+       use  them.  However,  if the just-in-time (JIT) optimization feature is
+       being used, it needs separate memory stack areas for each  thread.  See
+       the pcre2jit documentation for more details.
 
-       In a more complicated situation, where patterns are compiled only  when
-       they  are  first needed, but are still shared between threads, pointers
-       to compiled patterns must be protected  from  simultaneous  writing  by
+       In  a more complicated situation, where patterns are compiled only when
+       they are first needed, but are still shared between  threads,  pointers
+       to  compiled  patterns  must  be protected from simultaneous writing by
        multiple threads, at least until a pattern has been compiled. The logic
        can be something like this:
 
@@ -618,16 +675,17 @@
          Release the lock
          Use pointer in pcre2_match()
 
-       Of course, testing for compilation errors should also  be  included  in
+       Of  course,  testing  for compilation errors should also be included in
        the code.
 
        If JIT is being used, but the JIT compilation is not being done immedi-
-       ately, (perhaps waiting to see if the pattern  is  used  often  enough)
+       ately,  (perhaps  waiting  to  see if the pattern is used often enough)
        similar logic is required. JIT compilation updates a pointer within the
-       compiled code block, so a thread must gain unique write access  to  the
-       pointer     before    calling    pcre2_jit_compile().    Alternatively,
-       pcre2_code_copy() can be used to obtain a private copy of the  compiled
-       code.
+       compiled  code  block, so a thread must gain unique write access to the
+       pointer    before    calling    pcre2_jit_compile().     Alternatively,
+       pcre2_code_copy()  or  pcre2_code_copy_with_tables()  can  be  used  to
+       obtain a private copy of the compiled code before calling the JIT  com-
+       piler.
 
    Context blocks
 
@@ -646,10 +704,10 @@
 
    Match blocks
 
-       The matching functions need a block of memory for working space and for
-       storing  the  results  of  a  match.  This includes details of what was
-       matched, as well as additional  information  such  as  the  name  of  a
-       (*MARK) setting. Each thread must provide its own copy of this memory.
+       The matching functions need a block of memory for storing  the  results
+       of a match. This includes details of what was matched, as well as addi-
+       tional information such as the name of a (*MARK) setting.  Each  thread
+       must provide its own copy of this memory.
 
 
 PCRE2 CONTEXTS
@@ -714,21 +772,22 @@
 
    The compile context
 
-       A compile context is required if you want to change the default  values
-       of any of the following compile-time parameters:
+       A compile context is required if you want to provide an external  func-
+       tion  for  stack  checking  during compilation or to change the default
+       values of any of the following compile-time parameters:
 
          What \R matches (Unicode newlines or CR, LF, CRLF only)
          PCRE2's character tables
          The newline character sequence
          The compile time nested parentheses limit
          The maximum length of the pattern string
-         An external function for stack checking
+         The extra options bits (none set by default)
 
-       A  compile context is also required if you are using custom memory man-
-       agement.  If none of these apply, just pass NULL as the  context  argu-
+       A compile context is also required if you are using custom memory  man-
+       agement.   If  none of these apply, just pass NULL as the context argu-
        ment of pcre2_compile().
 
-       A  compile context is created, copied, and freed by the following func-
+       A compile context is created, copied, and freed by the following  func-
        tions:
 
        pcre2_compile_context *pcre2_compile_context_create(
@@ -739,57 +798,75 @@
 
        void pcre2_compile_context_free(pcre2_compile_context *ccontext);
 
-       A compile context is created with default values  for  its  parameters.
+       A  compile  context  is created with default values for its parameters.
        These can be changed by calling the following functions, which return 0
        on success, or PCRE2_ERROR_BADDATA if invalid data is detected.
 
        int pcre2_set_bsr(pcre2_compile_context *ccontext,
          uint32_t value);
 
-       The value must be PCRE2_BSR_ANYCRLF, to specify that  \R  matches  only
-       CR,  LF,  or CRLF, or PCRE2_BSR_UNICODE, to specify that \R matches any
+       The  value  must  be PCRE2_BSR_ANYCRLF, to specify that \R matches only
+       CR, LF, or CRLF, or PCRE2_BSR_UNICODE, to specify that \R  matches  any
        Unicode line ending sequence. The value is used by the JIT compiler and
-       by   the   two   interpreted   matching  functions,  pcre2_match()  and
+       by  the  two  interpreted   matching   functions,   pcre2_match()   and
        pcre2_dfa_match().
 
        int pcre2_set_character_tables(pcre2_compile_context *ccontext,
          const unsigned char *tables);
 
-       The value must be the result of a  call  to  pcre2_maketables(),  whose
+       The  value  must  be  the result of a call to pcre2_maketables(), whose
        only argument is a general context. This function builds a set of char-
        acter tables in the current locale.
 
+       int pcre2_set_compile_extra_options(pcre2_compile_context *ccontext,
+         uint32_t extra_options);
+
+       As  PCRE2  has developed, almost all the 32 option bits that are avail-
+       able in the options argument of pcre2_compile() have been used  up.  To
+       avoid  running  out, the compile context contains a set of extra option
+       bits which are used for some newer, assumed rarer, options. This  func-
+       tion  sets  those bits. It always sets all the bits (either on or off).
+       It does not modify any existing  setting.  The  available  options  are
+       defined in the section entitled "Extra compile options" below.
+
        int pcre2_set_max_pattern_length(pcre2_compile_context *ccontext,
          PCRE2_SIZE value);
 
-       This sets a maximum length, in code units, for the pattern string  that
-       is  to  be  compiled.  If the pattern is longer, an error is generated.
-       This facility is provided so that  applications  that  accept  patterns
-       from  external sources can limit their size. The default is the largest
-       number that a PCRE2_SIZE variable can hold, which is effectively unlim-
-       ited.
+       This  sets a maximum length, in code units, for any pattern string that
+       is compiled with this context. If the pattern is longer,  an  error  is
+       generated.   This facility is provided so that applications that accept
+       patterns from external sources can limit their size. The default is the
+       largest  number  that  a  PCRE2_SIZE variable can hold, which is effec-
+       tively unlimited.
 
        int pcre2_set_newline(pcre2_compile_context *ccontext,
          uint32_t value);
 
        This specifies which characters or character sequences are to be recog-
-       nized as newlines. The value must be one of PCRE2_NEWLINE_CR  (carriage
+       nized  as newlines. The value must be one of PCRE2_NEWLINE_CR (carriage
        return only), PCRE2_NEWLINE_LF (linefeed only), PCRE2_NEWLINE_CRLF (the
-       two-character sequence CR followed by LF),  PCRE2_NEWLINE_ANYCRLF  (any
-       of the above), or PCRE2_NEWLINE_ANY (any Unicode newline sequence).
+       two-character  sequence  CR followed by LF), PCRE2_NEWLINE_ANYCRLF (any
+       of the above), PCRE2_NEWLINE_ANY (any  Unicode  newline  sequence),  or
+       PCRE2_NEWLINE_NUL (the NUL character, that is a binary zero).
 
-       When a pattern is compiled with the PCRE2_EXTENDED option, the value of
-       this parameter affects the recognition of white space and  the  end  of
-       internal comments starting with #. The value is saved with the compiled
-       pattern for subsequent use by the JIT compiler and by  the  two  inter-
-       preted matching functions, pcre2_match() and pcre2_dfa_match().
+       A pattern can override the value set in the compile context by starting
+       with a sequence such as (*CRLF). See the pcre2pattern page for details.
+
+       When   a   pattern   is   compiled   with   the    PCRE2_EXTENDED    or
+       PCRE2_EXTENDED_MORE option, the newline convention affects the recogni-
+       tion of white space and the end of internal comments starting  with  #.
+       The  value is saved with the compiled pattern for subsequent use by the
+       JIT  compiler  and  by  the   two   interpreted   matching   functions,
+       pcre2_match() and pcre2_dfa_match().
 
        int pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext,
          uint32_t value);
 
        This parameter ajusts the limit, set when PCRE2 is built (default 250),
        on the depth of parenthesis nesting in  a  pattern.  This  limit  stops
-       rogue patterns using up too much system stack when being compiled.
+       rogue  patterns using up too much system stack when being compiled. The
+       limit applies to parentheses of all kinds, not just capturing parenthe-
+       ses.
 
        int pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
          int (*guard_function)(uint32_t, void *), void *user_data);
@@ -797,31 +874,32 @@
        There  is at least one application that runs PCRE2 in threads with very
        limited system stack, where running out of stack is to  be  avoided  at
        all  costs. The parenthesis limit above cannot take account of how much
-       stack is actually available. For a finer  control,  you  can  supply  a
-       function  that  is  called whenever pcre2_compile() starts to compile a
-       parenthesized part of a pattern. This function  can  check  the  actual
-       stack size (or anything else that it wants to, of course).
+       stack is actually available during compilation. For  a  finer  control,
+       you  can  supply  a  function  that  is called whenever pcre2_compile()
+       starts to compile a parenthesized part of a pattern. This function  can
+       check  the  actual  stack  size  (or anything else that it wants to, of
+       course).
 
-       The  first  argument to the callout function gives the current depth of
-       nesting, and the second is user data that is set up by the  last  argu-
-       ment   of  pcre2_set_compile_recursion_guard().  The  callout  function
+       The first argument to the callout function gives the current  depth  of
+       nesting,  and  the second is user data that is set up by the last argu-
+       ment  of  pcre2_set_compile_recursion_guard().  The  callout   function
        should return zero if all is well, or non-zero to force an error.
 
    The match context
 
-       A match context is required if you want to change the default values of
-       any of the following match-time parameters:
+       A match context is required if you want to:
 
-         A callout function
-         The offset limit for matching an unanchored pattern
-         The limit for calling match() (see below)
-         The limit for calling match() recursively
+         Set up a callout function
+         Set an offset limit for matching an unanchored pattern
+         Change the limit on the amount of heap used when matching
+         Change the backtracking match limit
+         Change the backtracking depth limit
+         Set custom memory management specifically for the match
 
-       A match context is also required if you are using custom memory manage-
-       ment.  If none of these apply, just pass NULL as the  context  argument
-       of pcre2_match(), pcre2_dfa_match(), or pcre2_jit_match().
+       If  none  of  these  apply,  just  pass NULL as the context argument of
+       pcre2_match(), pcre2_dfa_match(), or pcre2_jit_match().
 
-       A  match  context  is created, copied, and freed by the following func-
+       A match context is created, copied, and freed by  the  following  func-
        tions:
 
        pcre2_match_context *pcre2_match_context_create(
@@ -832,7 +910,7 @@
 
        void pcre2_match_context_free(pcre2_match_context *mcontext);
 
-       A match context is created with  default  values  for  its  parameters.
+       A  match  context  is  created  with default values for its parameters.
        These can be changed by calling the following functions, which return 0
        on success, or PCRE2_ERROR_BADDATA if invalid data is detected.
 
@@ -840,120 +918,137 @@
          int (*callout_function)(pcre2_callout_block *, void *),
          void *callout_data);
 
-       This sets up a "callout" function, which PCRE2 will call  at  specified
-       points during a matching operation. Details are given in the pcre2call-
-       out documentation.
+       This sets up a "callout" function for PCRE2 to call at specified points
+       during a matching operation. Details are given in the pcre2callout doc-
+       umentation.
 
        int pcre2_set_offset_limit(pcre2_match_context *mcontext,
          PCRE2_SIZE value);
 
-       The offset_limit parameter limits how  far  an  unanchored  search  can
-       advance  in  the  subject string. The default value is PCRE2_UNSET. The
-       pcre2_match()     and      pcre2_dfa_match()      functions      return
-       PCRE2_ERROR_NOMATCH  if  a match with a starting point before or at the
-       given offset is not found. For example, if the pattern /abc/ is matched
-       against  "123abc"  with  an  offset  limit  less  than 3, the result is
-       PCRE2_ERROR_NO_MATCH.  A match can never be found  if  the  startoffset
-       argument of pcre2_match() or pcre2_dfa_match() is greater than the off-
-       set limit.
+       The  offset_limit  parameter  limits  how  far an unanchored search can
+       advance in the subject string. The default value  is  PCRE2_UNSET.  The
+       pcre2_match()      and      pcre2_dfa_match()      functions     return
+       PCRE2_ERROR_NOMATCH if a match with a starting point before or  at  the
+       given  offset  is  not  found. The pcre2_substitute() function makes no
+       more substitutions.
 
-       When using this facility,  you  must  set  PCRE2_USE_OFFSET_LIMIT  when
-       calling  pcre2_compile() so that when JIT is in use, different code can
-       be compiled. If a match is started with a non-default match limit  when
-       PCRE2_USE_OFFSET_LIMIT is not set, an error is generated.
+       For example, if the pattern /abc/ is matched against "123abc"  with  an
+       offset  limit  less than 3, the result is PCRE2_ERROR_NO_MATCH. A match
+       can never be  found  if  the  startoffset  argument  of  pcre2_match(),
+       pcre2_dfa_match(),  or  pcre2_substitute()  is  greater than the offset
+       limit set in the match context.
 
-       The  offset limit facility can be used to track progress when searching
-       large subject strings.  See  also  the  PCRE2_FIRSTLINE  option,  which
-       requires a match to start within the first line of the subject. If this
-       is set with an offset limit, a match must occur in the first  line  and
-       also  within  the  offset limit.  In other words, whichever limit comes
-       first is used.
+       When using this  facility,  you  must  set  the  PCRE2_USE_OFFSET_LIMIT
+       option when calling pcre2_compile() so that when JIT is in use, differ-
+       ent code can be compiled. If a match  is  started  with  a  non-default
+       match  limit when PCRE2_USE_OFFSET_LIMIT is not set, an error is gener-
+       ated.
+
+       The offset limit facility can be used to track progress when  searching
+       large  subject  strings or to limit the extent of global substitutions.
+       See also the PCRE2_FIRSTLINE option, which requires a  match  to  start
+       before  or  at  the first newline that follows the start of matching in
+       the subject. If this is set with an offset limit, a match must occur in
+       the first line and also within the offset limit. In other words, which-
+       ever limit comes first is used.
+
+       int pcre2_set_heap_limit(pcre2_match_context *mcontext,
+         uint32_t value);
+
+       The heap_limit parameter specifies, in units of kilobytes, the  maximum
+       amount  of  heap memory that pcre2_match() may use to hold backtracking
+       information when running an interpretive match.  This  limit  does  not
+       apply  to  matching with the JIT optimization, which has its own memory
+       control arrangements (see the pcre2jit documentation for more details),
+       nor  does  it apply to pcre2_dfa_match().  If the limit is reached, the
+       negative error code  PCRE2_ERROR_HEAPLIMIT  is  returned.  The  default
+       limit is set when PCRE2 is built; the default default is very large and
+       is essentially "unlimited".
+
+       A value for the heap limit may also be supplied by an item at the start
+       of a pattern of the form
+
+         (*LIMIT_HEAP=ddd)
+
+       where  ddd  is  a  decimal  number.  However, such a setting is ignored
+       unless ddd is less than the limit set by the  caller  of  pcre2_match()
+       or, if no such limit is set, less than the default.
+
+       The  pcre2_match() function starts out using a 20K vector on the system
+       stack for recording backtracking points. The more  nested  backtracking
+       points there are (that is, the deeper the search tree), the more memory
+       is needed.  Heap memory is used only  if  the  initial  vector  is  too
+       small. If the heap limit is set to a value less than 21 (in particular,
+       zero) no heap memory will be used. In this case, only patterns that  do
+       not have a lot of nested backtracking can be successfully processed.
 
        int pcre2_set_match_limit(pcre2_match_context *mcontext,
          uint32_t value);
 
-       The match_limit parameter provides a means  of  preventing  PCRE2  from
-       using up too many resources when processing patterns that are not going
-       to match, but which have a very large number of possibilities in  their
-       search  trees. The classic example is a pattern that uses nested unlim-
-       ited repeats.
+       The  match_limit  parameter  provides  a means of preventing PCRE2 from
+       using up too many computing resources when processing patterns that are
+       not going to match, but which have a very large number of possibilities
+       in their search trees. The classic  example  is  a  pattern  that  uses
+       nested unlimited repeats.
 
-       Internally, pcre2_match() uses a  function  called  match(),  which  it
-       calls  repeatedly (sometimes recursively). The limit set by match_limit
-       is imposed on the number of times this  function  is  called  during  a
-       match, which has the effect of limiting the amount of backtracking that
-       can take place. For patterns that are not anchored, the count  restarts
-       from  zero  for  each position in the subject string. This limit is not
-       relevant to pcre2_dfa_match(), which ignores it.
+       There  is an internal counter in pcre2_match() that is incremented each
+       time round its main matching loop. If  this  value  reaches  the  match
+       limit, pcre2_match() returns the negative value PCRE2_ERROR_MATCHLIMIT.
+       This has the effect of limiting the amount  of  backtracking  that  can
+       take place. For patterns that are not anchored, the count restarts from
+       zero for each position in the subject string. This limit  also  applies
+       to pcre2_dfa_match(), though the counting is done in a different way.
 
-       When pcre2_match() is called with a pattern that was successfully  pro-
+       When  pcre2_match() is called with a pattern that was successfully pro-
        cessed by pcre2_jit_compile(), the way in which matching is executed is
-       entirely different. However, there is still the possibility of  runaway
-       matching  that  goes  on  for  a very long time, and so the match_limit
-       value is also used in this case (but in a different way) to  limit  how
+       entirely  different. However, there is still the possibility of runaway
+       matching that goes on for a very long  time,  and  so  the  match_limit
+       value  is  also used in this case (but in a different way) to limit how
        long the matching can continue.
 
-       The  default  value  for  the limit can be set when PCRE2 is built; the
-       default default is 10 million, which handles all but the  most  extreme
-       cases.    If    the    limit   is   exceeded,   pcre2_match()   returns
-       PCRE2_ERROR_MATCHLIMIT. A value for the match limit may  also  be  sup-
-       plied by an item at the start of a pattern of the form
+       The default value for the limit can be set when  PCRE2  is  built;  the
+       default  default  is 10 million, which handles all but the most extreme
+       cases. A value for the match limit may also be supplied by an  item  at
+       the start of a pattern of the form
 
          (*LIMIT_MATCH=ddd)
 
        where  ddd  is  a  decimal  number.  However, such a setting is ignored
-       unless ddd is less than the limit set by the  caller  of  pcre2_match()
-       or, if no such limit is set, less than the default.
+       unless ddd is less than the limit set by the caller of pcre2_match() or
+       pcre2_dfa_match() or, if no such limit is set, less than the default.
 
-       int pcre2_set_recursion_limit(pcre2_match_context *mcontext,
+       int pcre2_set_depth_limit(pcre2_match_context *mcontext,
          uint32_t value);
 
-       The recursion_limit parameter is similar to match_limit, but instead of
-       limiting the total number of times that match() is  called,  it  limits
-       the  depth  of  recursion. The recursion depth is a smaller number than
-       the total number of calls, because not all calls to match() are  recur-
-       sive.  This limit is of use only if it is set smaller than match_limit.
+       This   parameter   limits   the   depth   of   nested  backtracking  in
+       pcre2_match().  Each time a nested backtracking point is passed, a  new
+       memory "frame" is used to remember the state of matching at that point.
+       Thus, this parameter indirectly limits the amount  of  memory  that  is
+       used  in  a  match.  However,  because  the size of each memory "frame"
+       depends on the number of capturing parentheses, the actual memory limit
+       varies  from pattern to pattern. This limit was more useful in versions
+       before 10.30, where function recursion was used for backtracking.
 
-       Limiting the recursion depth limits the amount of system stack that can
-       be used, or, when PCRE2 has been compiled to use  memory  on  the  heap
-       instead  of the stack, the amount of heap memory that can be used. This
-       limit is not relevant, and is ignored, when matching is done using  JIT
-       compiled code or by the pcre2_dfa_match() function.
+       The depth limit is not relevant, and is ignored, when matching is  done
+       using JIT compiled code. However, it is supported by pcre2_dfa_match(),
+       which uses it to limit the depth of internal recursive  function  calls
+       that implement atomic groups, lookaround assertions, and pattern recur-
+       sions. This is, therefore, an indirect limit on the  amount  of  system
+       stack that is used. A recursive pattern such as /(.)(?1)/, when matched
+       to a very long string using pcre2_dfa_match(), can use a great deal  of
+       stack.
 
-       The  default  value for recursion_limit can be set when PCRE2 is built;
-       the default default is the same value as the default  for  match_limit.
-       If  the limit is exceeded, pcre2_match() returns PCRE2_ERROR_RECURSION-
-       LIMIT. A value for the recursion limit may also be supplied by an  item
-       at the start of a pattern of the form
+       The  default  value for the depth limit can be set when PCRE2 is built;
+       the default default is the same value as  the  default  for  the  match
+       limit.  If  the  limit  is exceeded, pcre2_match() or pcre2_dfa_match()
+       returns PCRE2_ERROR_DEPTHLIMIT. A value for the depth limit may also be
+       supplied by an item at the start of a pattern of the form
 
-         (*LIMIT_RECURSION=ddd)
+         (*LIMIT_DEPTH=ddd)
 
        where  ddd  is  a  decimal  number.  However, such a setting is ignored
-       unless ddd is less than the limit set by the  caller  of  pcre2_match()
-       or, if no such limit is set, less than the default.
-
-       int pcre2_set_recursion_memory_management(
-         pcre2_match_context *mcontext,
-         void *(*private_malloc)(PCRE2_SIZE, void *),
-         void (*private_free)(void *, void *), void *memory_data);
-
-       This function sets up two additional custom memory management functions
-       for use by pcre2_match() when PCRE2 is compiled to  use  the  heap  for
-       remembering backtracking data, instead of recursive function calls that
-       use the system stack. There is a discussion about PCRE2's  stack  usage
-       in  the  pcre2stack documentation. See the pcre2build documentation for
-       details of how to build PCRE2.
-
-       Using the heap for recursion is a non-standard way of  building  PCRE2,
-       for  use  in  environments  that  have  limited  stacks. Because of the
-       greater use of memory management, pcre2_match() runs more slowly. Func-
-       tions  that  are  different  to the general custom memory functions are
-       provided so that special-purpose external code can  be  used  for  this
-       case,  because  the memory blocks are all the same size. The blocks are
-       retained by pcre2_match() until it is about to exit so that they can be
-       re-used  when  possible during the match. In the absence of these func-
-       tions, the normal custom memory management functions are used, if  sup-
-       plied, otherwise the system functions.
+       unless ddd is less than the limit set by the caller of pcre2_match() or
+       pcre2_dfa_match() or, if no such limit is set, less than the default.
 
 
 CHECKING BUILD-TIME OPTIONS
@@ -987,6 +1082,26 @@
        sequence;  a  value of PCRE2_BSR_ANYCRLF means that \R matches only CR,
        LF, or CRLF. The default can be overridden when a pattern is compiled.
 
+         PCRE2_CONFIG_COMPILED_WIDTHS
+
+       The output is a uint32_t integer whose lower bits indicate  which  code
+       unit  widths  were  selected  when PCRE2 was built. The 1-bit indicates
+       8-bit support, and the 2-bit and 4-bit indicate 16-bit and 32-bit  sup-
+       port, respectively.
+
+         PCRE2_CONFIG_DEPTHLIMIT
+
+       The  output  is a uint32_t integer that gives the default limit for the
+       depth of nested backtracking in pcre2_match() or the  depth  of  nested
+       recursions  and  lookarounds  in pcre2_dfa_match(). Further details are
+       given with pcre2_set_depth_limit() above.
+
+         PCRE2_CONFIG_HEAPLIMIT
+
+       The output is a uint32_t integer that gives, in kilobytes, the  default
+       limit  for  the  amount  of  heap memory used by pcre2_match(). Further
+       details are given with pcre2_set_heap_limit() above.
+
          PCRE2_CONFIG_JIT
 
        The output is a uint32_t integer that is set  to  one  if  support  for
@@ -1021,9 +1136,9 @@
 
          PCRE2_CONFIG_MATCHLIMIT
 
-       The output is a uint32_t integer that gives the default limit  for  the
-       number  of  internal  matching function calls in a pcre2_match() execu-
-       tion. Further details are given with pcre2_match() below.
+       The output is a uint32_t integer that gives the default match limit for
+       pcre2_match().  Further  details are given with pcre2_set_match_limit()
+       above.
 
          PCRE2_CONFIG_NEWLINE
 
@@ -1036,10 +1151,17 @@
          PCRE2_NEWLINE_CRLF     Carriage return, linefeed (CRLF)
          PCRE2_NEWLINE_ANY      Any Unicode line ending
          PCRE2_NEWLINE_ANYCRLF  Any of CR, LF, or CRLF
+         PCRE2_NEWLINE_NUL      The NUL character (binary zero)
 
        The default should normally correspond to  the  standard  sequence  for
        your operating system.
 
+         PCRE2_CONFIG_NEVER_BACKSLASH_C
+
+       The  output  is  a uint32_t integer that is set to one if the use of \C
+       was permanently disabled when PCRE2 was built; otherwise it is  set  to
+       zero.
+
          PCRE2_CONFIG_PARENSLIMIT
 
        The  output is a uint32_t integer that gives the maximum depth of nest-
@@ -1050,43 +1172,32 @@
        application. For  finer  control  over  compilation  stack  usage,  see
        pcre2_set_compile_recursion_guard().
 
-         PCRE2_CONFIG_RECURSIONLIMIT
-
-       The  output  is a uint32_t integer that gives the default limit for the
-       depth of recursion when calling the internal  matching  function  in  a
-       pcre2_match()  execution.  Further details are given with pcre2_match()
-       below.
-
          PCRE2_CONFIG_STACKRECURSE
 
-       The output is a uint32_t integer that is set to one if internal  recur-
-       sion  when  running  pcre2_match() is implemented by recursive function
-       calls that use the system stack to remember their state.  This  is  the
-       usual  way that PCRE2 is compiled. The output is zero if PCRE2 was com-
-       piled to use blocks of data on the heap instead of  recursive  function
-       calls.
+       This parameter is obsolete and should not be used in new code. The out-
+       put is a uint32_t integer that is always set to zero.
 
          PCRE2_CONFIG_UNICODE_VERSION
 
-       The  where  argument  should point to a buffer that is at least 24 code
-       units long.  (The  exact  length  required  can  be  found  by  calling
-       pcre2_config()  with  where  set  to  NULL.) If PCRE2 has been compiled
-       without Unicode support, the buffer is filled with  the  text  "Unicode
-       not  supported".  Otherwise,  the  Unicode version string (for example,
-       "8.0.0") is inserted. The number of code units used is  returned.  This
+       The where argument should point to a buffer that is at  least  24  code
+       units  long.  (The  exact  length  required  can  be  found  by calling
+       pcre2_config() with where set to NULL.)  If  PCRE2  has  been  compiled
+       without  Unicode  support,  the buffer is filled with the text "Unicode
+       not supported". Otherwise, the Unicode  version  string  (for  example,
+       "8.0.0")  is  inserted. The number of code units used is returned. This
        is the length of the string plus one unit for the terminating zero.
 
          PCRE2_CONFIG_UNICODE
 
-       The  output is a uint32_t integer that is set to one if Unicode support
-       is available; otherwise it is set to zero. Unicode support implies  UTF
+       The output is a uint32_t integer that is set to one if Unicode  support
+       is  available; otherwise it is set to zero. Unicode support implies UTF
        support.
 
          PCRE2_CONFIG_VERSION
 
-       The  where  argument  should point to a buffer that is at least 12 code
-       units long.  (The  exact  length  required  can  be  found  by  calling
-       pcre2_config()  with  where set to NULL.) The buffer is filled with the
+       The where argument should point to a buffer that is at  least  24  code
+       units  long.  (The  exact  length  required  can  be  found  by calling
+       pcre2_config() with where set to NULL.) The buffer is filled  with  the
        PCRE2 version string, zero-terminated. The number of code units used is
        returned. This is the length of the string plus one unit for the termi-
        nating zero.
@@ -1102,28 +1213,41 @@
 
        pcre2_code *pcre2_code_copy(const pcre2_code *code);
 
-       The pcre2_compile() function compiles a pattern into an internal  form.
-       The  pattern  is  defined  by a pointer to a string of code units and a
-       length. If the pattern is zero-terminated, the length can be  specified
-       as  PCRE2_ZERO_TERMINATED. The function returns a pointer to a block of
-       memory that contains the compiled pattern and related data, or NULL  if
-       an error occurred.
+       pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *code);
 
-       If  the  compile context argument ccontext is NULL, memory for the com-
-       piled pattern  is  obtained  by  calling  malloc().  Otherwise,  it  is
-       obtained  from  the  same memory function that was used for the compile
-       context. The caller must free the memory by  calling  pcre2_code_free()
+       The  pcre2_compile() function compiles a pattern into an internal form.
+       The pattern is defined by a pointer to a string of  code  units  and  a
+       length  (in  code units). If the pattern is zero-terminated, the length
+       can be specified  as  PCRE2_ZERO_TERMINATED.  The  function  returns  a
+       pointer  to  a  block  of memory that contains the compiled pattern and
+       related data, or NULL if an error occurred.
+
+       If the compile context argument ccontext is NULL, memory for  the  com-
+       piled  pattern  is  obtained  by  calling  malloc().  Otherwise,  it is
+       obtained from the same memory function that was used  for  the  compile
+       context.  The  caller must free the memory by calling pcre2_code_free()
        when it is no longer needed.
 
        The function pcre2_code_copy() makes a copy of the compiled code in new
-       memory, using the same memory allocator as was used for  the  original.
-       However,  if  the  code  has  been  processed  by the JIT compiler (see
-       below), the JIT information cannot be copied (because it  is  position-
+       memory,  using  the same memory allocator as was used for the original.
+       However, if the code has  been  processed  by  the  JIT  compiler  (see
+       below),  the  JIT information cannot be copied (because it is position-
        dependent).  The new copy can initially be used only for non-JIT match-
-       ing, though it can be passed to pcre2_jit_compile()  if  required.  The
-       pcre2_code_copy()  function  provides a way for individual threads in a
-       multithreaded application to acquire a private copy of shared  compiled
-       code.
+       ing, though it can be passed to pcre2_jit_compile() if required.
+
+       The pcre2_code_copy() function provides a way for individual threads in
+       a multithreaded application to acquire a private copy  of  shared  com-
+       piled  code.   However, it does not make a copy of the character tables
+       used by the compiled pattern; the new pattern code points to  the  same
+       tables  as  the original code.  (See "Locale Support" below for details
+       of these character tables.) In many applications the  same  tables  are
+       used  throughout, so this behaviour is appropriate. Nevertheless, there
+       are occasions when a copy of a compiled pattern and the relevant tables
+       are  needed.  The pcre2_code_copy_with_tables() provides this facility.
+       Copies of both the code and the tables are  made,  with  the  new  code
+       pointing  to the new tables. The memory for the new tables is automati-
+       cally freed when pcre2_code_free() is called for the new  copy  of  the
+       compiled code.
 
        NOTE:  When  one  of  the matching functions is called, pointers to the
        compiled pattern and the subject string are set in the match data block
@@ -1141,33 +1265,46 @@
 
        For  those options that can be different in different parts of the pat-
        tern, the contents of the options argument specifies their settings  at
-       the  start  of  compilation.  The PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK
-       options can be set at the time of matching as well as at compile time.
+       the  start  of  compilation. The PCRE2_ANCHORED, PCRE2_ENDANCHORED, and
+       PCRE2_NO_UTF_CHECK options can be set at the time of matching  as  well
+       as at compile time.
 
-       Other, less frequently required compile-time parameters  (for  example,
+       Other,  less  frequently required compile-time parameters (for example,
        the newline setting) can be provided in a compile context (as described
        above).
 
        If errorcode or erroroffset is NULL, pcre2_compile() returns NULL imme-
-       diately.  Otherwise,  the  variables to which these point are set to an
-       error code and an offset (number of code  units)  within  the  pattern,
-       respectively,  when  pcre2_compile() returns NULL because a compilation
+       diately. Otherwise, the variables to which these point are  set  to  an
+       error  code  and  an  offset (number of code units) within the pattern,
+       respectively, when pcre2_compile() returns NULL because  a  compilation
        error has occurred. The values are not defined when compilation is suc-
        cessful and pcre2_compile() returns a non-NULL value.
 
-       The  pcre2_get_error_message() function (see "Obtaining a textual error
-       message" below) provides a textual message for each error code.  Compi-
-       lation errors have positive error codes; UTF formatting error codes are
-       negative. For an invalid UTF-8 or UTF-16 string, the offset is that  of
-       the first code unit of the failing character.
+       There are nearly 100 positive  error  codes  that  pcre2_compile()  may
+       return  if  it finds an error in the pattern. There are also some nega-
+       tive error codes that are used for invalid UTF strings. These  are  the
+       same as given by pcre2_match() and pcre2_dfa_match(), and are described
+       in the pcre2unicode page. There is no separate  documentation  for  the
+       positive  error  codes,  because  the  textual  error messages that are
+       obtained  by  calling  the  pcre2_get_error_message()   function   (see
+       "Obtaining  a textual error message" below) should be self-explanatory.
+       Macro names starting with PCRE2_ERROR_ are defined  for  both  positive
+       and negative error codes in pcre2.h.
 
-       Some  errors are not detected until the whole pattern has been scanned;
-       in these cases, the offset passed back is the length  of  the  pattern.
-       Note  that  the  offset is in code units, not characters, even in a UTF
+       The value returned in erroroffset is an indication of where in the pat-
+       tern the error occurred. It is not necessarily the  furthest  point  in
+       the  pattern  that  was  read. For example, after the error "lookbehind
+       assertion is not fixed length", the error offset points to the start of
+       the  failing assertion. For an invalid UTF-8 or UTF-16 string, the off-
+       set is that of the first code unit of the failing character.
+
+       Some errors are not detected until the whole pattern has been  scanned;
+       in  these  cases,  the offset passed back is the length of the pattern.
+       Note that the offset is in code units, not characters, even  in  a  UTF
        mode. It may sometimes point into the middle of a UTF-8 or UTF-16 char-
        acter.
 
-       This  code  fragment shows a typical straightforward call to pcre2_com-
+       This code fragment shows a typical straightforward call  to  pcre2_com-
        pile():
 
          pcre2_code *re;
@@ -1181,77 +1318,86 @@
            &erroffset,             /* for error offset */
            NULL);                  /* no compile context */
 
-       The following names for option bits are defined in the  pcre2.h  header
+       The  following  names for option bits are defined in the pcre2.h header
        file:
 
          PCRE2_ANCHORED
 
        If this bit is set, the pattern is forced to be "anchored", that is, it
-       is constrained to match only at the first matching point in the  string
-       that  is being searched (the "subject string"). This effect can also be
-       achieved by appropriate constructs in the pattern itself, which is  the
+       is  constrained to match only at the first matching point in the string
+       that is being searched (the "subject string"). This effect can also  be
+       achieved  by appropriate constructs in the pattern itself, which is the
        only way to do it in Perl.
 
          PCRE2_ALLOW_EMPTY_CLASS
 
-       By  default, for compatibility with Perl, a closing square bracket that
-       immediately follows an opening one is treated as a data  character  for
-       the  class.  When  PCRE2_ALLOW_EMPTY_CLASS  is  set,  it terminates the
+       By default, for compatibility with Perl, a closing square bracket  that
+       immediately  follows  an opening one is treated as a data character for
+       the class. When  PCRE2_ALLOW_EMPTY_CLASS  is  set,  it  terminates  the
        class, which therefore contains no characters and so can never match.
 
          PCRE2_ALT_BSUX
 
-       This option request alternative handling  of  three  escape  sequences,
-       which  makes  PCRE2's  behaviour more like ECMAscript (aka JavaScript).
+       This  option  request  alternative  handling of three escape sequences,
+       which makes PCRE2's behaviour more like  ECMAscript  (aka  JavaScript).
        When it is set:
 
        (1) \U matches an upper case "U" character; by default \U causes a com-
        pile time error (Perl uses \U to upper case subsequent characters).
 
        (2) \u matches a lower case "u" character unless it is followed by four
-       hexadecimal digits, in which case the hexadecimal  number  defines  the
-       code  point  to match. By default, \u causes a compile time error (Perl
+       hexadecimal  digits,  in  which case the hexadecimal number defines the
+       code point to match. By default, \u causes a compile time  error  (Perl
        uses it to upper case the following character).
 
-       (3) \x matches a lower case "x" character unless it is followed by  two
-       hexadecimal  digits,  in  which case the hexadecimal number defines the
-       code point to match. By default, as in Perl, a  hexadecimal  number  is
+       (3)  \x matches a lower case "x" character unless it is followed by two
+       hexadecimal digits, in which case the hexadecimal  number  defines  the
+       code  point  to  match. By default, as in Perl, a hexadecimal number is
        always expected after \x, but it may have zero, one, or two digits (so,
        for example, \xz matches a binary zero character followed by z).
 
          PCRE2_ALT_CIRCUMFLEX
 
        In  multiline  mode  (when  PCRE2_MULTILINE  is  set),  the  circumflex
-       metacharacter  matches at the start of the subject (unless PCRE2_NOTBOL
-       is set), and also after any internal  newline.  However,  it  does  not
+       metacharacter matches at the start of the subject (unless  PCRE2_NOTBOL
+       is  set),  and  also  after  any internal newline. However, it does not
        match after a newline at the end of the subject, for compatibility with
-       Perl. If you want a multiline circumflex also to match after  a  termi-
+       Perl.  If  you want a multiline circumflex also to match after a termi-
        nating newline, you must set PCRE2_ALT_CIRCUMFLEX.
 
          PCRE2_ALT_VERBNAMES
 
-       By  default, for compatibility with Perl, the name in any verb sequence
-       such as (*MARK:NAME) is  any  sequence  of  characters  that  does  not
-       include  a  closing  parenthesis. The name is not processed in any way,
-       and it is not possible to include a closing parenthesis  in  the  name.
-       However,  if  the  PCRE2_ALT_VERBNAMES  option is set, normal backslash
-       processing is applied to verb  names  and  only  an  unescaped  closing
-       parenthesis  terminates the name. A closing parenthesis can be included
-       in a name either as \) or between \Q  and  \E.  If  the  PCRE2_EXTENDED
-       option is set, unescaped whitespace in verb names is skipped and #-com-
-       ments are recognized, exactly as in the rest of the pattern.
+       By default, for compatibility with Perl, the name in any verb  sequence
+       such  as  (*MARK:NAME)  is  any  sequence  of  characters that does not
+       include a closing parenthesis. The name is not processed  in  any  way,
+       and  it  is  not possible to include a closing parenthesis in the name.
+       However, if the PCRE2_ALT_VERBNAMES option  is  set,  normal  backslash
+       processing  is  applied  to  verb  names  and only an unescaped closing
+       parenthesis terminates the name. A closing parenthesis can be  included
+       in  a  name either as \) or between \Q and \E. If the PCRE2_EXTENDED or
+       PCRE2_EXTENDED_MORE option is set, unescaped whitespace in  verb  names
+       is  skipped  and  #-comments are recognized in this mode, exactly as in
+       the rest of the pattern.
 
          PCRE2_AUTO_CALLOUT
 
        If this bit  is  set,  pcre2_compile()  automatically  inserts  callout
-       items, all with number 255, before each pattern item. For discussion of
-       the callout facility, see the pcre2callout documentation.
+       items,  all  with  number 255, before each pattern item, except immedi-
+       ately before or after an explicit callout in the pattern.  For  discus-
+       sion of the callout facility, see the pcre2callout documentation.
 
          PCRE2_CASELESS
 
-       If this bit is set, letters in the pattern match both upper  and  lower
-       case  letters in the subject. It is equivalent to Perl's /i option, and
-       it can be changed within a pattern by a (?i) option setting.
+       If  this  bit is set, letters in the pattern match both upper and lower
+       case letters in the subject. It is equivalent to Perl's /i option,  and
+       it  can  be  changed  within  a  pattern  by  a (?i) option setting. If
+       PCRE2_UTF is set, Unicode properties are used for all  characters  with
+       more  than one other case, and for all characters whose code points are
+       greater than U+007f. For lower valued characters with  only  one  other
+       case,  a  lookup  table is used for speed. When PCRE2_UTF is not set, a
+       lookup table is used for all code points less than 256, and higher code
+       points  (available  only  in  16-bit or 32-bit mode) are treated as not
+       having another case.
 
          PCRE2_DOLLAR_ENDONLY
 
@@ -1281,178 +1427,229 @@
        matched.  There  are  more details of named subpatterns below; see also
        the pcre2pattern documentation.
 
+         PCRE2_ENDANCHORED
+
+       If this bit is set, the end of any pattern match must be right  at  the
+       end of the string being searched (the "subject string"). If the pattern
+       match succeeds by reaching (*ACCEPT), but does not reach the end of the
+       subject,  the match fails at the current starting point. For unanchored
+       patterns, a new match is then tried at the next  starting  point.  How-
+       ever, if the match succeeds by reaching the end of the pattern, but not
+       the end of the subject, backtracking occurs and  an  alternative  match
+       may be found. Consider these two patterns:
+
+         .(*ACCEPT)|..
+         .|..
+
+       If  matched against "abc" with PCRE2_ENDANCHORED set, the first matches
+       "c" whereas the second matches "bc". The  effect  of  PCRE2_ENDANCHORED
+       can  also  be achieved by appropriate constructs in the pattern itself,
+       which is the only way to do it in Perl.
+
+       For DFA matching with pcre2_dfa_match(), PCRE2_ENDANCHORED applies only
+       to  the  first  (that  is,  the longest) matched string. Other parallel
+       matches, which are necessarily substrings of the first one, must  obvi-
+       ously end before the end of the subject.
+
          PCRE2_EXTENDED
 
-       If this bit is set, most white space  characters  in  the  pattern  are
-       totally  ignored  except when escaped or inside a character class. How-
-       ever, white space is not allowed within  sequences  such  as  (?>  that
+       If  this  bit  is  set,  most white space characters in the pattern are
+       totally ignored except when escaped or inside a character  class.  How-
+       ever,  white  space  is  not  allowed within sequences such as (?> that
        introduce various parenthesized subpatterns, nor within numerical quan-
-       tifiers such as {1,3}.  Ignorable white space is permitted  between  an
-       item  and a following quantifier and between a quantifier and a follow-
+       tifiers  such  as {1,3}.  Ignorable white space is permitted between an
+       item and a following quantifier and between a quantifier and a  follow-
        ing + that indicates possessiveness.
 
-       PCRE2_EXTENDED also causes characters between an unescaped # outside  a
-       character  class  and the next newline, inclusive, to be ignored, which
+       PCRE2_EXTENDED  also causes characters between an unescaped # outside a
+       character class and the next newline, inclusive, to be  ignored,  which
        makes it possible to include comments inside complicated patterns. Note
-       that  the  end of this type of comment is a literal newline sequence in
+       that the end of this type of comment is a literal newline  sequence  in
        the pattern; escape sequences that happen to represent a newline do not
-       count.  PCRE2_EXTENDED is equivalent to Perl's /x option, and it can be
+       count. PCRE2_EXTENDED is equivalent to Perl's /x option, and it can  be
        changed within a pattern by a (?x) option setting.
 
        Which characters are interpreted as newlines can be specified by a set-
-       ting  in  the compile context that is passed to pcre2_compile() or by a
-       special sequence at the start of the pattern, as described in the  sec-
-       tion  entitled "Newline conventions" in the pcre2pattern documentation.
+       ting in the compile context that is passed to pcre2_compile() or  by  a
+       special  sequence at the start of the pattern, as described in the sec-
+       tion entitled "Newline conventions" in the pcre2pattern  documentation.
        A default is defined when PCRE2 is built.
 
+         PCRE2_EXTENDED_MORE
+
+       This  option  has  the  effect  of  PCRE2_EXTENDED,  but,  in addition,
+       unescaped space and horizontal tab  characters  are  ignored  inside  a
+       character  class.  PCRE2_EXTENDED_MORE is equivalent to Perl's 5.26 /xx
+       option, and it can be changed within a pattern by a (?xx)  option  set-
+       ting.
+
          PCRE2_FIRSTLINE
 
-       If this option is set, an  unanchored  pattern  is  required  to  match
-       before  or  at  the  first  newline  in  the subject string, though the
-       matched text may continue over the  newline.  See  also  PCRE2_USE_OFF-
-       SET_LIMIT,   which  provides  a  more  general  limiting  facility.  If
-       PCRE2_FIRSTLINE is set with an offset limit, a match must occur in  the
-       first  line and also within the offset limit. In other words, whichever
-       limit comes first is used.
+       If this option is set, the start of an unanchored pattern match must be
+       before or at the first newline in  the  subject  string  following  the
+       start  of  matching, though the matched text may continue over the new-
+       line. If startoffset is non-zero, the limiting newline is not necessar-
+       ily  the  first  newline  in  the  subject. For example, if the subject
+       string is "abc\nxyz" (where \n represents a single-character newline) a
+       pattern  match for "yz" succeeds with PCRE2_FIRSTLINE if startoffset is
+       greater than 3. See also PCRE2_USE_OFFSET_LIMIT, which provides a  more
+       general  limiting  facility.  If  PCRE2_FIRSTLINE is set with an offset
+       limit, a match must occur in the first line and also within the  offset
+       limit. In other words, whichever limit comes first is used.
+
+         PCRE2_LITERAL
+
+       If this option is set, all meta-characters in the pattern are disabled,
+       and it is treated as a literal string. Matching literal strings with  a
+       regular expression engine is not the most efficient way of doing it. If
+       you are doing a lot of literal matching and  are  worried  about  effi-
+       ciency, you should consider using other approaches. The only other main
+       options  that  are  allowed  with  PCRE2_LITERAL  are:  PCRE2_ANCHORED,
+       PCRE2_ENDANCHORED, PCRE2_AUTO_CALLOUT, PCRE2_CASELESS, PCRE2_FIRSTLINE,
+       PCRE2_NO_START_OPTIMIZE,     PCRE2_NO_UTF_CHECK,     PCRE2_UTF,     and
+       PCRE2_USE_OFFSET_LIMIT.  The  extra  options PCRE2_EXTRA_MATCH_LINE and
+       PCRE2_EXTRA_MATCH_WORD are also supported. Any other options  cause  an
+       error.
 
          PCRE2_MATCH_UNSET_BACKREF
 
-       If this option is set, a back reference to an  unset  subpattern  group
-       matches  an  empty  string (by default this causes the current matching
-       alternative to fail).  A pattern such as  (\1)(a)  succeeds  when  this
-       option  is set (assuming it can find an "a" in the subject), whereas it
-       fails by default, for Perl compatibility.  Setting  this  option  makes
+       If  this  option  is set, a back reference to an unset subpattern group
+       matches an empty string (by default this causes  the  current  matching
+       alternative  to  fail).   A  pattern such as (\1)(a) succeeds when this
+       option is set (assuming it can find an "a" in the subject), whereas  it
+       fails  by  default,  for  Perl compatibility. Setting this option makes
        PCRE2 behave more like ECMAscript (aka JavaScript).
 
          PCRE2_MULTILINE
 
-       By  default,  for  the purposes of matching "start of line" and "end of
-       line", PCRE2 treats the subject string as consisting of a  single  line
-       of  characters,  even  if  it actually contains newlines. The "start of
-       line" metacharacter (^) matches only at the start of  the  string,  and
-       the  "end  of  line"  metacharacter  ($) matches only at the end of the
+       By default, for the purposes of matching "start of line"  and  "end  of
+       line",  PCRE2  treats the subject string as consisting of a single line
+       of characters, even if it actually contains  newlines.  The  "start  of
+       line"  metacharacter  (^)  matches only at the start of the string, and
+       the "end of line" metacharacter ($) matches only  at  the  end  of  the
        string,  or  before  a  terminating  newline  (except  when  PCRE2_DOL-
-       LAR_ENDONLY  is  set).  Note, however, that unless PCRE2_DOTALL is set,
+       LAR_ENDONLY is set). Note, however, that unless  PCRE2_DOTALL  is  set,
        the "any character" metacharacter (.) does not match at a newline. This
        behaviour (for ^, $, and dot) is the same as Perl.
 
-       When  PCRE2_MULTILINE  it is set, the "start of line" and "end of line"
-       constructs match immediately following or immediately  before  internal
-       newlines  in  the  subject string, respectively, as well as at the very
-       start and end. This is equivalent to Perl's /m option, and  it  can  be
+       When PCRE2_MULTILINE it is set, the "start of line" and "end  of  line"
+       constructs  match  immediately following or immediately before internal
+       newlines in the subject string, respectively, as well as  at  the  very
+       start  and  end.  This is equivalent to Perl's /m option, and it can be
        changed within a pattern by a (?m) option setting. Note that the "start
        of line" metacharacter does not match after a newline at the end of the
-       subject,  for compatibility with Perl.  However, you can change this by
-       setting the PCRE2_ALT_CIRCUMFLEX option. If there are no newlines in  a
-       subject  string,  or  no  occurrences  of  ^ or $ in a pattern, setting
+       subject, for compatibility with Perl.  However, you can change this  by
+       setting  the PCRE2_ALT_CIRCUMFLEX option. If there are no newlines in a
+       subject string, or no occurrences of ^  or  $  in  a  pattern,  setting
        PCRE2_MULTILINE has no effect.
 
          PCRE2_NEVER_BACKSLASH_C
 
-       This option locks out the use of \C in the pattern that is  being  com-
-       piled.   This  escape  can  cause  unpredictable  behaviour in UTF-8 or
-       UTF-16 modes, because it may leave the current matching  point  in  the
-       middle  of  a  multi-code-unit  character. This option may be useful in
-       applications that process patterns from  external  sources.  Note  that
+       This  option  locks out the use of \C in the pattern that is being com-
+       piled.  This escape can  cause  unpredictable  behaviour  in  UTF-8  or
+       UTF-16  modes,  because  it may leave the current matching point in the
+       middle of a multi-code-unit character. This option  may  be  useful  in
+       applications  that  process  patterns  from external sources. Note that
        there is also a build-time option that permanently locks out the use of
        \C.
 
          PCRE2_NEVER_UCP
 
-       This option locks out the use of Unicode properties  for  handling  \B,
+       This  option  locks  out the use of Unicode properties for handling \B,
        \b, \D, \d, \S, \s, \W, \w, and some of the POSIX character classes, as
-       described for the PCRE2_UCP option below. In  particular,  it  prevents
-       the  creator of the pattern from enabling this facility by starting the
-       pattern with (*UCP). This option may be  useful  in  applications  that
+       described  for  the  PCRE2_UCP option below. In particular, it prevents
+       the creator of the pattern from enabling this facility by starting  the
+       pattern  with  (*UCP).  This  option may be useful in applications that
        process patterns from external sources. The option combination PCRE_UCP
        and PCRE_NEVER_UCP causes an error.
 
          PCRE2_NEVER_UTF
 
-       This option locks out interpretation of the pattern as  UTF-8,  UTF-16,
+       This  option  locks out interpretation of the pattern as UTF-8, UTF-16,
        or UTF-32, depending on which library is in use. In particular, it pre-
-       vents the creator of the pattern from switching to  UTF  interpretation
-       by  starting  the  pattern  with  (*UTF).  This option may be useful in
-       applications that process patterns from external sources. The  combina-
+       vents  the  creator of the pattern from switching to UTF interpretation
+       by starting the pattern with (*UTF).  This  option  may  be  useful  in
+       applications  that process patterns from external sources. The combina-
        tion of PCRE2_UTF and PCRE2_NEVER_UTF causes an error.
 
          PCRE2_NO_AUTO_CAPTURE
 
        If this option is set, it disables the use of numbered capturing paren-
-       theses in the pattern. Any opening parenthesis that is not followed  by
-       ?  behaves as if it were followed by ?: but named parentheses can still
-       be used for capturing (and they acquire  numbers  in  the  usual  way).
-       There  is  no  equivalent  of  this  option in Perl. Note that, if this
-       option is set, references  to  capturing  groups  (back  references  or
-       recursion/subroutine  calls) may only refer to named groups, though the
-       reference can be by name or by number.
+       theses  in the pattern. Any opening parenthesis that is not followed by
+       ? behaves as if it were followed by ?: but named parentheses can  still
+       be used for capturing (and they acquire numbers in the usual way). This
+       is the same as Perl's /n option.  Note that, when this option  is  set,
+       references to capturing groups (back references or recursion/subroutine
+       calls) may only refer to named groups, though the reference can  be  by
+       name or by number.
 
          PCRE2_NO_AUTO_POSSESS
 
        If this option is set, it disables "auto-possessification", which is an
-       optimization  that,  for example, turns a+b into a++b in order to avoid
-       backtracks into a+ that can never be successful. However,  if  callouts
-       are  in  use,  auto-possessification means that some callouts are never
+       optimization that, for example, turns a+b into a++b in order  to  avoid
+       backtracks  into  a+ that can never be successful. However, if callouts
+       are in use, auto-possessification means that some  callouts  are  never
        taken. You can set this option if you want the matching functions to do
-       a  full  unoptimized  search and run all the callouts, but it is mainly
+       a full unoptimized search and run all the callouts, but  it  is  mainly
        provided for testing purposes.
 
          PCRE2_NO_DOTSTAR_ANCHOR
 
        If this option is set, it disables an optimization that is applied when
-       .*  is  the  first significant item in a top-level branch of a pattern,
-       and all the other branches also start with .* or with \A or  \G  or  ^.
-       The  optimization  is  automatically disabled for .* if it is inside an
-       atomic group or a capturing group that is the subject of a back  refer-
-       ence,  or  if  the pattern contains (*PRUNE) or (*SKIP). When the opti-
-       mization is not disabled, such a pattern is automatically  anchored  if
+       .* is the first significant item in a top-level branch  of  a  pattern,
+       and  all  the  other branches also start with .* or with \A or \G or ^.
+       The optimization is automatically disabled for .* if it  is  inside  an
+       atomic  group or a capturing group that is the subject of a back refer-
+       ence, or if the pattern contains (*PRUNE) or (*SKIP).  When  the  opti-
+       mization  is  not disabled, such a pattern is automatically anchored if
        PCRE2_DOTALL is set for all the .* items and PCRE2_MULTILINE is not set
-       for any ^ items. Otherwise, the fact that any match must  start  either
-       at  the start of the subject or following a newline is remembered. Like
+       for  any  ^ items. Otherwise, the fact that any match must start either
+       at the start of the subject or following a newline is remembered.  Like
        other optimizations, this can cause callouts to be skipped.
 
          PCRE2_NO_START_OPTIMIZE
 
-       This is an option whose main effect is at matching time.  It  does  not
+       This  is  an  option whose main effect is at matching time. It does not
        change what pcre2_compile() generates, but it does affect the output of
        the JIT compiler.
 
-       There are a number of optimizations that may occur at the  start  of  a
-       match,  in  order  to speed up the process. For example, if it is known
-       that an unanchored match must start  with  a  specific  character,  the
-       matching  code searches the subject for that character, and fails imme-
-       diately if it cannot find it, without actually running the main  match-
-       ing  function.  This means that a special item such as (*COMMIT) at the
-       start of a pattern is not considered until after  a  suitable  starting
-       point  for  the  match  has  been found. Also, when callouts or (*MARK)
-       items are in use, these "start-up" optimizations can cause them  to  be
-       skipped  if  the pattern is never actually used. The start-up optimiza-
-       tions are in effect a pre-scan of the subject that takes  place  before
+       There  are  a  number of optimizations that may occur at the start of a
+       match, in order to speed up the process. For example, if  it  is  known
+       that  an  unanchored  match must start with a specific code unit value,
+       the matching code searches the subject for that value, and fails  imme-
+       diately  if it cannot find it, without actually running the main match-
+       ing function. This means that a special item such as (*COMMIT)  at  the
+       start  of  a  pattern is not considered until after a suitable starting
+       point for the match has been found.  Also,  when  callouts  or  (*MARK)
+       items  are  in use, these "start-up" optimizations can cause them to be
+       skipped if the pattern is never actually used. The  start-up  optimiza-
+       tions  are  in effect a pre-scan of the subject that takes place before
        the pattern is run.
 
        The PCRE2_NO_START_OPTIMIZE option disables the start-up optimizations,
-       possibly causing performance to suffer,  but  ensuring  that  in  cases
-       where  the  result is "no match", the callouts do occur, and that items
+       possibly  causing  performance  to  suffer,  but ensuring that in cases
+       where the result is "no match", the callouts do occur, and  that  items
        such as (*COMMIT) and (*MARK) are considered at every possible starting
        position in the subject string.
 
-       Setting  PCRE2_NO_START_OPTIMIZE  may  change the outcome of a matching
+       Setting PCRE2_NO_START_OPTIMIZE may change the outcome  of  a  matching
        operation.  Consider the pattern
 
          (*COMMIT)ABC
 
-       When this is compiled, PCRE2 records the fact that a match  must  start
-       with  the  character  "A".  Suppose the subject string is "DEFABC". The
-       start-up optimization scans along the subject, finds "A" and  runs  the
-       first  match attempt from there. The (*COMMIT) item means that the pat-
-       tern must match the current starting position, which in this  case,  it
-       does.  However,  if  the same match is run with PCRE2_NO_START_OPTIMIZE
-       set, the initial scan along the subject string  does  not  happen.  The
-       first  match  attempt  is  run  starting  from "D" and when this fails,
-       (*COMMIT) prevents any further matches  being  tried,  so  the  overall
-       result is "no match". There are also other start-up optimizations.  For
-       example, a minimum length for the subject may be recorded. Consider the
-       pattern
+       When  this  is compiled, PCRE2 records the fact that a match must start
+       with the character "A". Suppose the subject  string  is  "DEFABC".  The
+       start-up  optimization  scans along the subject, finds "A" and runs the
+       first match attempt from there. The (*COMMIT) item means that the  pat-
+       tern  must  match the current starting position, which in this case, it
+       does. However, if the same match is  run  with  PCRE2_NO_START_OPTIMIZE
+       set,  the  initial  scan  along the subject string does not happen. The
+       first match attempt is run starting  from  "D"  and  when  this  fails,
+       (*COMMIT)  prevents  any  further  matches  being tried, so the overall
+       result is "no match".
+
+       There are also other start-up optimizations.  For  example,  a  minimum
+       length for the subject may be recorded. Consider the pattern
 
          (*MARK:A)(X|Y)
 
@@ -1469,63 +1666,133 @@
        When  PCRE2_UTF  is set, the validity of the pattern as a UTF string is
        automatically checked. There are  discussions  about  the  validity  of
        UTF-8  strings,  UTF-16 strings, and UTF-32 strings in the pcre2unicode
-       document.  If an invalid UTF sequence is found, pcre2_compile() returns
+       document. If an invalid UTF sequence is found, pcre2_compile()  returns
        a negative error code.
 
-       If you know that your pattern is valid, and you want to skip this check
-       for performance reasons, you can  set  the  PCRE2_NO_UTF_CHECK  option.
-       When  it  is set, the effect of passing an invalid UTF string as a pat-
-       tern is undefined. It may cause your program to  crash  or  loop.  Note
-       that   this   option   can   also   be   passed  to  pcre2_match()  and
-       pcre_dfa_match(), to suppress validity checking of the subject string.
+       If  you  know  that your pattern is a valid UTF string, and you want to
+       skip  this  check  for   performance   reasons,   you   can   set   the
+       PCRE2_NO_UTF_CHECK  option.  When  it  is set, the effect of passing an
+       invalid UTF string as a pattern is undefined. It may cause your program
+       to crash or loop.
+
+       Note  that  this  option  can  also  be  passed  to  pcre2_match()  and
+       pcre_dfa_match(), to suppress UTF  validity  checking  of  the  subject
+       string.
+
+       Note also that setting PCRE2_NO_UTF_CHECK at compile time does not dis-
+       able the error that is given if an escape sequence for an invalid  Uni-
+       code  code  point is encountered in the pattern. In particular, the so-
+       called "surrogate" code points (0xd800 to 0xdfff) are invalid.  If  you
+       want  to  allow  escape  sequences  such  as  \x{d800}  you can set the
+       PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES extra option, as described  in  the
+       section  entitled "Extra compile options" below.  However, this is pos-
+       sible only in UTF-8 and UTF-32 modes, because these values are not rep-
+       resentable in UTF-16.
 
          PCRE2_UCP
 
        This option changes the way PCRE2 processes \B, \b, \D, \d, \S, \s, \W,
-       \w,  and  some  of  the POSIX character classes. By default, only ASCII
-       characters are recognized, but if PCRE2_UCP is set, Unicode  properties
-       are  used instead to classify characters. More details are given in the
+       \w, and some of the POSIX character classes.  By  default,  only  ASCII
+       characters  are recognized, but if PCRE2_UCP is set, Unicode properties
+       are used instead to classify characters. More details are given in  the
        section on generic character types in the pcre2pattern page. If you set
-       PCRE2_UCP,  matching one of the items it affects takes much longer. The
-       option is available only if PCRE2 has been compiled with  Unicode  sup-
-       port.
+       PCRE2_UCP, matching one of the items it affects takes much longer.  The
+       option  is  available only if PCRE2 has been compiled with Unicode sup-
+       port (which is the default).
 
          PCRE2_UNGREEDY
 
-       This  option  inverts  the "greediness" of the quantifiers so that they
-       are not greedy by default, but become greedy if followed by "?". It  is
-       not  compatible  with Perl. It can also be set by a (?U) option setting
+       This option inverts the "greediness" of the quantifiers  so  that  they
+       are  not greedy by default, but become greedy if followed by "?". It is
+       not compatible with Perl. It can also be set by a (?U)  option  setting
        within the pattern.
 
          PCRE2_USE_OFFSET_LIMIT
 
        This option must be set for pcre2_compile() if pcre2_set_offset_limit()
-       is  going  to be used to set a non-default offset limit in a match con-
-       text for matches that use this pattern. An error  is  generated  if  an
-       offset  limit  is  set  without  this option. For more details, see the
-       description of pcre2_set_offset_limit() in the section  that  describes
+       is going to be used to set a non-default offset limit in a  match  con-
+       text  for  matches  that  use this pattern. An error is generated if an
+       offset limit is set without this option.  For  more  details,  see  the
+       description  of  pcre2_set_offset_limit() in the section that describes
        match contexts. See also the PCRE2_FIRSTLINE option above.
 
          PCRE2_UTF
 
-       This  option  causes  PCRE2  to regard both the pattern and the subject
-       strings that are subsequently processed as strings  of  UTF  characters
-       instead  of  single-code-unit  strings.  It  is available when PCRE2 is
-       built to include Unicode support (which is  the  default).  If  Unicode
-       support  is  not  available,  the use of this option provokes an error.
-       Details of how this option changes the behaviour of PCRE2 are given  in
+       This option causes PCRE2 to regard both the  pattern  and  the  subject
+       strings  that  are  subsequently processed as strings of UTF characters
+       instead of single-code-unit strings. It  is  available  when  PCRE2  is
+       built  to  include  Unicode  support (which is the default). If Unicode
+       support is not available, the use of this  option  provokes  an  error.
+       Details  of  how  PCRE2_UTF changes the behaviour of PCRE2 are given in
        the pcre2unicode page.
 
+   Extra compile options
 
-COMPILATION ERROR CODES
+       Unlike the main compile-time options, the extra options are  not  saved
+       with the compiled pattern. The option bits that can be set in a compile
+       context by calling the pcre2_set_compile_extra_options()  function  are
+       as follows:
 
-       There  are over 80 positive error codes that pcre2_compile() may return
-       (via errorcode) if it finds an error in the  pattern.  There  are  also
-       some  negative error codes that are used for invalid UTF strings. These
-       are the same as given by pcre2_match() and pcre2_dfa_match(),  and  are
-       described in the pcre2unicode page. The pcre2_get_error_message() func-
-       tion (see "Obtaining a textual error message" below) can be  called  to
-       obtain a textual error message from any error code.
+         PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES
+
+       This  option  applies when compiling a pattern in UTF-8 or UTF-32 mode.
+       It is forbidden in UTF-16 mode, and ignored in non-UTF  modes.  Unicode
+       "surrogate" code points in the range 0xd800 to 0xdfff are used in pairs
+       in UTF-16 to encode code points with values in  the  range  0x10000  to
+       0x10ffff.  The  surrogates  cannot  therefore be represented in UTF-16.
+       They can be represented in UTF-8 and UTF-32, but are defined as invalid
+       code  points,  and  cause  errors  if  encountered in a UTF-8 or UTF-32
+       string that is being checked for validity by PCRE2.
+
+       These values also cause errors if encountered in escape sequences  such
+       as \x{d912} within a pattern. However, it seems that some applications,
+       when using PCRE2 to check for unwanted  characters  in  UTF-8  strings,
+       explicitly   test  for  the  surrogates  using  escape  sequences.  The
+       PCRE2_NO_UTF_CHECK option does  not  disable  the  error  that  occurs,
+       because  it applies only to the testing of input strings for UTF valid-
+       ity.
+
+       If the extra option PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is set,  surro-
+       gate  code  point values in UTF-8 and UTF-32 patterns no longer provoke
+       errors and are incorporated in the compiled pattern. However, they  can
+       only  match  subject characters if the matching function is called with
+       PCRE2_NO_UTF_CHECK set.
+
+         PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
+
+       This is a dangerous option. Use with care. By default, an  unrecognized
+       escape  such  as \j or a malformed one such as \x{2z} causes a compile-
+       time error when detected by pcre2_compile(). Perl is somewhat inconsis-
+       tent  in  handling  such items: for example, \j is treated as a literal
+       "j", and non-hexadecimal digits in \x{} are just ignored, though  warn-
+       ings  are given in both cases if Perl's warning switch is enabled. How-
+       ever, a malformed octal number after \o{  always  causes  an  error  in
+       Perl.
+
+       If  the  PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL  extra  option  is passed to
+       pcre2_compile(), all unrecognized or  erroneous  escape  sequences  are
+       treated  as  single-character escapes. For example, \j is a literal "j"
+       and \x{2z} is treated as  the  literal  string  "x{2z}".  Setting  this
+       option  means  that  typos in patterns may go undetected and have unex-
+       pected results. This is a dangerous option. Use with care.
+
+         PCRE2_EXTRA_MATCH_LINE
+
+       This option is provided for use by  the  -x  option  of  pcre2grep.  It
+       causes  the  pattern  only to match complete lines. This is achieved by
+       automatically inserting the code for "^(?:" at the start  of  the  com-
+       piled  pattern  and ")$" at the end. Thus, when PCRE2_MULTILINE is set,
+       the matched line may be in the  middle  of  the  subject  string.  This
+       option can be used with PCRE2_LITERAL.
+
+         PCRE2_EXTRA_MATCH_WORD
+
+       This  option  is  provided  for  use  by the -w option of pcre2grep. It
+       causes the pattern only to match strings that have a word  boundary  at
+       the  start and the end. This is achieved by automatically inserting the
+       code for "\b(?:" at the start of the compiled pattern and ")\b" at  the
+       end.  The option may be used with PCRE2_LITERAL. However, it is ignored
+       if PCRE2_EXTRA_MATCH_LINE is also set.
 
 
 JUST-IN-TIME (JIT) COMPILATION
@@ -1547,53 +1814,53 @@
 
        void pcre2_jit_stack_free(pcre2_jit_stack *jit_stack);
 
-       These  functions  provide  support  for  JIT compilation, which, if the
-       just-in-time compiler is available, further processes a  compiled  pat-
+       These functions provide support for  JIT  compilation,  which,  if  the
+       just-in-time  compiler  is available, further processes a compiled pat-
        tern into machine code that executes much faster than the pcre2_match()
-       interpretive matching function. Full details are given in the  pcre2jit
+       interpretive  matching function. Full details are given in the pcre2jit
        documentation.
 
-       JIT  compilation  is  a heavyweight optimization. It can take some time
-       for patterns to be analyzed, and for one-off matches  and  simple  pat-
-       terns  the benefit of faster execution might be offset by a much slower
-       compilation time.  Most, but not all patterns can be optimized  by  the
+       JIT compilation is a heavyweight optimization. It can  take  some  time
+       for  patterns  to  be analyzed, and for one-off matches and simple pat-
+       terns the benefit of faster execution might be offset by a much  slower
+       compilation  time.  Most (but not all) patterns can be optimized by the
        JIT compiler.
 
 
 LOCALE SUPPORT
 
-       PCRE2  handles caseless matching, and determines whether characters are
-       letters, digits, or whatever, by reference to a set of tables,  indexed
-       by  character  code  point.  This applies only to characters whose code
-       points are less than 256. By default, higher-valued code  points  never
-       match  escapes  such  as \w or \d.  However, if PCRE2 is built with UTF
-       support, all characters can be tested with  \p  and  \P,  or,  alterna-
-       tively,  the  PCRE2_UCP  option  can be set when a pattern is compiled;
-       this causes \w and friends to use Unicode property support  instead  of
+       PCRE2 handles caseless matching, and determines whether characters  are
+       letters,  digits, or whatever, by reference to a set of tables, indexed
+       by character code point. This applies only  to  characters  whose  code
+       points  are  less than 256. By default, higher-valued code points never
+       match escapes such as \w or \d.  However, if PCRE2 is built  with  Uni-
+       code support, all characters can be tested with \p and \P, or, alterna-
+       tively, the PCRE2_UCP option can be set when  a  pattern  is  compiled;
+       this  causes  \w and friends to use Unicode property support instead of
        the built-in tables.
 
-       The  use  of  locales  with Unicode is discouraged. If you are handling
-       characters with code points greater than 128,  you  should  either  use
+       The use of locales with Unicode is discouraged.  If  you  are  handling
+       characters  with  code  points  greater than 128, you should either use
        Unicode support, or use locales, but not try to mix the two.
 
-       PCRE2  contains  an  internal  set of character tables that are used by
-       default.  These are sufficient for  many  applications.  Normally,  the
+       PCRE2 contains an internal set of character tables  that  are  used  by
+       default.   These  are  sufficient  for many applications. Normally, the
        internal tables recognize only ASCII characters. However, when PCRE2 is
        built, it is possible to cause the internal tables to be rebuilt in the
        default "C" locale of the local system, which may cause them to be dif-
        ferent.
 
-       The internal tables can be overridden by tables supplied by the  appli-
-       cation  that  calls  PCRE2.  These may be created in a different locale
-       from the default.  As more and more applications change to  using  Uni-
+       The  internal tables can be overridden by tables supplied by the appli-
+       cation that calls PCRE2. These may be created  in  a  different  locale
+       from  the  default.  As more and more applications change to using Uni-
        code, the need for this locale support is expected to die away.
 
-       External  tables  are built by calling the pcre2_maketables() function,
-       in the relevant locale. The result can be passed to pcre2_compile()  as
-       often   as  necessary,  by  creating  a  compile  context  and  calling
-       pcre2_set_character_tables() to set the  tables  pointer  therein.  For
-       example,  to  build  and use tables that are appropriate for the French
-       locale (where accented characters with  values  greater  than  128  are
+       External tables are built by calling the  pcre2_maketables()  function,
+       in  the relevant locale. The result can be passed to pcre2_compile() as
+       often  as  necessary,  by  creating  a  compile  context  and   calling
+       pcre2_set_character_tables()  to  set  the  tables pointer therein. For
+       example, to build and use tables that are appropriate  for  the  French
+       locale  (where  accented  characters  with  values greater than 128 are
        treated as letters), the following code could be used:
 
          setlocale(LC_CTYPE, "fr_FR");
@@ -1602,15 +1869,15 @@
          pcre2_set_character_tables(ccontext, tables);
          re = pcre2_compile(..., ccontext);
 
-       The  locale  name "fr_FR" is used on Linux and other Unix-like systems;
-       if you are using Windows, the name for the French locale  is  "french".
-       It  is the caller's responsibility to ensure that the memory containing
+       The locale name "fr_FR" is used on Linux and other  Unix-like  systems;
+       if  you  are using Windows, the name for the French locale is "french".
+       It is the caller's responsibility to ensure that the memory  containing
        the tables remains available for as long as it is needed.
 
        The pointer that is passed (via the compile context) to pcre2_compile()
-       is  saved  with  the  compiled pattern, and the same tables are used by
-       pcre2_match() and pcre_dfa_match(). Thus, for any single pattern,  com-
-       pilation,  and  matching  all  happen in the same locale, but different
+       is saved with the compiled pattern, and the same  tables  are  used  by
+       pcre2_match()  and pcre_dfa_match(). Thus, for any single pattern, com-
+       pilation and matching both happen in the  same  locale,  but  different
        patterns can be processed in different locales.
 
 
@@ -1618,14 +1885,14 @@
 
        int pcre2_pattern_info(const pcre2 *code, uint32_t what, void *where);
 
-       The pcre2_pattern_info() function returns general information  about  a
+       The  pcre2_pattern_info()  function returns general information about a
        compiled pattern. For information about callouts, see the next section.
-       The first argument for pcre2_pattern_info() is a pointer  to  the  com-
+       The  first  argument  for pcre2_pattern_info() is a pointer to the com-
        piled pattern. The second argument specifies which piece of information
-       is required, and the third argument is  a  pointer  to  a  variable  to
-       receive  the data. If the third argument is NULL, the first argument is
-       ignored, and the function returns the size in  bytes  of  the  variable
-       that is required for the information requested. Otherwise, The yield of
+       is  required,  and  the  third  argument  is a pointer to a variable to
+       receive the data. If the third argument is NULL, the first argument  is
+       ignored,  and  the  function  returns the size in bytes of the variable
+       that is required for the information requested. Otherwise, the yield of
        the function is zero for success, or one of the following negative num-
        bers:
 
@@ -1634,9 +1901,9 @@
          PCRE2_ERROR_BADOPTION      the value of what was invalid
          PCRE2_ERROR_UNSET          the requested field is not set
 
-       The  "magic  number" is placed at the start of each compiled pattern as
-       an simple check against passing an arbitrary memory pointer. Here is  a
-       typical  call of pcre2_pattern_info(), to obtain the length of the com-
+       The "magic number" is placed at the start of each compiled  pattern  as
+       an  simple check against passing an arbitrary memory pointer. Here is a
+       typical call of pcre2_pattern_info(), to obtain the length of the  com-
        piled pattern:
 
          int rc;
@@ -1651,12 +1918,16 @@
 
          PCRE2_INFO_ALLOPTIONS
          PCRE2_INFO_ARGOPTIONS
+         PCRE2_INFO_EXTRAOPTIONS
 
-       Return a copy of the pattern's options. The third argument should point
-       to a  uint32_t  variable.  PCRE2_INFO_ARGOPTIONS  returns  exactly  the
-       options  that were passed to pcre2_compile(), whereas PCRE2_INFO_ALLOP-
-       TIONS returns the compile options as modified by any  top-level  (*XXX)
-       option settings such as (*UTF) at the start of the pattern itself.
+       Return copies of the pattern's options. The third argument should point
+       to  a  uint32_t  variable.  PCRE2_INFO_ARGOPTIONS  returns  exactly the
+       options that were passed to pcre2_compile(), whereas  PCRE2_INFO_ALLOP-
+       TIONS  returns  the compile options as modified by any top-level (*XXX)
+       option settings such as (*UTF) at the  start  of  the  pattern  itself.
+       PCRE2_INFO_EXTRAOPTIONS  returns the extra options that were set in the
+       compile context by calling the pcre2_set_compile_extra_options()  func-
+       tion.
 
        For   example,   if  the  pattern  /(*UTF)abc/  is  compiled  with  the
        PCRE2_EXTENDED  option,  the  result   for   PCRE2_INFO_ALLOPTIONS   is
@@ -1681,8 +1952,8 @@
          .* is not in a capturing group that is the subject
               of a back reference
          PCRE2_DOTALL is in force for .*
-         Neither (*PRUNE) nor (*SKIP) appears in the pattern.
-         PCRE2_NO_DOTSTAR_ANCHOR is not set.
+         Neither (*PRUNE) nor (*SKIP) appears in the pattern
+         PCRE2_NO_DOTSTAR_ANCHOR is not set
 
        For  patterns  that are auto-anchored, the PCRE2_ANCHORED bit is set in
        the options returned for PCRE2_INFO_ALLOPTIONS.
@@ -1711,6 +1982,16 @@
        terns where (?| is not used, this is also the total number of capturing
        subpatterns.  The third argument should point to an uint32_t variable.
 
+         PCRE2_INFO_DEPTHLIMIT
+
+       If the pattern set a backtracking depth limit by including an  item  of
+       the  form  (*LIMIT_DEPTH=nnnn) at the start, the value is returned. The
+       third argument should point to an unsigned 32-bit integer. If  no  such
+       value  has been set, the call to pcre2_pattern_info() returns the error
+       PCRE2_ERROR_UNSET. Note that this limit will only be used during match-
+       ing  if it is less than the limit set or defaulted by the caller of the
+       match function.
+
          PCRE2_INFO_FIRSTBITMAP
 
        In the absence of a single first code unit for a non-anchored  pattern,
@@ -1727,33 +2008,53 @@
        Return information about the first code unit of any matched string, for
        a non-anchored pattern. The third argument should point to an  uint32_t
        variable.  If there is a fixed first value, for example, the letter "c"
-       from a pattern such as (cat|cow|coyote), 1 is returned, and the charac-
-       ter  value can be retrieved using PCRE2_INFO_FIRSTCODEUNIT. If there is
-       no fixed first value, but it is known that a match can  occur  only  at
-       the  start  of  the subject or following a newline in the subject, 2 is
-       returned. Otherwise, and for anchored patterns, 0 is returned.
+       from a pattern such as (cat|cow|coyote), 1 is returned, and  the  value
+       can  be  retrieved using PCRE2_INFO_FIRSTCODEUNIT. If there is no fixed
+       first value, but it is known that a match can occur only at  the  start
+       of  the  subject  or following a newline in the subject, 2 is returned.
+       Otherwise, and for anchored patterns, 0 is returned.
 
          PCRE2_INFO_FIRSTCODEUNIT
 
-       Return the value of the first code unit of any matched  string  in  the
-       situation where PCRE2_INFO_FIRSTCODETYPE returns 1; otherwise return 0.
+       Return the value of the first code unit of any  matched  string  for  a
+       pattern  where  PCRE2_INFO_FIRSTCODETYPE returns 1; otherwise return 0.
        The third argument should point to an uint32_t variable. In  the  8-bit
        library,  the  value is always less than 256. In the 16-bit library the
        value can be up to 0xffff. In the 32-bit library  in  UTF-32  mode  the
        value can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32
        mode.
 
+         PCRE2_INFO_FRAMESIZE
+
+       Return the size (in bytes) of the data frames that are used to remember
+       backtracking  positions  when the pattern is processed by pcre2_match()
+       without the use of JIT. The third argument should point  to  an  size_t
+       variable. The frame size depends on the number of capturing parentheses
+       in the pattern. Each additional capturing  group  adds  two  PCRE2_SIZE
+       variables.
+
          PCRE2_INFO_HASBACKSLASHC
 
-       Return 1 if the pattern contains any instances of \C, otherwise 0.  The
+       Return  1 if the pattern contains any instances of \C, otherwise 0. The
        third argument should point to an uint32_t variable.
 
          PCRE2_INFO_HASCRORLF
 
-       Return  1  if  the  pattern  contains any explicit matches for CR or LF
+       Return 1 if the pattern contains any explicit  matches  for  CR  or  LF
        characters, otherwise 0. The third argument should point to an uint32_t
-       variable.  An explicit match is either a literal CR or LF character, or
-       \r or \n.
+       variable. An explicit match is either a literal CR or LF character,  or
+       \r  or  \n  or  one  of  the  equivalent  hexadecimal  or  octal escape
+       sequences.
+
+         PCRE2_INFO_HEAPLIMIT
+
+       If the pattern set a heap memory limit by including an item of the form
+       (*LIMIT_HEAP=nnnn) at the start, the value is returned. The third argu-
+       ment should point to an unsigned 32-bit integer. If no such  value  has
+       been   set,   the   call  to  pcre2_pattern_info()  returns  the  error
+       PCRE2_ERROR_UNSET. Note that this limit will only be used during match-
+       ing  if it is less than the limit set or defaulted by the caller of the
+       match function.
 
          PCRE2_INFO_JCHANGED
 
@@ -1782,10 +2083,10 @@
 
          PCRE2_INFO_LASTCODEUNIT
 
-       Return  the value of the rightmost literal data unit that must exist in
-       any matched string, other than at its start, if such a value  has  been
-       recorded.  The  third argument should point to an uint32_t variable. If
-       there is no such value, 0 is returned.
+       Return  the value of the rightmost literal code unit that must exist in
+       any matched string, other than  at  its  start,  for  a  pattern  where
+       PCRE2_INFO_LASTCODETYPE returns 1. Otherwise, return 0. The third argu-
+       ment should point to an uint32_t variable.
 
          PCRE2_INFO_MATCHEMPTY
 
@@ -1801,7 +2102,9 @@
        (*LIMIT_MATCH=nnnn)  at  the  start,  the  value is returned. The third
        argument should point to an unsigned 32-bit integer. If no  such  value
        has  been  set,  the  call  to  pcre2_pattern_info()  returns the error
-       PCRE2_ERROR_UNSET.
+       PCRE2_ERROR_UNSET. Note that this limit will only be used during match-
+       ing  if it is less than the limit set or defaulted by the caller of the
+       match function.
 
          PCRE2_INFO_MAXLOOKBEHIND
 
@@ -1814,7 +2117,7 @@
        inspect the previous character. This is to ensure  that  at  least  one
        character  from  the old segment is retained when a new segment is pro-
        cessed. Otherwise, if there are no lookbehinds in the pattern, \A might
-       match incorrectly at the start of a new segment.
+       match incorrectly at the start of a second or subsequent segment.
 
          PCRE2_INFO_MINLENGTH
 
@@ -1889,24 +2192,17 @@
 
          PCRE2_INFO_NEWLINE
 
-       The output is a uint32_t with one of the following values:
+       The output is one of the following uint32_t values:
 
          PCRE2_NEWLINE_CR       Carriage return (CR)
          PCRE2_NEWLINE_LF       Linefeed (LF)
          PCRE2_NEWLINE_CRLF     Carriage return, linefeed (CRLF)
          PCRE2_NEWLINE_ANY      Any Unicode line ending
          PCRE2_NEWLINE_ANYCRLF  Any of CR, LF, or CRLF
+         PCRE2_NEWLINE_NUL      The NUL character (binary zero)
 
-       This specifies the default character sequence that will  be  recognized
-       as meaning "newline" while matching.
-
-         PCRE2_INFO_RECURSIONLIMIT
-
-       If  the  pattern set a recursion limit by including an item of the form
-       (*LIMIT_RECURSION=nnnn) at the start, the value is returned. The  third
-       argument  should  point to an unsigned 32-bit integer. If no such value
-       has been set,  the  call  to  pcre2_pattern_info()  returns  the  error
-       PCRE2_ERROR_UNSET.
+       This identifies the character sequence that will be recognized as mean-
+       ing "newline" while matching.
 
          PCRE2_INFO_SIZE
 
@@ -1962,15 +2258,15 @@
        match  data  block,  which  is  an opaque structure that is accessed by
        function calls. In particular, the match data block contains  a  vector
        of  offsets into the subject string that define the matched part of the
-       subject and any substrings that were captured.  This  is  know  as  the
+       subject and any substrings that were captured. This  is  known  as  the
        ovector.
 
        Before  calling  pcre2_match(), pcre2_dfa_match(), or pcre2_jit_match()
        you must create a match data block by calling one of the creation func-
        tions  above.  For pcre2_match_data_create(), the first argument is the
        number of pairs of offsets in the  ovector.  One  pair  of  offsets  is
-       required  to  identify  the string that matched the whole pattern, with
-       another pair for each captured substring. For example,  a  value  of  4
+       required to identify the string that matched the whole pattern, with an
+       additional pair for each captured substring. For example, a value of  4
        creates  enough space to record the matched portion of the subject plus
        three captured substrings. A minimum of at least 1 pair is  imposed  by
        pcre2_match_data_create(), so it is always possible to return the over-
@@ -2038,7 +2334,7 @@
            11,             /* the length of the subject string */
            0,              /* start at offset 0 in the subject */
            0,              /* default options */
-           match_data,     /* the match data block */
+           md,             /* the match data block */
            NULL);          /* a match context; NULL means use defaults */
 
        If  the  subject  string is zero-terminated, the length can be given as
@@ -2094,24 +2390,26 @@
        so,  and the current character is CR followed by LF, advance the start-
        ing offset by two characters instead of one.
 
-       If a non-zero starting offset is passed when the pattern  is  anchored,
-       one attempt to match at the given offset is made. This can only succeed
-       if the pattern does not require the match to be at  the  start  of  the
-       subject.
+       If a non-zero starting offset is passed when the pattern is anchored, a
+       single attempt to match at the given offset is made. This can only suc-
+       ceed if the pattern does not require the match to be at  the  start  of
+       the  subject.  In other words, the anchoring must be the result of set-
+       ting the PCRE2_ANCHORED option or the use of .* with PCRE2_DOTALL,  not
+       by starting the pattern with ^ or \A.
 
    Option bits for pcre2_match()
 
        The unused bits of the options argument for pcre2_match() must be zero.
-       The only  bits  that  may  be  set  are  PCRE2_ANCHORED,  PCRE2_NOTBOL,
-       PCRE2_NOTEOL,   PCRE2_NOTEMPTY,  PCRE2_NOTEMPTY_ATSTART,  PCRE2_NO_JIT,
-       PCRE2_NO_UTF_CHECK, PCRE2_PARTIAL_HARD, and  PCRE2_PARTIAL_SOFT.  Their
-       action is described below.
+       The only bits that may be set  are  PCRE2_ANCHORED,  PCRE2_ENDANCHORED,
+       PCRE2_NOTBOL,   PCRE2_NOTEOL,  PCRE2_NOTEMPTY,  PCRE2_NOTEMPTY_ATSTART,
+       PCRE2_NO_JIT, PCRE2_NO_UTF_CHECK,  PCRE2_PARTIAL_HARD,  and  PCRE2_PAR-
+       TIAL_SOFT.  Their action is described below.
 
-       Setting  PCRE2_ANCHORED  at match time is not supported by the just-in-
-       time (JIT) compiler. If it is set, JIT matching  is  disabled  and  the
-       normal   interpretive   code   in  pcre2_match()  is  run.  Apart  from
-       PCRE2_NO_JIT (obviously), the remaining options are supported  for  JIT
-       matching.
+       Setting  PCRE2_ANCHORED  or PCRE2_ENDANCHORED at match time is not sup-
+       ported by the just-in-time (JIT) compiler. If it is set,  JIT  matching
+       is  disabled  and  the interpretive code in pcre2_match() is run. Apart
+       from PCRE2_NO_JIT (obviously), the remaining options are supported  for
+       JIT matching.
 
          PCRE2_ANCHORED
 
@@ -2121,6 +2419,12 @@
        unachored at matching time. Note that setting the option at match  time
        disables JIT matching.
 
+         PCRE2_ENDANCHORED
+
+       If  the  PCRE2_ENDANCHORED option is set, any string that pcre2_match()
+       matches must be right at the end of the subject string. Note that  set-
+       ting the option at match time disables JIT matching.
+
          PCRE2_NOTBOL
 
        This option specifies that first character of the subject string is not
@@ -2192,11 +2496,11 @@
        checks  for  performance  reasons,  you  can set the PCRE2_NO_UTF_CHECK
        option when calling pcre2_match(). You might want to do  this  for  the
        second and subsequent calls to pcre2_match() if you are making repeated
-       calls to find all the matches in a single subject string.
+       calls to find other matches in the same subject string.
 
-       NOTE: When PCRE2_NO_UTF_CHECK is set, the effect of passing an  invalid
-       string  as a subject, or an invalid value of startoffset, is undefined.
-       Your program may crash or loop indefinitely.
+       WARNING: When PCRE2_NO_UTF_CHECK is  set,  the  effect  of  passing  an
+       invalid  string  as  a  subject, or an invalid value of startoffset, is
+       undefined.  Your program may crash or loop indefinitely.
 
          PCRE2_PARTIAL_HARD
          PCRE2_PARTIAL_SOFT
@@ -2249,11 +2553,12 @@
        acter after the first failure.
 
        An explicit match for CR of LF is either a literal appearance of one of
-       those  characters  in  the  pattern,  or  one  of  the  \r or \n escape
-       sequences. Implicit matches such as [^X] do not  count,  nor  does  \s,
-       even though it includes CR and LF in the characters that it matches.
+       those  characters  in the pattern, or one of the \r or \n or equivalent
+       octal or hexadecimal escape sequences. Implicit matches such as [^X] do
+       not  count, nor does \s, even though it includes CR and LF in the char-
+       acters that it matches.
 
-       Notwithstanding  the above, anomalous effects may still occur when CRLF
+       Notwithstanding the above, anomalous effects may still occur when  CRLF
        is a valid newline sequence and explicit \r or \n escapes appear in the
        pattern.
 
@@ -2264,85 +2569,81 @@
 
        PCRE2_SIZE *pcre2_get_ovector_pointer(pcre2_match_data *match_data);
 
-       In  general, a pattern matches a certain portion of the subject, and in
-       addition, further substrings from the subject  may  be  picked  out  by
-       parenthesized  parts  of  the  pattern.  Following the usage in Jeffrey
-       Friedl's book, this is called "capturing"  in  what  follows,  and  the
-       phrase  "capturing subpattern" or "capturing group" is used for a frag-
-       ment of a pattern that picks out a substring.  PCRE2  supports  several
+       In general, a pattern matches a certain portion of the subject, and  in
+       addition,  further  substrings  from  the  subject may be picked out by
+       parenthesized parts of the pattern.  Following  the  usage  in  Jeffrey
+       Friedl's  book,  this  is  called  "capturing" in what follows, and the
+       phrase "capturing subpattern" or "capturing group" is used for a  frag-
+       ment  of  a  pattern that picks out a substring. PCRE2 supports several
        other kinds of parenthesized subpattern that do not cause substrings to
-       be captured. The pcre2_pattern_info() function can be used to find  out
+       be  captured. The pcre2_pattern_info() function can be used to find out
        how many capturing subpatterns there are in a compiled pattern.
 
-       You  can  use  auxiliary functions for accessing captured substrings by
+       You can use auxiliary functions for accessing  captured  substrings  by
        number or by name, as described in sections below.
 
        Alternatively, you can make direct use of the vector of PCRE2_SIZE val-
-       ues,  called  the  ovector,  which  contains  the  offsets  of captured
-       strings.  It  is  part  of  the  match  data   block.    The   function
-       pcre2_get_ovector_pointer()  returns  the  address  of the ovector, and
+       ues, called  the  ovector,  which  contains  the  offsets  of  captured
+       strings.   It   is   part  of  the  match  data  block.   The  function
+       pcre2_get_ovector_pointer() returns the address  of  the  ovector,  and
        pcre2_get_ovector_count() returns the number of pairs of values it con-
        tains.
 
        Within the ovector, the first in each pair of values is set to the off-
        set of the first code unit of a substring, and the second is set to the
-       offset  of the first code unit after the end of a substring. These val-
-       ues are always code unit offsets, not character offsets. That is,  they
-       are  byte  offsets  in  the 8-bit library, 16-bit offsets in the 16-bit
+       offset of the first code unit after the end of a substring. These  val-
+       ues  are always code unit offsets, not character offsets. That is, they
+       are byte offsets in the 8-bit library, 16-bit  offsets  in  the  16-bit
        library, and 32-bit offsets in the 32-bit library.
 
-       After a partial match  (error  return  PCRE2_ERROR_PARTIAL),  only  the
-       first  pair  of  offsets  (that is, ovector[0] and ovector[1]) are set.
-       They identify the part of the subject that was partially  matched.  See
+       After  a  partial  match  (error  return PCRE2_ERROR_PARTIAL), only the
+       first pair of offsets (that is, ovector[0]  and  ovector[1])  are  set.
+       They  identify  the part of the subject that was partially matched. See
        the pcre2partial documentation for details of partial matching.
 
-       After a successful match, the first pair of offsets identifies the por-
-       tion of the subject string that was matched by the entire pattern.  The
-       next  pair  is  used for the first capturing subpattern, and so on. The
-       value returned by pcre2_match() is one more than the  highest  numbered
-       pair  that  has been set. For example, if two substrings have been cap-
-       tured, the returned value is 3. If there are no capturing  subpatterns,
-       the return value from a successful match is 1, indicating that just the
-       first pair of offsets has been set.
+       After a fully successful match, the first pair  of  offsets  identifies
+       the  portion  of the subject string that was matched by the entire pat-
+       tern. The next pair is used for the first captured  substring,  and  so
+       on.  The  value  returned by pcre2_match() is one more than the highest
+       numbered pair that has been set. For example, if  two  substrings  have
+       been  captured,  the returned value is 3. If there are no captured sub-
+       strings, the return value from a successful match is 1, indicating that
+       just the first pair of offsets has been set.
 
-       If a pattern uses the \K escape sequence within a  positive  assertion,
+       If  a  pattern uses the \K escape sequence within a positive assertion,
        the reported start of a successful match can be greater than the end of
-       the match.  For example, if the pattern  (?=ab\K)  is  matched  against
+       the  match.   For  example,  if the pattern (?=ab\K) is matched against
        "ab", the start and end offset values for the match are 2 and 0.
 
-       If  a  capturing subpattern group is matched repeatedly within a single
-       match operation, it is the last portion of the subject that it  matched
+       If a capturing subpattern group is matched repeatedly within  a  single
+       match  operation, it is the last portion of the subject that it matched
        that is returned.
 
        If the ovector is too small to hold all the captured substring offsets,
-       as much as possible is filled in, and the function returns a  value  of
-       zero.  If captured substrings are not of interest, pcre2_match() may be
+       as  much  as possible is filled in, and the function returns a value of
+       zero. If captured substrings are not of interest, pcre2_match() may  be
        called with a match data block whose ovector is of minimum length (that
-       is, one pair). However, if the pattern contains back references and the
-       ovector is not big enough to remember the related substrings, PCRE2 has
-       to  get  additional  memory for use during matching. Thus it is usually
-       advisable to set up a match data block containing an ovector of reason-
-       able size.
+       is, one pair).
 
-       It  is  possible for capturing subpattern number n+1 to match some part
+       It is possible for capturing subpattern number n+1 to match  some  part
        of the subject when subpattern n has not been used at all. For example,
-       if  the  string  "abc"  is  matched against the pattern (a|(z))(bc) the
+       if the string "abc" is matched  against  the  pattern  (a|(z))(bc)  the
        return from the function is 4, and subpatterns 1 and 3 are matched, but
-       2  is  not.  When  this happens, both values in the offset pairs corre-
+       2 is not. When this happens, both values in  the  offset  pairs  corre-
        sponding to unused subpatterns are set to PCRE2_UNSET.
 
-       Offset values that correspond to unused subpatterns at the end  of  the
-       expression  are  also  set  to  PCRE2_UNSET. For example, if the string
+       Offset  values  that correspond to unused subpatterns at the end of the
+       expression are also set to PCRE2_UNSET.  For  example,  if  the  string
        "abc" is matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3
-       are  not matched.  The return from the function is 2, because the high-
+       are not matched.  The return from the function is 2, because the  high-
        est used capturing subpattern number is 1. The offsets for for the sec-
-       ond  and  third  capturing  subpatterns  (assuming  the vector is large
+       ond and third capturing  subpatterns  (assuming  the  vector  is  large
        enough, of course) are set to PCRE2_UNSET.
 
        Elements in the ovector that do not correspond to capturing parentheses
        in the pattern are never changed. That is, if a pattern contains n cap-
        turing parentheses, no more than ovector[0] to ovector[2n+1] are set by
-       pcre2_match().  The  other  elements retain whatever values they previ-
+       pcre2_match(). The other elements retain whatever  values  they  previ-
        ously had.
 
 
@@ -2352,56 +2653,60 @@
 
        PCRE2_SIZE pcre2_get_startchar(pcre2_match_data *match_data);
 
-       As well as the offsets in the ovector, other information about a  match
-       is  retained  in the match data block and can be retrieved by the above
-       functions in appropriate circumstances. If they  are  called  at  other
+       As  well as the offsets in the ovector, other information about a match
+       is retained in the match data block and can be retrieved by  the  above
+       functions  in  appropriate  circumstances.  If they are called at other
        times, the result is undefined.
 
-       After  a  successful match, a partial match (PCRE2_ERROR_PARTIAL), or a
-       failure to match (PCRE2_ERROR_NOMATCH), a (*MARK) name  may  be  avail-
-       able,  and  pcre2_get_mark() can be called. It returns a pointer to the
-       zero-terminated name, which is within the compiled  pattern.  Otherwise
-       NULL  is returned. The length of the (*MARK) name (excluding the termi-
-       nating zero) is stored in the code unit that  preceeds  the  name.  You
-       should  use  this  instead  of  relying  on the terminating zero if the
-       (*MARK) name might contain a binary zero.
+       After a successful match, a partial match (PCRE2_ERROR_PARTIAL),  or  a
+       failure to match (PCRE2_ERROR_NOMATCH), a (*MARK), (*PRUNE), or (*THEN)
+       name may be available. The function pcre2_get_mark() can be  called  to
+       access  this  name.  The  same  function applies to all three verbs. It
+       returns a pointer to the zero-terminated name, which is within the com-
+       piled pattern. If no name is available, NULL is returned. The length of
+       the name (excluding the terminating zero) is stored in  the  code  unit
+       that  precedes  the name. You should use this length instead of relying
+       on the terminating zero if the name might contain a binary zero.
 
-       After a successful match, the (*MARK) name that is returned is the last
-       one  encountered  on the matching path through the pattern. After a "no
-       match" or a  partial  match,  the  last  encountered  (*MARK)  name  is
-       returned. For example, consider this pattern:
+       After a successful match,  the  name  that  is  returned  is  the  last
+       (*MARK),  (*PRUNE),  or  (*THEN)  name encountered on the matching path
+       through the pattern.  Instances of (*PRUNE) and (*THEN)  without  names
+       are   ignored.  Thus,  for  example,  if  the  matching  path  contains
+       (*MARK:A)(*PRUNE), the name "A" is returned.  After a "no match"  or  a
+       partial  match,  the  last  encountered name is returned.  For example,
+       consider this pattern:
 
          ^(*MARK:A)((*MARK:B)a|b)c
 
-       When  it  matches "bc", the returned mark is A. The B mark is "seen" in
-       the first branch of the group, but it is not on the matching  path.  On
-       the  other  hand,  when  this pattern fails to match "bx", the returned
-       mark is B.
+       When it matches "bc", the returned name is A. The B mark is  "seen"  in
+       the  first  branch of the group, but it is not on the matching path. On
+       the other hand, when this pattern fails to  match  "bx",  the  returned
+       name is B.
 
-       After a successful match, a partial match, or one of  the  invalid  UTF
-       errors  (for example, PCRE2_ERROR_UTF8_ERR5), pcre2_get_startchar() can
+       After  a  successful  match, a partial match, or one of the invalid UTF
+       errors (for example, PCRE2_ERROR_UTF8_ERR5), pcre2_get_startchar()  can
        be called. After a successful or partial match it returns the code unit
-       offset  of  the character at which the match started. For a non-partial
-       match, this can be different to the value of ovector[0] if the  pattern
-       contains  the  \K escape sequence. After a partial match, however, this
-       value is always the same as ovector[0] because \K does not  affect  the
+       offset of the character at which the match started. For  a  non-partial
+       match,  this can be different to the value of ovector[0] if the pattern
+       contains the \K escape sequence. After a partial match,  however,  this
+       value  is  always the same as ovector[0] because \K does not affect the
        result of a partial match.
 
-       After  a UTF check failure, pcre2_get_startchar() can be used to obtain
+       After a UTF check failure, pcre2_get_startchar() can be used to  obtain
        the code unit offset of the invalid UTF character. Details are given in
        the pcre2unicode page.
 
 
 ERROR RETURNS FROM pcre2_match()
 
-       If  pcre2_match() fails, it returns a negative number. This can be con-
-       verted to a text string by calling the pcre2_get_error_message()  func-
-       tion  (see  "Obtaining a textual error message" below).  Negative error
-       codes are also returned by other functions,  and  are  documented  with
-       them.  The codes are given names in the header file. If UTF checking is
+       If pcre2_match() fails, it returns a negative number. This can be  con-
+       verted  to a text string by calling the pcre2_get_error_message() func-
+       tion (see "Obtaining a textual error message" below).   Negative  error
+       codes  are  also  returned  by other functions, and are documented with
+       them. The codes are given names in the header file. If UTF checking  is
        in force and an invalid UTF subject string is detected, one of a number
-       of  UTF-specific negative error codes is returned. Details are given in
-       the pcre2unicode page. The following are the other errors that  may  be
+       of UTF-specific negative error codes is returned. Details are given  in
+       the  pcre2unicode  page. The following are the other errors that may be
        returned by pcre2_match():
 
          PCRE2_ERROR_NOMATCH
@@ -2410,20 +2715,21 @@
 
          PCRE2_ERROR_PARTIAL
 
-       The  subject  string did not match, but it did match partially. See the
+       The subject string did not match, but it did match partially.  See  the
        pcre2partial documentation for details of partial matching.
 
          PCRE2_ERROR_BADMAGIC
 
        PCRE2 stores a 4-byte "magic number" at the start of the compiled code,
-       to  catch  the case when it is passed a junk pointer. This is the error
+       to catch the case when it is passed a junk pointer. This is  the  error
        that is returned when the magic number is not present.
 
          PCRE2_ERROR_BADMODE
 
-       This error is given when a pattern  that  was  compiled  by  the  8-bit
-       library  is  passed  to  a  16-bit  or 32-bit library function, or vice
-       versa.
+       This  error is given when a compiled pattern is passed to a function in
+       a library of a different code unit width, for example, a  pattern  com-
+       piled  by  the  8-bit  library  is passed to a 16-bit or 32-bit library
+       function.
 
          PCRE2_ERROR_BADOFFSET
 
@@ -2447,19 +2753,19 @@
        pcre2_callout_enumerate()  to  return a distinctive error code. See the
        pcre2callout documentation for details.
 
+         PCRE2_ERROR_DEPTHLIMIT
+
+       The nested backtracking depth limit was reached.
+
+         PCRE2_ERROR_HEAPLIMIT
+
+       The heap limit was reached.
+
          PCRE2_ERROR_INTERNAL
 
        An unexpected internal error has occurred. This error could  be  caused
        by a bug in PCRE2 or by overwriting of the compiled pattern.
 
-         PCRE2_ERROR_JIT_BADOPTION
-
-       This  error  is  returned  when a pattern that was successfully studied
-       using JIT is being matched, but the matching mode (partial or  complete
-       match)  does  not  correspond to any JIT compilation mode. When the JIT
-       fast path function is used, this error may be also  given  for  invalid
-       options. See the pcre2jit documentation for more details.
-
          PCRE2_ERROR_JIT_STACKLIMIT
 
        This  error  is  returned  when a pattern that was successfully studied
@@ -2469,15 +2775,15 @@
 
          PCRE2_ERROR_MATCHLIMIT
 
-       The backtracking limit was reached.
+       The backtracking match limit was reached.
 
          PCRE2_ERROR_NOMEMORY
 
-       If a pattern contains back references,  but  the  ovector  is  not  big
-       enough  to  remember  the  referenced substrings, PCRE2 gets a block of
-       memory at the start of matching to use for this purpose. There are some
-       other  special cases where extra memory is needed during matching. This
-       error is given when memory cannot be obtained.
+       If a pattern contains many nested backtracking points, heap  memory  is
+       used  to  remember them. This error is given when the memory allocation
+       function (default or  custom)  fails.  Note  that  a  different  error,
+       PCRE2_ERROR_HEAPLIMIT,  is given if the amount of memory needed exceeds
+       the heap limit.
 
          PCRE2_ERROR_NULL
 
@@ -2493,10 +2799,6 @@
        plicated  cases,  in particular mutual recursions between two different
        subpatterns, cannot be detected until matching is attempted.
 
-         PCRE2_ERROR_RECURSIONLIMIT
-
-       The internal recursion limit was reached.
-
 
 OBTAINING A TEXTUAL ERROR MESSAGE
 
@@ -2506,16 +2808,17 @@
        A text message for an error code  from  any  PCRE2  function  (compile,
        match,  or  auxiliary)  can be obtained by calling pcre2_get_error_mes-
        sage(). The code is passed as the first argument,  with  the  remaining
-       two  arguments specifying a code unit buffer and its length, into which
-       the text message is placed. Note that the message is returned  in  code
-       units of the appropriate width for the library that is being used.
+       two  arguments  specifying  a  code  unit buffer and its length in code
+       units, into which the text message is placed. The message  is  returned
+       in  code  units  of the appropriate width for the library that is being
+       used.
 
-       The  returned message is terminated with a trailing zero, and the func-
-       tion returns the number of code  units  used,  excluding  the  trailing
+       The returned message is terminated with a trailing zero, and the  func-
+       tion  returns  the  number  of  code units used, excluding the trailing
        zero.  If  the  error  number  is  unknown,  the  negative  error  code
-       PCRE2_ERROR_BADDATA is returned. If the buffer is too small,  the  mes-
-       sage  is  truncated  (but still with a trailing zero), and the negative
-       error code PCRE2_ERROR_NOMEMORY is returned.  None of the messages  are
+       PCRE2_ERROR_BADDATA  is  returned. If the buffer is too small, the mes-
+       sage is truncated (but still with a trailing zero),  and  the  negative
+       error  code PCRE2_ERROR_NOMEMORY is returned.  None of the messages are
        very long; a buffer size of 120 code units is ample.
 
 
@@ -2534,39 +2837,39 @@
 
        void pcre2_substring_free(PCRE2_UCHAR *buffer);
 
-       Captured  substrings  can  be accessed directly by using the ovector as
+       Captured substrings can be accessed directly by using  the  ovector  as
        described above.  For convenience, auxiliary functions are provided for
-       extracting   captured  substrings  as  new,  separate,  zero-terminated
+       extracting  captured  substrings  as  new,  separate,   zero-terminated
        strings. A substring that contains a binary zero is correctly extracted
-       and  has  a  further  zero  added on the end, but the result is not, of
+       and has a further zero added on the end, but  the  result  is  not,  of
        course, a C string.
 
        The functions in this section identify substrings by number. The number
        zero refers to the entire matched substring, with higher numbers refer-
-       ring to substrings captured by parenthesized groups.  After  a  partial
-       match,  only  substring  zero  is  available. An attempt to extract any
-       other substring gives the error PCRE2_ERROR_PARTIAL. The  next  section
+       ring  to  substrings  captured by parenthesized groups. After a partial
+       match, only substring zero is available.  An  attempt  to  extract  any
+       other  substring  gives the error PCRE2_ERROR_PARTIAL. The next section
        describes similar functions for extracting captured substrings by name.
 
-       If  a  pattern uses the \K escape sequence within a positive assertion,
+       If a pattern uses the \K escape sequence within a  positive  assertion,
        the reported start of a successful match can be greater than the end of
-       the  match.   For  example,  if the pattern (?=ab\K) is matched against
-       "ab", the start and end offset values for the match are  2  and  0.  In
-       this  situation,  calling  these functions with a zero substring number
+       the match.  For example, if the pattern  (?=ab\K)  is  matched  against
+       "ab",  the  start  and  end offset values for the match are 2 and 0. In
+       this situation, calling these functions with a  zero  substring  number
        extracts a zero-length empty string.
 
-       You can find the length in code units of a captured  substring  without
-       extracting  it  by calling pcre2_substring_length_bynumber(). The first
-       argument is a pointer to the match data block, the second is the  group
-       number,  and the third is a pointer to a variable into which the length
-       is placed. If you just want to know whether or not  the  substring  has
+       You  can  find the length in code units of a captured substring without
+       extracting it by calling pcre2_substring_length_bynumber().  The  first
+       argument  is a pointer to the match data block, the second is the group
+       number, and the third is a pointer to a variable into which the  length
+       is  placed.  If  you just want to know whether or not the substring has
        been captured, you can pass the third argument as NULL.
 
-       The  pcre2_substring_copy_bynumber()  function  copies  a captured sub-
-       string into a supplied buffer,  whereas  pcre2_substring_get_bynumber()
-       copies  it  into  new memory, obtained using the same memory allocation
-       function that was used for the match data block. The  first  two  argu-
-       ments  of  these  functions are a pointer to the match data block and a
+       The pcre2_substring_copy_bynumber() function  copies  a  captured  sub-
+       string  into  a supplied buffer, whereas pcre2_substring_get_bynumber()
+       copies it into new memory, obtained using the  same  memory  allocation
+       function  that  was  used for the match data block. The first two argu-
+       ments of these functions are a pointer to the match data  block  and  a
        capturing group number.
 
        The final arguments of pcre2_substring_copy_bynumber() are a pointer to
@@ -2575,25 +2878,25 @@
        for the extracted substring, excluding the terminating zero.
 
        For pcre2_substring_get_bynumber() the third and fourth arguments point
-       to variables that are updated with a pointer to the new memory and  the
-       number  of  code units that comprise the substring, again excluding the
-       terminating zero. When the substring is no longer  needed,  the  memory
+       to  variables that are updated with a pointer to the new memory and the
+       number of code units that comprise the substring, again  excluding  the
+       terminating  zero.  When  the substring is no longer needed, the memory
        should be freed by calling pcre2_substring_free().
 
-       The  return  value  from  all these functions is zero for success, or a
-       negative error code. If the pattern match  failed,  the  match  failure
-       code  is  returned.   If  a  substring number greater than zero is used
-       after a partial match, PCRE2_ERROR_PARTIAL is returned. Other  possible
+       The return value from all these functions is zero  for  success,  or  a
+       negative  error  code.  If  the pattern match failed, the match failure
+       code is returned.  If a substring number  greater  than  zero  is  used
+       after  a partial match, PCRE2_ERROR_PARTIAL is returned. Other possible
        error codes are:
 
          PCRE2_ERROR_NOMEMORY
 
-       The  buffer  was  too small for pcre2_substring_copy_bynumber(), or the
+       The buffer was too small for  pcre2_substring_copy_bynumber(),  or  the
        attempt to get memory failed for pcre2_substring_get_bynumber().
 
          PCRE2_ERROR_NOSUBSTRING
 
-       There is no substring with that number in the  pattern,  that  is,  the
+       There  is  no  substring  with that number in the pattern, that is, the
        number is greater than the number of capturing parentheses.
 
          PCRE2_ERROR_UNAVAILABLE
@@ -2604,8 +2907,8 @@
 
          PCRE2_ERROR_UNSET
 
-       The  substring  did  not  participate in the match. For example, if the
-       pattern is (abc)|(def) and the subject is "def", and the  ovector  con-
+       The substring did not participate in the match.  For  example,  if  the
+       pattern  is  (abc)|(def) and the subject is "def", and the ovector con-
        tains at least two capturing slots, substring number 1 is unset.
 
 
@@ -2616,32 +2919,32 @@
 
        void pcre2_substring_list_free(PCRE2_SPTR *list);
 
-       The  pcre2_substring_list_get()  function  extracts  all available sub-
-       strings and builds a list of pointers to  them.  It  also  (optionally)
-       builds  a  second  list  that  contains  their lengths (in code units),
+       The pcre2_substring_list_get() function  extracts  all  available  sub-
+       strings  and  builds  a  list of pointers to them. It also (optionally)
+       builds a second list that  contains  their  lengths  (in  code  units),
        excluding a terminating zero that is added to each of them. All this is
        done in a single block of memory that is obtained using the same memory
        allocation function that was used to get the match data block.
 
-       This function must be called only after a successful match.  If  called
+       This  function  must be called only after a successful match. If called
        after a partial match, the error code PCRE2_ERROR_PARTIAL is returned.
 
-       The  address of the memory block is returned via listptr, which is also
+       The address of the memory block is returned via listptr, which is  also
        the start of the list of string pointers. The end of the list is marked
-       by  a  NULL pointer. The address of the list of lengths is returned via
-       lengthsptr. If your strings do not contain binary zeros and you do  not
+       by a NULL pointer. The address of the list of lengths is  returned  via
+       lengthsptr.  If your strings do not contain binary zeros and you do not
        therefore need the lengths, you may supply NULL as the lengthsptr argu-
-       ment to disable the creation of a list of lengths.  The  yield  of  the
-       function  is zero if all went well, or PCRE2_ERROR_NOMEMORY if the mem-
-       ory block could not be obtained. When the list is no longer needed,  it
+       ment  to  disable  the  creation of a list of lengths. The yield of the
+       function is zero if all went well, or PCRE2_ERROR_NOMEMORY if the  mem-
+       ory  block could not be obtained. When the list is no longer needed, it
        should be freed by calling pcre2_substring_list_free().
 
        If this function encounters a substring that is unset, which can happen
-       when capturing subpattern number n+1 matches some part of the  subject,
-       but  subpattern n has not been used at all, it returns an empty string.
-       This can be distinguished  from  a  genuine  zero-length  substring  by
+       when  capturing subpattern number n+1 matches some part of the subject,
+       but subpattern n has not been used at all, it returns an empty  string.
+       This  can  be  distinguished  from  a  genuine zero-length substring by
        inspecting  the  appropriate  offset  in  the  ovector,  which  contain
-       PCRE2_UNSET  for   unset   substrings,   or   by   calling   pcre2_sub-
+       PCRE2_UNSET   for   unset   substrings,   or   by   calling  pcre2_sub-
        string_length_bynumber().
 
 
@@ -2661,39 +2964,39 @@
 
        void pcre2_substring_free(PCRE2_UCHAR *buffer);
 
-       To  extract a substring by name, you first have to find associated num-
+       To extract a substring by name, you first have to find associated  num-
        ber.  For example, for this pattern:
 
          (a+)b(?<xxx>\d+)...
 
        the number of the subpattern called "xxx" is 2. If the name is known to
-       be  unique  (PCRE2_DUPNAMES  was not set), you can find the number from
+       be unique (PCRE2_DUPNAMES was not set), you can find  the  number  from
        the name by calling pcre2_substring_number_from_name(). The first argu-
-       ment  is the compiled pattern, and the second is the name. The yield of
+       ment is the compiled pattern, and the second is the name. The yield  of
        the function is the subpattern number, PCRE2_ERROR_NOSUBSTRING if there
-       is  no  subpattern  of  that  name, or PCRE2_ERROR_NOUNIQUESUBSTRING if
-       there is more than one subpattern of that name. Given the  number,  you
-       can  extract  the  substring  directly,  or  use  one  of the functions
-       described above.
+       is no subpattern of  that  name,  or  PCRE2_ERROR_NOUNIQUESUBSTRING  if
+       there  is  more than one subpattern of that name. Given the number, you
+       can extract the substring directly from the ovector, or use one of  the
+       "bynumber" functions described above.
 
-       For convenience, there are also "byname" functions that  correspond  to
-       the  "bynumber"  functions,  the  only difference being that the second
-       argument is a name instead of a number. If PCRE2_DUPNAMES  is  set  and
+       For  convenience,  there are also "byname" functions that correspond to
+       the "bynumber" functions, the only difference  being  that  the  second
+       argument  is  a  name instead of a number. If PCRE2_DUPNAMES is set and
        there are duplicate names, these functions scan all the groups with the
        given name, and return the first named string that is set.
 
-       If there are no groups with the given name, PCRE2_ERROR_NOSUBSTRING  is
-       returned.  If  all  groups  with the name have numbers that are greater
-       than the number of slots in  the  ovector,  PCRE2_ERROR_UNAVAILABLE  is
-       returned.  If  there  is at least one group with a slot in the ovector,
+       If  there are no groups with the given name, PCRE2_ERROR_NOSUBSTRING is
+       returned. If all groups with the name have  numbers  that  are  greater
+       than  the  number  of  slots in the ovector, PCRE2_ERROR_UNAVAILABLE is
+       returned. If there is at least one group with a slot  in  the  ovector,
        but no group is found to be set, PCRE2_ERROR_UNSET is returned.
 
        Warning: If the pattern uses the (?| feature to set up multiple subpat-
-       terns  with  the  same number, as described in the section on duplicate
-       subpattern numbers in the pcre2pattern page, you cannot  use  names  to
-       distinguish  the  different subpatterns, because names are not included
-       in the compiled code. The matching process uses only numbers. For  this
-       reason,  the  use of different names for subpatterns of the same number
+       terns with the same number, as described in the  section  on  duplicate
+       subpattern  numbers  in  the pcre2pattern page, you cannot use names to
+       distinguish the different subpatterns, because names are  not  included
+       in  the compiled code. The matching process uses only numbers. For this
+       reason, the use of different names for subpatterns of the  same  number
        causes an error at compile time.
 
 
@@ -2706,46 +3009,47 @@
          PCRE2_SIZE rlength, PCRE2_UCHAR *outputbufferP,
          PCRE2_SIZE *outlengthptr);
 
-       This function calls pcre2_match() and then makes a copy of the  subject
-       string  in  outputbuffer,  replacing the part that was matched with the
-       replacement string, whose length is supplied in rlength.  This  can  be
+       This  function calls pcre2_match() and then makes a copy of the subject
+       string in outputbuffer, replacing the part that was  matched  with  the
+       replacement  string,  whose  length is supplied in rlength. This can be
        given as PCRE2_ZERO_TERMINATED for a zero-terminated string. Matches in
-       which a \K item in a lookahead in the pattern causes the match  to  end
+       which  a  \K item in a lookahead in the pattern causes the match to end
        before it starts are not supported, and give rise to an error return.
 
-       The  first  seven  arguments  of pcre2_substitute() are the same as for
+       The first seven arguments of pcre2_substitute() are  the  same  as  for
        pcre2_match(), except that the partial matching options are not permit-
-       ted,  and  match_data may be passed as NULL, in which case a match data
-       block is obtained and freed within this function, using memory  manage-
-       ment  functions from the match context, if provided, or else those that
+       ted, and match_data may be passed as NULL, in which case a  match  data
+       block  is obtained and freed within this function, using memory manage-
+       ment functions from the match context, if provided, or else those  that
        were used to allocate memory for the compiled code.
 
-       The outlengthptr argument must point to a variable  that  contains  the
-       length,  in  code  units, of the output buffer. If the function is suc-
-       cessful, the value is updated to contain the length of the new  string,
+       The  outlengthptr  argument  must point to a variable that contains the
+       length, in code units, of the output buffer. If the  function  is  suc-
+       cessful,  the value is updated to contain the length of the new string,
        excluding the trailing zero that is automatically added.
 
-       If  the  function  is  not  successful,  the value set via outlengthptr
-       depends on the type of error. For  syntax  errors  in  the  replacement
-       string,  the  value  is  the offset in the replacement string where the
-       error was detected. For other  errors,  the  value  is  PCRE2_UNSET  by
-       default.  This  includes the case of the output buffer being too small,
-       unless PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set (see  below),  in  which
-       case  the  value  is the minimum length needed, including space for the
-       trailing zero. Note that in  order  to  compute  the  required  length,
-       pcre2_substitute()  has  to  simulate  all  the  matching  and copying,
+       If the function is not  successful,  the  value  set  via  outlengthptr
+       depends  on  the  type  of  error. For syntax errors in the replacement
+       string, the value is the offset in the  replacement  string  where  the
+       error  was  detected.  For  other  errors,  the value is PCRE2_UNSET by
+       default. This includes the case of the output buffer being  too  small,
+       unless  PCRE2_SUBSTITUTE_OVERFLOW_LENGTH  is  set (see below), in which
+       case the value is the minimum length needed, including  space  for  the
+       trailing  zero.  Note  that  in  order  to compute the required length,
+       pcre2_substitute() has  to  simulate  all  the  matching  and  copying,
        instead of giving an error return as soon as the buffer overflows. Note
        also that the length is in code units, not bytes.
 
-       In  the replacement string, which is interpreted as a UTF string in UTF
-       mode, and is checked for UTF  validity  unless  the  PCRE2_NO_UTF_CHECK
+       In the replacement string, which is interpreted as a UTF string in  UTF
+       mode,  and  is  checked  for UTF validity unless the PCRE2_NO_UTF_CHECK
        option is set, a dollar character is an escape character that can spec-
-       ify the insertion of characters from capturing groups or (*MARK)  items
-       in the pattern. The following forms are always recognized:
+       ify  the  insertion  of  characters  from  capturing groups or (*MARK),
+       (*PRUNE), or (*THEN) items in the  pattern.  The  following  forms  are
+       always recognized:
 
          $$                  insert a dollar character
          $<n> or ${<n>}      insert the contents of group <n>
-         $*MARK or ${*MARK}  insert the name of the last (*MARK) encountered
+         $*MARK or ${*MARK}  insert a (*MARK), (*PRUNE), or (*THEN) name
 
        Either  a  group  number  or  a  group name can be given for <n>. Curly
        brackets are required only if the following character would  be  inter-
@@ -2754,24 +3058,44 @@
        matched  with "=abc=" and the replacement string "+$1$0$1+", the result
        is "=+babcb+=".
 
-       The facility for inserting a (*MARK) name can be used to perform simple
-       simultaneous substitutions, as this pcre2test example shows:
+       $*MARK inserts the name from the last encountered (*MARK), (*PRUNE), or
+       (*THEN)  on  the  matching  path  that  has a name. (*MARK) must always
+       include a name, but (*PRUNE) and (*THEN) need not. For example, in  the
+       case   of   (*MARK:A)(*PRUNE)   the  name  inserted  is  "A",  but  for
+       (*MARK:A)(*PRUNE:B) the relevant name is "B".   This  facility  can  be
+       used  to  perform  simple simultaneous substitutions, as this pcre2test
+       example shows:
 
-         /(*:pear)apple|(*:orange)lemon/g,replace=${*MARK}
+         /(*MARK:pear)apple|(*MARK:orange)lemon/g,replace=${*MARK}
              apple lemon
           2: pear orange
 
-       As  well as the usual options for pcre2_match(), a number of additional
-       options can be set in the options argument.
+       As well as the usual options for pcre2_match(), a number of  additional
+       options can be set in the options argument of pcre2_substitute().
 
        PCRE2_SUBSTITUTE_GLOBAL causes the function to iterate over the subject
-       string,  replacing  every  matching substring. If this is not set, only
-       the first matching substring is replaced. If any matched substring  has
-       zero  length, after the substitution has happened, an attempt to find a
-       non-empty match at the same position is performed. If this is not  suc-
-       cessful,  the current position is advanced by one character except when
-       CRLF is a valid newline sequence and the next two  characters  are  CR,
-       LF. In this case, the current position is advanced by two characters.
+       string, replacing every matching substring. If this option is not  set,
+       only  the  first matching substring is replaced. The search for matches
+       takes place in the original subject string (that is, previous  replace-
+       ments  do  not  affect  it).  Iteration is implemented by advancing the
+       startoffset value for each search, which is always  passed  the  entire
+       subject string. If an offset limit is set in the match context, search-
+       ing stops when that limit is reached.
+
+       You can restrict the effect of a global substitution to  a  portion  of
+       the subject string by setting either or both of startoffset and an off-
+       set limit. Here is a pcre2test example:
+
+         /B/g,replace=!,use_offset_limit
+         ABC ABC ABC ABC\=offset=3,offset_limit=12
+          2: ABC A!C A!C ABC
+
+       When continuing with global substitutions after  matching  a  substring
+       with zero length, an attempt to find a non-empty match at the same off-
+       set is performed.  If this is not successful, the offset is advanced by
+       one character except when CRLF is a valid newline sequence and the next
+       two characters are CR, LF. In this case, the offset is advanced by  two
+       characters.
 
        PCRE2_SUBSTITUTE_OVERFLOW_LENGTH  changes  what happens when the output
        buffer is too small. The default action is to return PCRE2_ERROR_NOMEM-
@@ -2883,10 +3207,10 @@
        PCRE2_ERROR_BADREPLACEMENT  is  used for miscellaneous syntax errors in
        the   replacement   string,   with   more   particular   errors   being
        PCRE2_ERROR_BADREPESCAPE  (invalid  escape  sequence), PCRE2_ERROR_REP-
-       MISSING_BRACE (closing curly bracket not found),  PCRE2_BADSUBSTITUTION
-       (syntax  error in extended group substitution), and PCRE2_BADSUBPATTERN
-       (the pattern match ended before it started, which can happen if  \K  is
-       used in an assertion).
+       MISSINGBRACE (closing curly bracket not found),  PCRE2_ERROR_BADSUBSTI-
+       TUTION   (syntax   error   in   extended   group   substitution),   and
+       PCRE2_ERROR_BADSUBSPATTERN (the pattern match ended before it  started,
+       which can happen if \K is used in an assertion).
 
        As for all PCRE2 errors, a text message that describes the error can be
        obtained  by  calling  the  pcre2_get_error_message()   function   (see
@@ -2961,13 +3285,13 @@
 
        The function pcre2_dfa_match() is called  to  match  a  subject  string
        against  a  compiled pattern, using a matching algorithm that scans the
-       subject string just once, and does not backtrack.  This  has  different
-       characteristics  to  the  normal  algorithm, and is not compatible with
-       Perl. Some of the features of PCRE2 patterns are not supported.  Never-
-       theless,  there are times when this kind of matching can be useful. For
-       a discussion of the two matching algorithms, and  a  list  of  features
-       that pcre2_dfa_match() does not support, see the pcre2matching documen-
-       tation.
+       subject string just once (not counting lookaround assertions), and does
+       not  backtrack.  This has different characteristics to the normal algo-
+       rithm, and is not compatible with Perl. Some of the features  of  PCRE2
+       patterns  are  not  supported.  Nevertheless, there are times when this
+       kind of matching can be useful. For a discussion of  the  two  matching
+       algorithms, and a list of features that pcre2_dfa_match() does not sup-
+       port, see the pcre2matching documentation.
 
        The arguments for the pcre2_dfa_match() function are the  same  as  for
        pcre2_match(), plus two extras. The ovector within the match data block
@@ -2991,7 +3315,7 @@
            11,             /* the length of the subject string */
            0,              /* start at offset 0 in the subject */
            0,              /* default options */
-           match_data,     /* the match data block */
+           md,             /* the match data block */
            NULL,           /* a match context; NULL means use defaults */
            wspace,         /* working space vector */
            20);            /* number of elements (NOT size in bytes) */
@@ -2999,12 +3323,12 @@
    Option bits for pcre_dfa_match()
 
        The unused bits of the options argument for pcre2_dfa_match()  must  be
-       zero.  The  only bits that may be set are PCRE2_ANCHORED, PCRE2_NOTBOL,
-       PCRE2_NOTEOL,          PCRE2_NOTEMPTY,          PCRE2_NOTEMPTY_ATSTART,
-       PCRE2_NO_UTF_CHECK,       PCRE2_PARTIAL_HARD,       PCRE2_PARTIAL_SOFT,
-       PCRE2_DFA_SHORTEST, and PCRE2_DFA_RESTART. All but  the  last  four  of
-       these  are  exactly the same as for pcre2_match(), so their description
-       is not repeated here.
+       zero.  The  only  bits that may be set are PCRE2_ANCHORED, PCRE2_ENDAN-
+       CHORED,       PCRE2_NOTBOL,        PCRE2_NOTEOL,        PCRE2_NOTEMPTY,
+       PCRE2_NOTEMPTY_ATSTART,     PCRE2_NO_UTF_CHECK,     PCRE2_PARTIAL_HARD,
+       PCRE2_PARTIAL_SOFT, PCRE2_DFA_SHORTEST, and PCRE2_DFA_RESTART. All  but
+       the  last  four  of these are exactly the same as for pcre2_match(), so
+       their description is not repeated here.
 
          PCRE2_PARTIAL_HARD
          PCRE2_PARTIAL_SOFT
@@ -3093,7 +3417,7 @@
        example,  the pattern "a\d+" is compiled as if it were "a\d++". For DFA
        matching, this means that only one possible  match  is  found.  If  you
        really  do  want multiple matches in such cases, either use an ungreedy
-       repeat auch as "a\d+?" or set  the  PCRE2_NO_AUTO_POSSESS  option  when
+       repeat such as "a\d+?" or set  the  PCRE2_NO_AUTO_POSSESS  option  when
        compiling.
 
    Error returns from pcre2_dfa_match()
@@ -3138,8 +3462,7 @@
 SEE ALSO
 
        pcre2build(3),    pcre2callout(3),    pcre2demo(3),   pcre2matching(3),
-       pcre2partial(3),    pcre2posix(3),    pcre2sample(3),    pcre2stack(3),
-       pcre2unicode(3).
+       pcre2partial(3), pcre2posix(3), pcre2sample(3), pcre2unicode(3).
 
 
 AUTHOR
@@ -3151,8 +3474,8 @@
 
 REVISION
 
-       Last updated: 17 June 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 31 December 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -3198,21 +3521,21 @@
 
          ./configure --help
 
-       The  following  sections  include  descriptions  of options whose names
-       begin with --enable or --disable. These settings specify changes to the
-       defaults  for  the configure command. Because of the way that configure
-       works, --enable and --disable always come in pairs, so  the  complemen-
-       tary  option always exists as well, but as it specifies the default, it
-       is not described.
+       The  following  sections include descriptions of "on/off" options whose
+       names begin with --enable or --disable. Because of the way that config-
+       ure  works, --enable and --disable always come in pairs, so the comple-
+       mentary option always exists as well, but as it specifies the  default,
+       it is not described.  Options that specify values have names that start
+       with --with.
 
 
 BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES
 
        By default, a library called libpcre2-8 is built, containing  functions
-       that  take  string arguments contained in vectors of bytes, interpreted
+       that  take  string  arguments contained in arrays of bytes, interpreted
        either as single-byte characters, or UTF-8 strings. You can also  build
        two  other libraries, called libpcre2-16 and libpcre2-32, which process
-       strings that are contained in vectors of 16-bit and 32-bit code  units,
+       strings that are contained in arrays of 16-bit and 32-bit  code  units,
        respectively. These can be interpreted either as single-unit characters
        or UTF-16/UTF-32 strings. To build these additional libraries, add  one
        or both of the following to the configure command:
@@ -3260,11 +3583,11 @@
        application has locked this out by setting PCRE2_NEVER_UTF.
 
        UTF support allows the libraries to process character code points up to
-       0x10ffff in the strings that they handle. It also provides support  for
-       accessing  the  Unicode  properties  of  such characters, using pattern
-       escapes such as \P, \p, and \X. Only the  general  category  properties
-       such  as Lu and Nd are supported. Details are given in the pcre2pattern
-       documentation.
+       0x10ffff in the strings that they handle. Unicode  support  also  gives
+       access  to  the Unicode properties of characters, using pattern escapes
+       such as \P, \p, and \X. Only the general category properties such as Lu
+       and  Nd are supported. Details are given in the pcre2pattern documenta-
+       tion.
 
        Pattern escapes such as \d and \w do not by default make use of Unicode
        properties.  The  application  can  request that they do by setting the
@@ -3287,15 +3610,21 @@
 
 JUST-IN-TIME COMPILER SUPPORT
 
-       Just-in-time compiler support is included in the build by specifying
+       Just-in-time  (JIT) compiler support is included in the build by speci-
+       fying
 
          --enable-jit
 
-       This  support  is available only for certain hardware architectures. If
-       this option is set for an unsupported architecture,  a  building  error
-       occurs.   See the pcre2jit documentation for a discussion of JIT usage.
-       When JIT support is enabled, pcre2grep automatically makes use  of  it,
-       unless you add
+       This support is available only for certain hardware  architectures.  If
+       this  option  is  set for an unsupported architecture, a building error
+       occurs. If you are running under SELinux you may also want to add
+
+         --enable-jit-sealloc
+
+       which enables the use of an execmem allocator in JIT that is compatible
+       with  SELinux.  This  has  no  effect  if  JIT  is not enabled. See the
+       pcre2jit documentation for a discussion of JIT usage. When JIT  support
+       is enabled, pcre2grep automatically makes use of it, unless you add
 
          --disable-pcre2grep-jit
 
@@ -3325,7 +3654,7 @@
          --enable-newline-is-anycrlf
 
        which  causes  PCRE2 to recognize any of the three sequences CR, LF, or
-       CRLF as indicating a line ending. Finally, a fifth option, specified by
+       CRLF as indicating a line ending. A fifth option, specified by
 
          --enable-newline-is-any
 
@@ -3333,144 +3662,148 @@
        newline sequences are the three just mentioned, plus the single charac-
        ters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line,
        U+0085),  LS  (line  separator,  U+2028),  and PS (paragraph separator,
-       U+2029).
+       U+2029). The final option is
+
+         --enable-newline-is-nul
+
+       which causes NUL (binary zero) is set as the default line-ending  char-
+       acter.
 
        Whatever default line ending convention is selected when PCRE2 is built
-       can  be  overridden by applications that use the library. At build time
-       it is conventional to use the standard for your operating system.
+       can be overridden by applications that use the library. At  build  time
+       it is recommended to use the standard for your operating system.
 
 
 WHAT \R MATCHES
 
-       By default, the sequence \R in a pattern matches  any  Unicode  newline
-       sequence,  independently  of  what has been selected as the line ending
+       By  default,  the  sequence \R in a pattern matches any Unicode newline
+       sequence, independently of what has been selected as  the  line  ending
        sequence. If you specify
 
          --enable-bsr-anycrlf
 
-       the default is changed so that \R matches only CR, LF, or  CRLF.  What-
-       ever  is selected when PCRE2 is built can be overridden by applications
-       that use the called.
+       the  default  is changed so that \R matches only CR, LF, or CRLF. What-
+       ever is selected when PCRE2 is built can be overridden by  applications
+       that use the library.
 
 
 HANDLING VERY LARGE PATTERNS
 
-       Within a compiled pattern, offset values are used  to  point  from  one
-       part  to another (for example, from an opening parenthesis to an alter-
-       nation metacharacter). By default, in the 8-bit and  16-bit  libraries,
-       two-byte  values  are used for these offsets, leading to a maximum size
-       for a compiled pattern of around 64K code units. This is sufficient  to
+       Within  a  compiled  pattern,  offset values are used to point from one
+       part to another (for example, from an opening parenthesis to an  alter-
+       nation  metacharacter).  By default, in the 8-bit and 16-bit libraries,
+       two-byte values are used for these offsets, leading to a  maximum  size
+       for  a compiled pattern of around 64K code units. This is sufficient to
        handle all but the most gigantic patterns. Nevertheless, some people do
-       want to process truly enormous patterns, so it is possible  to  compile
-       PCRE2  to  use three-byte or four-byte offsets by adding a setting such
+       want  to  process truly enormous patterns, so it is possible to compile
+       PCRE2 to use three-byte or four-byte offsets by adding a  setting  such
        as
 
          --with-link-size=3
 
-       to the configure command. The value given must be 2, 3, or 4.  For  the
-       16-bit  library,  a  value of 3 is rounded up to 4. In these libraries,
-       using longer offsets slows down the operation of PCRE2 because  it  has
-       to  load additional data when handling them. For the 32-bit library the
-       value is always 4 and cannot be overridden; the value  of  --with-link-
+       to  the  configure command. The value given must be 2, 3, or 4. For the
+       16-bit library, a value of 3 is rounded up to 4.  In  these  libraries,
+       using  longer  offsets slows down the operation of PCRE2 because it has
+       to load additional data when handling them. For the 32-bit library  the
+       value  is  always 4 and cannot be overridden; the value of --with-link-
        size is ignored.
 
 
-AVOIDING EXCESSIVE STACK USAGE
-
-       When  matching  with the pcre2_match() function, PCRE2 implements back-
-       tracking by making recursive  calls  to  an  internal  function  called
-       match().  In  environments where the size of the stack is limited, this
-       can severely limit PCRE2's operation. (The Unix  environment  does  not
-       usually  suffer from this problem, but it may sometimes be necessary to
-       increase  the  maximum  stack  size.  There  is  a  discussion  in  the
-       pcre2stack  documentation.)  An  alternative approach to recursion that
-       uses memory from the heap to remember data, instead of using  recursive
-       function  calls, has been implemented to work round the problem of lim-
-       ited stack size. If you want to build a version  of  PCRE2  that  works
-       this way, add
-
-         --disable-stack-for-recursion
-
-       to the configure command. By default, the system functions malloc() and
-       free() are called to manage the heap memory that is required, but  cus-
-       tom  memory  management  functions  can  be  called instead. PCRE2 runs
-       noticeably more slowly when built in this way. This option affects only
-       the pcre2_match() function; it is not relevant for pcre2_dfa_match().
-
-
 LIMITING PCRE2 RESOURCE USAGE
 
-       Internally, PCRE2 has a function called match(), which it calls repeat-
-       edly  (sometimes  recursively)  when  matching  a  pattern   with   the
-       pcre2_match() function. By controlling the maximum number of times this
-       function may be called during a single matching operation, a limit  can
-       be  placed on the resources used by a single call to pcre2_match(). The
-       limit can be changed at run time, as described in the pcre2api documen-
-       tation.  The default is 10 million, but this can be changed by adding a
-       setting such as
+       The pcre2_match() function increments a counter each time it goes round
+       its  main  loop. Putting a limit on this counter controls the amount of
+       computing resource used by a single call to  pcre2_match().  The  limit
+       can be changed at run time, as described in the pcre2api documentation.
+       The default is 10 million, but this can be changed by adding a  setting
+       such as
 
          --with-match-limit=500000
 
-       to  the  configure  command.  This  setting  has  no  effect   on   the
-       pcre2_dfa_match() matching function.
+       to   the   configure   command.   This  setting  also  applies  to  the
+       pcre2_dfa_match() matching function, and to JIT  matching  (though  the
+       counting is done differently).
 
-       In  some  environments  it is desirable to limit the depth of recursive
-       calls of match() more strictly than the total number of calls, in order
-       to  restrict  the maximum amount of stack (or heap, if --disable-stack-
-       for-recursion is specified) that is used. A second limit controls this;
-       it  defaults  to  the  value  that is set for --with-match-limit, which
-       imposes no additional constraints. However, you can set a  lower  limit
-       by adding, for example,
+       The  pcre2_match() function starts out using a 20K vector on the system
+       stack to record  backtracking  points.  The  more  nested  backtracking
+       points there are (that is, the deeper the search tree), the more memory
+       is needed. If the initial vector is not large enough,  heap  memory  is
+       used, up to a certain limit, which is specified in kilobytes. The limit
+       can be changed at run time, as described in the pcre2api documentation.
+       The  default  limit (in effect unlimited) is 20 million. You can change
+       this by a setting such as
 
-         --with-match-limit-recursion=10000
+         --with-heap-limit=500
 
-       to  the  configure  command.  This  value can also be overridden at run
-       time.
+       which limits the amount of heap to 500 kilobytes.  This  limit  applies
+       only  to interpretive matching in pcre2_match(). It does not apply when
+       JIT (which has its own memory arrangements) is used, nor does it  apply
+       to pcre2_dfa_match().
+
+       You  can  also explicitly limit the depth of nested backtracking in the
+       pcre2_match() interpreter. This limit defaults to the value that is set
+       for  --with-match-limit.  You  can set a lower default limit by adding,
+       for example,
+
+         --with-match-limit_depth=10000
+
+       to the configure command. This value can be  overridden  at  run  time.
+       This  depth  limit  indirectly limits the amount of heap memory that is
+       used, but because the size of each backtracking "frame" depends on  the
+       number  of  capturing parentheses in a pattern, the amount of heap that
+       is used before the limit is reached varies  from  pattern  to  pattern.
+       This  limit  was  more  useful in versions before 10.30, where function
+       recursion was used for backtracking.
+
+       As well as applying to pcre2_match(), the depth limit also controls the
+       depth  of recursive function calls in pcre2_dfa_match(). These are used
+       for lookaround assertions, atomic groups,  and  recursion  within  pat-
+       terns.  The limit does not apply to JIT matching.
 
 
 CREATING CHARACTER TABLES AT BUILD TIME
 
        PCRE2 uses fixed tables for processing characters whose code points are
        less than 256. By default, PCRE2 is built with a set of tables that are
-       distributed in the file src/pcre2_chartables.c.dist. These  tables  are
+       distributed  in  the file src/pcre2_chartables.c.dist. These tables are
        for ASCII codes only. If you add
 
          --enable-rebuild-chartables
 
-       to  the  configure  command, the distributed tables are no longer used.
-       Instead, a program called dftables is compiled and  run.  This  outputs
+       to the configure command, the distributed tables are  no  longer  used.
+       Instead,  a  program  called dftables is compiled and run. This outputs
        the source for new set of tables, created in the default locale of your
-       C run-time system. (This method of replacing the tables does  not  work
-       if  you are cross compiling, because dftables is run on the local host.
-       If you need to create alternative tables when cross compiling, you will
-       have to do so "by hand".)
+       C run-time system. This method of replacing the tables does not work if
+       you are cross compiling, because dftables is run on the local host.  If
+       you  need  to  create alternative tables when cross compiling, you will
+       have to do so "by hand".
 
 
 USING EBCDIC CODE
 
-       PCRE2  assumes  by default that it will run in an environment where the
-       character code is ASCII or Unicode, which is a superset of ASCII.  This
+       PCRE2 assumes by default that it will run in an environment  where  the
+       character  code is ASCII or Unicode, which is a superset of ASCII. This
        is the case for most computer operating systems. PCRE2 can, however, be
        compiled to run in an 8-bit EBCDIC environment by adding
 
          --enable-ebcdic --disable-unicode
 
        to the configure command. This setting implies --enable-rebuild-charta-
-       bles.  You  should  only  use  it if you know that you are in an EBCDIC
+       bles. You should only use it if you know that  you  are  in  an  EBCDIC
        environment (for example, an IBM mainframe operating system).
 
-       It is not possible to support both EBCDIC and UTF-8 codes in  the  same
-       version  of  the  library. Consequently, --enable-unicode and --enable-
+       It  is  not possible to support both EBCDIC and UTF-8 codes in the same
+       version of the library. Consequently,  --enable-unicode  and  --enable-
        ebcdic are mutually exclusive.
 
        The EBCDIC character that corresponds to an ASCII LF is assumed to have
-       the  value  0x15 by default. However, in some EBCDIC environments, 0x25
+       the value 0x15 by default. However, in some EBCDIC  environments,  0x25
        is used. In such an environment you should use
 
          --enable-ebcdic-nl25
 
        as well as, or instead of, --enable-ebcdic. The EBCDIC character for CR
-       has  the  same  value  as in ASCII, namely, 0x0d. Whichever of 0x15 and
+       has the same value as in ASCII, namely, 0x0d.  Whichever  of  0x15  and
        0x25 is not chosen as LF is made to correspond to the Unicode NEL char-
        acter (which, in Unicode, is 0x85).
 
@@ -3483,39 +3816,44 @@
 
        By default, on non-Windows systems, pcre2grep supports the use of call-
        outs with string arguments within the patterns it is matching, in order
-       to  run external scripts. For details, see the pcre2grep documentation.
-       This support can be disabled by adding  --disable-pcre2grep-callout  to
+       to run external scripts. For details, see the pcre2grep  documentation.
+       This  support  can be disabled by adding --disable-pcre2grep-callout to
        the configure command.
 
 
 PCRE2GREP OPTIONS FOR COMPRESSED FILE SUPPORT
 
-       By  default,  pcre2grep reads all files as plain text. You can build it
-       so that it recognizes files whose names end in .gz or .bz2,  and  reads
+       By default, pcre2grep reads all files as plain text. You can  build  it
+       so  that  it recognizes files whose names end in .gz or .bz2, and reads
        them with libz or libbz2, respectively, by adding one or both of
 
          --enable-pcre2grep-libz
          --enable-pcre2grep-libbz2
 
        to the configure command. These options naturally require that the rel-
-       evant libraries are installed on your system. Configuration  will  fail
+       evant  libraries  are installed on your system. Configuration will fail
        if they are not.
 
 
 PCRE2GREP BUFFER SIZE
 
-       pcre2grep  uses an internal buffer to hold a "window" on the file it is
+       pcre2grep uses an internal buffer to hold a "window" on the file it  is
        scanning, in order to be able to output "before" and "after" lines when
-       it  finds  a match. The size of the buffer is controlled by a parameter
-       whose default value is 20K. The buffer itself is three times this size,
-       but because of the way it is used for holding "before" lines, the long-
-       est line that is guaranteed to be processable is  the  parameter  size.
-       You can change the default parameter value by adding, for example,
+       it finds a match. The starting size of the buffer is  controlled  by  a
+       parameter  whose default value is 20K. The buffer itself is three times
+       this size, but because of the way  it  is  used  for  holding  "before"
+       lines,  the  longest  line  that is guaranteed to be processable is the
+       parameter size. If a longer line is  encountered,  pcre2grep  automati-
+       cally expands the buffer, up to a specified maximum size, whose default
+       is 1M or the starting size, whichever is the larger. You can change the
+       default parameter values by adding, for example,
 
-         --with-pcre2grep-bufsize=50K
+         --with-pcre2grep-bufsize=51200
+         --with-pcre2grep-max-bufsize=2097152
 
-       to  the  configure  command.  The caller of pcre2grep can override this
-       value by using --buffer-size on the command line.
+       to  the  configure  command. The caller of pcre2grep can override these
+       values by using --buffer-size  and  --max-buffer-size  on  the  command
+       line.
 
 
 PCRE2TEST OPTION FOR LIBREADLINE SUPPORT
@@ -3525,26 +3863,26 @@
          --enable-pcre2test-libreadline
          --enable-pcre2test-libedit
 
-       to the configure command, pcre2test  is  linked  with  the  libreadline
+       to  the  configure  command,  pcre2test  is linked with the libreadline
        orlibedit library, respectively, and when its input is from a terminal,
-       it reads it using the readline() function. This  provides  line-editing
-       and  history  facilities.  Note that libreadline is GPL-licensed, so if
-       you distribute a binary of pcre2test linked in this way, there  may  be
+       it  reads  it using the readline() function. This provides line-editing
+       and history facilities. Note that libreadline is  GPL-licensed,  so  if
+       you  distribute  a binary of pcre2test linked in this way, there may be
        licensing issues. These can be avoided by linking instead with libedit,
        which has a BSD licence.
 
-       Setting --enable-pcre2test-libreadline causes the -lreadline option  to
-       be  added to the pcre2test build. In many operating environments with a
-       sytem-installed readline library this is sufficient. However,  in  some
+       Setting  --enable-pcre2test-libreadline causes the -lreadline option to
+       be added to the pcre2test build. In many operating environments with  a
+       sytem-installed  readline  library this is sufficient. However, in some
        environments (e.g. if an unmodified distribution version of readline is
-       in use), some extra configuration may be necessary.  The  INSTALL  file
+       in  use),  some  extra configuration may be necessary. The INSTALL file
        for libreadline says this:
 
          "Readline uses the termcap functions, but does not link with
          the termcap or curses library itself, allowing applications
          which link with readline the to choose an appropriate library."
 
-       If  your environment has not been set up so that an appropriate library
+       If your environment has not been set up so that an appropriate  library
        is automatically included, you may need to add something like
 
          LIBS="-ncurses"
@@ -3558,7 +3896,7 @@
 
          --enable-debug
 
-       to the configure command, additional debugging code is included in  the
+       to  the configure command, additional debugging code is included in the
        build. This feature is intended for use by the PCRE2 maintainers.
 
 
@@ -3568,15 +3906,15 @@
 
          --enable-valgrind
 
-       to  the  configure command, PCRE2 will use valgrind annotations to mark
-       certain memory regions as  unaddressable.  This  allows  it  to  detect
-       invalid  memory  accesses,  and  is  mostly  useful for debugging PCRE2
+       to the configure command, PCRE2 will use valgrind annotations  to  mark
+       certain  memory  regions  as  unaddressable.  This  allows it to detect
+       invalid memory accesses, and  is  mostly  useful  for  debugging  PCRE2
        itself.
 
 
 CODE COVERAGE REPORTING
 
-       If your C compiler is gcc, you can build a version of  PCRE2  that  can
+       If  your  C  compiler is gcc, you can build a version of PCRE2 that can
        generate a code coverage report for its test suite. To enable this, you
        must install lcov version 1.6 or above. Then specify
 
@@ -3585,20 +3923,20 @@
        to the configure command and build PCRE2 in the usual way.
 
        Note that using ccache (a caching C compiler) is incompatible with code
-       coverage  reporting. If you have configured ccache to run automatically
+       coverage reporting. If you have configured ccache to run  automatically
        on your system, you must set the environment variable
 
          CCACHE_DISABLE=1
 
        before running make to build PCRE2, so that ccache is not used.
 
-       When --enable-coverage is used,  the  following  addition  targets  are
+       When  --enable-coverage  is  used,  the  following addition targets are
        added to the Makefile:
 
          make coverage
 
-       This  creates  a  fresh coverage report for the PCRE2 test suite. It is
-       equivalent to running "make coverage-reset", "make  coverage-baseline",
+       This creates a fresh coverage report for the PCRE2 test  suite.  It  is
+       equivalent  to running "make coverage-reset", "make coverage-baseline",
        "make check", and then "make coverage-report".
 
          make coverage-reset
@@ -3615,21 +3953,59 @@
 
          make coverage-clean-report
 
-       This  removes the generated coverage report without cleaning the cover-
+       This removes the generated coverage report without cleaning the  cover-
        age data itself.
 
          make coverage-clean-data
 
-       This removes the captured coverage data without removing  the  coverage
+       This  removes  the captured coverage data without removing the coverage
        files created at compile time (*.gcno).
 
          make coverage-clean
 
-       This  cleans all coverage data including the generated coverage report.
-       For more information about code coverage, see the gcov and  lcov  docu-
+       This cleans all coverage data including the generated coverage  report.
+       For  more  information about code coverage, see the gcov and lcov docu-
        mentation.
 
 
+SUPPORT FOR FUZZERS
+
+       There is a special option for use by people who  want  to  run  fuzzing
+       tests on PCRE2:
+
+         --enable-fuzz-support
+
+       At present this applies only to the 8-bit library. If set, it causes an
+       extra library  called  libpcre2-fuzzsupport.a  to  be  built,  but  not
+       installed.  This contains a single function called LLVMFuzzerTestOneIn-
+       put() whose arguments are a pointer to a string and the length  of  the
+       string.  When  called,  this  function tries to compile the string as a
+       pattern, and if that succeeds, to match it.  This is done both with  no
+       options  and  with some random options bits that are generated from the
+       string.
+
+       Setting --enable-fuzz-support also causes  a  binary  called  pcre2fuz-
+       zcheck  to be created. This is normally run under valgrind or used when
+       PCRE2 is compiled with address sanitizing enabled. It calls the fuzzing
+       function  and  outputs information about it is doing. The input strings
+       are specified by arguments: if an argument starts with "=" the rest  of
+       it  is  a  literal  input string. Otherwise, it is assumed to be a file
+       name, and the contents of the file are the test string.
+
+
+OBSOLETE OPTION
+
+       In versions of PCRE2 prior to 10.30, there were two  ways  of  handling
+       backtracking  in the pcre2_match() function. The default was to use the
+       system stack, but if
+
+         --disable-stack-for-recursion
+
+       was set, memory on the heap was used. From release 10.30  onwards  this
+       has  changed  (the  stack  is  no longer used) and this option now does
+       nothing except give a warning.
+
+
 SEE ALSO
 
        pcre2api(3), pcre2-config(3).
@@ -3644,8 +4020,8 @@
 
 REVISION
 
-       Last updated: 01 April 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 18 July 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -3689,14 +4065,22 @@
 
        If the PCRE2_AUTO_CALLOUT option bit is set when a pattern is compiled,
        PCRE2 automatically inserts callouts, all with number 255, before  each
-       item  in  the  pattern. For example, if PCRE2_AUTO_CALLOUT is used with
-       the pattern
+       item  in the pattern except for immediately before or after an explicit
+       callout. For example, if PCRE2_AUTO_CALLOUT is used with the pattern
 
-         A(\d{2}|--)
+         A(?C3)B
 
        it is processed as if it were
 
-       (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
+         (?C255)A(?C3)B(?C255)
+
+       Here is a more complicated example:
+
+         A(\d{2}|--)
+
+       With PCRE2_AUTO_CALLOUT, this pattern is processed as if it were
+
+         (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
 
        Notice that there is a callout before and after  each  parenthesis  and
        alternation bar. If the pattern contains a conditional group whose con-
@@ -3737,10 +4121,11 @@
          No match
 
        This indicates that when matching [bc] fails, there is no  backtracking
-       into  a+  and  therefore the callouts that would be taken for the back-
-       tracks do not occur.  You can disable the  auto-possessify  feature  by
-       passing  PCRE2_NO_AUTO_POSSESS to pcre2_compile(), or starting the pat-
-       tern with (*NO_AUTO_POSSESS). In this case, the output changes to this:
+       into a+ (because it is being treated as a++) and therefore the callouts
+       that would be taken for the backtracks do not occur.  You  can  disable
+       the   auto-possessify   feature  by  passing  PCRE2_NO_AUTO_POSSESS  to
+       pcre2_compile(), or starting the pattern  with  (*NO_AUTO_POSSESS).  In
+       this case, the output changes to this:
 
          --->aaaa
           +0 ^        a+
@@ -3756,14 +4141,17 @@
    Automatic .* anchoring
 
        By default, an optimization is applied when .* is the first significant
-       item in a pattern. If PCRE2_DOTALL is set, so that the  dot  can  match
-       any  character,  the pattern is automatically anchored. If PCRE2_DOTALL
-       is not set, a match can start only after an internal newline or at  the
-       beginning  of  the  subject,  and  pcre2_compile() remembers this. This
-       optimization is disabled, however, if .* is in an atomic  group  or  if
-       there  is  a back reference to the capturing group in which it appears.
-       It is also disabled if the pattern contains (*PRUNE) or  (*SKIP).  How-
-       ever, the presence of callouts does not affect it.
+       item  in  a  pattern. If PCRE2_DOTALL is set, so that the dot can match
+       any character, the pattern is automatically anchored.  If  PCRE2_DOTALL
+       is  not set, a match can start only after an internal newline or at the
+       beginning of the subject, and pcre2_compile() remembers this. If a pat-
+       tern  has more than one top-level branch, automatic anchoring occurs if
+       all branches are anchorable.
+
+       This optimization is disabled, however, if .* is in an atomic group  or
+       if  there  is  a  back  reference  to  the  capturing group in which it
+       appears. It is also  disabled  if  the  pattern  contains  (*PRUNE)  or
+       (*SKIP). However, the presence of callouts does not affect it.
 
        For  example,  if  the pattern .*\d is compiled with PCRE2_AUTO_CALLOUT
        and applied to the string "aa", the pcre2test output is:
@@ -3795,46 +4183,45 @@
        ter.   Another  optimization, described in the next section, means that
        there is no subsequent attempt to match with an empty subject.
 
-       If a pattern has more than one top-level  branch,  automatic  anchoring
-       occurs if all branches are anchorable.
-
    Other optimizations
 
-       Other  optimizations  that  provide fast "no match" results also affect
+       Other optimizations that provide fast "no match"  results  also  affect
        callouts.  For example, if the pattern is
 
          ab(?C4)cd
 
-       PCRE2 knows that any matching string must contain the  letter  "d".  If
-       the  subject  string  is  "abyz",  the  lack of "d" means that matching
-       doesn't ever start, and the callout is  never  reached.  However,  with
+       PCRE2  knows  that  any matching string must contain the letter "d". If
+       the subject string is "abyz", the  lack  of  "d"  means  that  matching
+       doesn't  ever  start,  and  the callout is never reached. However, with
        "abyd", though the result is still no match, the callout is obeyed.
 
-       PCRE2  also  knows  the  minimum  length of a matching string, and will
-       immediately give a "no match" return without actually running  a  match
-       if  the  subject is not long enough, or, for unanchored patterns, if it
-       has been scanned far enough.
+       For most patterns PCRE2 also knows the minimum  length  of  a  matching
+       string,  and will immediately give a "no match" return without actually
+       running a match if the subject is not long enough, or,  for  unanchored
+       patterns, if it has been scanned far enough.
 
        You can disable these optimizations by passing the PCRE2_NO_START_OPTI-
-       MIZE  option  to  pcre2_compile(),  or  by  starting  the  pattern with
-       (*NO_START_OPT). This slows down the matching process, but does  ensure
+       MIZE option  to  pcre2_compile(),  or  by  starting  the  pattern  with
+       (*NO_START_OPT).  This slows down the matching process, but does ensure
        that callouts such as the example above are obeyed.
 
 
 THE CALLOUT INTERFACE
 
-       During  matching,  when  PCRE2  reaches a callout point, if an external
-       function is set in the match context, it is  called.  This  applies  to
-       both  normal  and DFA matching. The first argument to the callout func-
-       tion is a pointer to a pcre2_callout block. The second argument is  the
-       void  *  callout  data that was supplied when the callout was set up by
-       calling pcre2_set_callout() (see the pcre2api documentation). The call-
-       out block structure contains the following fields:
+       During matching, when PCRE2 reaches a callout  point,  if  an  external
+       function  is  provided in the match context, it is called. This applies
+       to both normal, DFA, and JIT matching. The first argument to the  call-
+       out function is a pointer to a pcre2_callout block. The second argument
+       is the void * callout data that was supplied when the callout  was  set
+       up by calling pcre2_set_callout() (see the pcre2api documentation). The
+       callout block structure contains the following fields, not  necessarily
+       in this order:
 
          uint32_t      version;
          uint32_t      callout_number;
          uint32_t      capture_top;
          uint32_t      capture_last;
+         uint32_t      callout_flags;
          PCRE2_SIZE   *offset_vector;
          PCRE2_SPTR    mark;
          PCRE2_SPTR    subject;
@@ -3848,19 +4235,19 @@
          PCRE2_SPTR    callout_string;
 
        The  version field contains the version number of the block format. The
-       current version is 1; the three callout string fields  were  added  for
-       this  version. If you are writing an application that might use an ear-
-       lier release of PCRE2, you  should  check  the  version  number  before
-       accessing  any  of  these  fields.  The version number will increase in
-       future if more fields are added, but the intention is never  to  remove
-       any of the existing fields.
+       current version is 2; the three callout string fields  were  added  for
+       version  1, and the callout_flags field for version 2. If you are writ-
+       ing an application that might use an  earlier  release  of  PCRE2,  you
+       should  check  the version number before accessing any of these fields.
+       The version number will increase in future if more  fields  are  added,
+       but the intention is never to remove any of the existing fields.
 
    Fields for numerical callouts
 
        For  a  numerical  callout,  callout_string is NULL, and callout_number
        contains the number of the callout, in the range  0-255.  This  is  the
-       number  that  follows  (?C for manual callouts; it is 255 for automati-
-       cally generated callouts.
+       number  that  follows  (?C for callouts that part of the pattern; it is
+       255 for automatically generated callouts.
 
    Fields for string callouts
 
@@ -3885,74 +4272,123 @@
        The remaining fields in the callout block are the same for  both  kinds
        of callout.
 
-       The offset_vector field is a pointer to the vector of capturing offsets
-       (the "ovector") that was passed to the matching function in  the  match
-       data  block.  When pcre2_match() is used, the contents can be inspected
-       in order to extract substrings that have been matched so  far,  in  the
-       same  way as for extracting substrings after a match has completed. For
-       the DFA matching function, this field is not useful.
+       The  offset_vector  field is a pointer to a vector of capturing offsets
+       (the "ovector"). You may read the elements in this vector, but you must
+       not change any of them.
+
+       For  calls  to  pcre2_match(),  the  offset_vector  field is not (since
+       release 10.30) a pointer to the actual ovector that was passed  to  the
+       matching  function  in  the  match  data block. Instead it points to an
+       internal ovector of a size large enough to hold all  possible  captured
+       substrings in the pattern. Note that whenever a recursion or subroutine
+       call within a pattern completes, the capturing state is reset  to  what
+       it was before.
+
+       The  capture_last  field  contains the number of the most recently cap-
+       tured substring, and the capture_top field contains one more  than  the
+       number  of  the  highest numbered captured substring so far. If no sub-
+       strings have yet been captured, the value of capture_last is 0 and  the
+       value  of  capture_top  is  1. The values of these fields do not always
+       differ  by  one;  for  example,  when  the  callout  in   the   pattern
+       ((a)(b))(?C2) is taken, capture_last is 1 but capture_top is 4.
+
+       The   contents  of  ovector[2]  to  ovector[<capture_top>*2-1]  can  be
+       inspected in order to extract substrings that have been matched so far,
+       in  the  same way as extracting substrings after a match has completed.
+       The values in ovector[0] and ovector[1] are always PCRE2_UNSET  because
+       the  match is by definition not complete. Substrings that have not been
+       captured but whose numbers are less than capture_top also have both  of
+       their ovector slots set to PCRE2_UNSET.
+
+       For  DFA  matching,  the offset_vector field points to the ovector that
+       was passed to the matching function in the match  data  block,  but  it
+       holds  no  useful information at callout time because pcre2_dfa_match()
+       does not support substring  capturing.  The  value  of  capture_top  is
+       always 1 and the value of capture_last is always 0 for DFA matching.
 
        The subject and subject_length fields contain copies of the values that
        were passed to the matching function.
 
-       The  start_match  field normally contains the offset within the subject
-       at which the current match attempt  started.  However,  if  the  escape
-       sequence  \K has been encountered, this value is changed to reflect the
-       modified starting point. If the pattern is not  anchored,  the  callout
+       The start_match field normally contains the offset within  the  subject
+       at  which  the  current  match  attempt started. However, if the escape
+       sequence \K has been encountered, this value is changed to reflect  the
+       modified  starting  point.  If the pattern is not anchored, the callout
        function may be called several times from the same point in the pattern
        for different starting points in the subject.
 
-       The current_position field contains the offset within  the  subject  of
+       The  current_position  field  contains the offset within the subject of
        the current match pointer.
 
-       When the pcre2_match() is used, the capture_top field contains one more
-       than the number of the highest numbered captured substring so  far.  If
-       no substrings have been captured, the value of capture_top is one. This
-       is always the case when the DFA functions are used, because they do not
-       support captured substrings.
-
-       The  capture_last  field  contains the number of the most recently cap-
-       tured substring. However, when a recursion exits, the value reverts  to
-       what  it  was  outside  the recursion, as do the values of all captured
-       substrings. If no substrings have been  captured,  the  value  of  cap-
-       ture_last is 0. This is always the case for the DFA matching functions.
-
        The pattern_position field contains the offset in the pattern string to
        the next item to be matched.
 
-       The next_item_length field contains the length of the next item  to  be
-       matched in the pattern string. When the callout immediately precedes an
-       alternation bar, a closing parenthesis, or the end of the pattern,  the
-       length  is  zero. When the callout precedes an opening parenthesis, the
-       length is that of the entire subpattern.
+       The  next_item_length  field contains the length of the next item to be
+       processed in the pattern string. When the callout is at the end of  the
+       pattern,  the  length  is  zero.  When  the callout precedes an opening
+       parenthesis, the length includes meta characters that follow the paren-
+       thesis.  For  example,  in a callout before an assertion such as (?=ab)
+       the length is 3. For an an alternation bar or  a  closing  parenthesis,
+       the  length is one, unless a closing parenthesis is followed by a quan-
+       tifier, in which case its length is included.  (This changed in release
+       10.23.  In  earlier  releases, before an opening parenthesis the length
+       was that of the entire subpattern, and before an alternation bar  or  a
+       closing parenthesis the length was zero.)
 
-       The pattern_position and next_item_length fields are intended  to  help
-       in  distinguishing between different automatic callouts, which all have
-       the same callout number. However, they are set for  all  callouts,  and
+       The  pattern_position  and next_item_length fields are intended to help
+       in distinguishing between different automatic callouts, which all  have
+       the  same  callout  number. However, they are set for all callouts, and
        are used by pcre2test to show the next item to be matched when display-
        ing callout information.
 
        In callouts from pcre2_match() the mark field contains a pointer to the
-       zero-terminated  name of the most recently passed (*MARK), (*PRUNE), or
-       (*THEN) item in the match, or NULL if no such items have  been  passed.
-       Instances  of  (*PRUNE)  or  (*THEN) without a name do not obliterate a
+       zero-terminated name of the most recently passed (*MARK), (*PRUNE),  or
+       (*THEN)  item  in the match, or NULL if no such items have been passed.
+       Instances of (*PRUNE) or (*THEN) without a name  do  not  obliterate  a
        previous (*MARK). In callouts from the DFA matching function this field
        always contains NULL.
 
+       The   callout_flags   field   is   always   zero   in   callouts   from
+       pcre2_dfa_match() or when JIT is being used. When pcre2_match() without
+       JIT is used, the following bits may be set:
+
+         PCRE2_CALLOUT_STARTMATCH
+
+       This is set for the first callout after the start of matching for  each
+       new starting position in the subject.
+
+         PCRE2_CALLOUT_BACKTRACK
+
+       This  is  set if there has been a matching backtrack since the previous
+       callout, or since the start of matching if this is  the  first  callout
+       from a pcre2_match() run.
+
+       Both  bits  are  set when a backtrack has caused a "bumpalong" to a new
+       starting position in the subject. Output from pcre2test does not  indi-
+       cate  the  presence  of these bits unless the callout_extra modifier is
+       set.
+
+       The information in the callout_flags field is provided so that applica-
+       tions  can track and tell their users how matching with backtracking is
+       done. This can be useful when trying to optimize patterns, or  just  to
+       understand  how  PCRE2  works. There is no support in pcre2_dfa_match()
+       because there is no backtracking in DFA matching, and there is no  sup-
+       port in JIT because JIT is all about maximimizing matching performance.
+       In both these cases the callout_flags field is always zero.
+
 
 RETURN VALUES FROM CALLOUTS
 
        The external callout function returns an integer to PCRE2. If the value
-       is zero, matching proceeds as normal. If  the  value  is  greater  than
-       zero,  matching  fails  at  the current point, but the testing of other
+       is  zero,  matching  proceeds  as  normal. If the value is greater than
+       zero, matching fails at the current point, but  the  testing  of  other
        matching possibilities goes ahead, just as if a lookahead assertion had
        failed. If the value is less than zero, the match is abandoned, and the
        matching function returns the negative value.
 
-       Negative  values  should  normally  be   chosen   from   the   set   of
-       PCRE2_ERROR_xxx  values.  In  particular,  PCRE2_ERROR_NOMATCH forces a
-       standard "no match" failure. The error  number  PCRE2_ERROR_CALLOUT  is
-       reserved  for  use by callout functions; it will never be used by PCRE2
+       Negative   values   should   normally   be   chosen  from  the  set  of
+       PCRE2_ERROR_xxx values. In  particular,  PCRE2_ERROR_NOMATCH  forces  a
+       standard  "no  match"  failure. The error number PCRE2_ERROR_CALLOUT is
+       reserved for use by callout functions; it will never be used  by  PCRE2
        itself.
 
 
@@ -3963,14 +4399,14 @@
          void *user_data);
 
        A script language that supports the use of string arguments in callouts
-       might  like  to  scan  all the callouts in a pattern before running the
+       might like to scan all the callouts in a  pattern  before  running  the
        match. This can be done by calling pcre2_callout_enumerate(). The first
-       argument  is  a  pointer  to a compiled pattern, the second points to a
-       callback function, and the third is arbitrary user data.  The  callback
-       function  is  called  for  every callout in the pattern in the order in
+       argument is a pointer to a compiled pattern, the  second  points  to  a
+       callback  function,  and the third is arbitrary user data. The callback
+       function is called for every callout in the pattern  in  the  order  in
        which they appear. Its first argument is a pointer to a callout enumer-
-       ation  block,  and  its second argument is the user_data value that was
-       passed to pcre2_callout_enumerate(). The data block contains  the  fol-
+       ation block, and its second argument is the user_data  value  that  was
+       passed  to  pcre2_callout_enumerate(). The data block contains the fol-
        lowing fields:
 
          version                Block version number
@@ -3981,17 +4417,17 @@
          callout_string_length  Length of callout string
          callout_string         Points to callout string or is NULL
 
-       The  version  number is currently 0. It will increase if new fields are
-       ever added to the block. The remaining fields are  the  same  as  their
-       namesakes  in  the pcre2_callout block that is used for callouts during
+       The version number is currently 0. It will increase if new  fields  are
+       ever  added  to  the  block. The remaining fields are the same as their
+       namesakes in the pcre2_callout block that is used for  callouts  during
        matching, as described above.
 
-       Note that the value of pattern_position is  unique  for  each  callout.
-       However,  if  a callout occurs inside a group that is quantified with a
+       Note  that  the  value  of pattern_position is unique for each callout.
+       However, if a callout occurs inside a group that is quantified  with  a
        non-zero minimum or a fixed maximum, the group is replicated inside the
-       compiled  pattern.  For example, a pattern such as /(a){2}/ is compiled
-       as if it were /(a)(a)/. This means that the callout will be  enumerated
-       more  than  once,  but with the same value for pattern_position in each
+       compiled pattern. For example, a pattern such as /(a){2}/  is  compiled
+       as  if it were /(a)(a)/. This means that the callout will be enumerated
+       more than once, but with the same value for  pattern_position  in  each
        case.
 
        The callback function should normally return zero. If it returns a non-
@@ -4008,8 +4444,8 @@
 
 REVISION
 
-       Last updated: 23 March 2015
-       Copyright (c) 1997-2015 University of Cambridge.
+       Last updated: 22 December 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -4024,45 +4460,46 @@
 
        This document describes the differences in the ways that PCRE2 and Perl
        handle regular expressions. The differences  described  here  are  with
-       respect to Perl versions 5.10 and above.
+       respect  to Perl versions 5.26, but as both Perl and PCRE2 are continu-
+       ally changing, the information may sometimes be out of date.
 
-       1.  PCRE2  has only a subset of Perl's Unicode support. Details of what
+       1. PCRE2 has only a subset of Perl's Unicode support. Details  of  what
        it does have are given in the pcre2unicode page.
 
-       2. PCRE2 allows repeat quantifiers only  on  parenthesized  assertions,
-       but  they  do not mean what you might think. For example, (?!a){3} does
-       not assert that the next three characters are not "a". It just  asserts
-       that  the  next  character  is not "a" three times (in principle: PCRE2
-       optimizes this to run the assertion  just  once).  Perl  allows  repeat
-       quantifiers  on  other  assertions such as \b, but these do not seem to
-       have any use.
+       2.  Like  Perl, PCRE2 allows repeat quantifiers on parenthesized asser-
+       tions, but they do not mean what you might think. For example, (?!a){3}
+       does  not  assert  that  the next three characters are not "a". It just
+       asserts that the next character is not "a" three times  (in  principle:
+       PCRE2  optimizes this to run the assertion just once). Perl allows some
+       repeat quantifiers on other  assertions,  for  example,  \b*  (but  not
+       \b{3}), but these do not seem to have any use.
 
-       3. Capturing subpatterns that occur inside  negative  lookahead  asser-
-       tions  are  counted,  but their entries in the offsets vector are never
-       set. Perl sometimes (but not always) sets its numerical variables  from
-       inside negative assertions.
+       3.  Capturing  subpatterns that occur inside negative lookaround asser-
+       tions are counted, but their entries in the offsets vector are set only
+       when  a  negative  assertion  is a condition that has a matching branch
+       (that is, the condition is false).
 
-       4.  The  following Perl escape sequences are not supported: \l, \u, \L,
-       \U, and \N when followed by a character name or Unicode value.  (\N  on
+       4. The following Perl escape sequences are not supported: \l,  \u,  \L,
+       \U,  and  \N when followed by a character name or Unicode value. (\N on
        its own, matching a non-newline character, is supported.) In fact these
-       are implemented by Perl's general string-handling and are not  part  of
-       its  pattern matching engine. If any of these are encountered by PCRE2,
+       are  implemented  by Perl's general string-handling and are not part of
+       its pattern matching engine. If any of these are encountered by  PCRE2,
        an error is generated by default. However, if the PCRE2_ALT_BSUX option
        is set, \U and \u are interpreted as ECMAScript interprets them.
 
        5. The Perl escape sequences \p, \P, and \X are supported only if PCRE2
-       is built with Unicode support. The properties that can be  tested  with
-       \p and \P are limited to the general category properties such as Lu and
-       Nd, script names such as Greek or Han, and the derived  properties  Any
-       and L&. PCRE2 does support the Cs (surrogate) property, which Perl does
-       not; the Perl documentation says "Because Perl hides the need  for  the
-       user  to  understand the internal representation of Unicode characters,
-       there is no need to implement the  somewhat  messy  concept  of  surro-
-       gates."
+       is built with Unicode support (the default). The properties that can be
+       tested with \p and \P are limited to the  general  category  properties
+       such  as  Lu and Nd, script names such as Greek or Han, and the derived
+       properties Any and L&.  PCRE2 does support the Cs (surrogate) property,
+       which  Perl  does  not; the Perl documentation says "Because Perl hides
+       the need for the user to understand the internal representation of Uni-
+       code  characters, there is no need to implement the somewhat messy con-
+       cept of surrogates."
 
-       6.  PCRE2 does support the \Q...\E escape for quoting substrings. Char-
-       acters in between are treated as literals. This is  slightly  different
-       from  Perl  in  that  $  and  @ are also handled as literals inside the
+       6. PCRE2 does support the \Q...\E escape for quoting substrings.  Char-
+       acters  in  between are treated as literals. This is slightly different
+       from Perl in that $ and @ are  also  handled  as  literals  inside  the
        quotes. In Perl, they cause variable interpolation (but of course PCRE2
        does not have variables).  Note the following examples:
 
@@ -4073,22 +4510,17 @@
            \Qabc\$xyz\E       abc\$xyz          abc\$xyz
            \Qabc\E\$\Qxyz\E   abc$xyz           abc$xyz
 
-       The  \Q...\E  sequence  is recognized both inside and outside character
+       The \Q...\E sequence is recognized both inside  and  outside  character
        classes.
 
-       7.  Fairly  obviously,  PCRE2  does  not  support  the  (?{code})   and
-       (??{code})  constructions. However, there is support for recursive pat-
-       terns. This is not available in Perl 5.8, but it is in Perl 5.10. Also,
-       the  PCRE2  "callout"  feature allows an external function to be called
-       during  pattern  matching.  See  the  pcre2callout  documentation   for
-       details.
+       7.   Fairly  obviously,  PCRE2  does  not  support  the  (?{code})  and
+       (??{code}) constructions. However, there is support  PCRE2's  "callout"
+       feature,  which allows an external function to be called during pattern
+       matching. See the pcre2callout documentation for details.
 
-       8.  Subroutine  calls  (whether recursive or not) are treated as atomic
-       groups.  Atomic recursion is like Python,  but  unlike  Perl.  Captured
-       values  that  are  set outside a subroutine call can be referenced from
-       inside in PCRE2, but not in Perl. There is a discussion  that  explains
-       these  differences  in  more detail in the section on recursion differ-
-       ences from Perl in the pcre2pattern page.
+       8. Subroutine calls (whether recursive or not) were treated  as  atomic
+       groups  up to PCRE2 release 10.23, but from release 10.30 this changed,
+       and backtracking into subroutine calls is now supported, as in Perl.
 
        9. If any of the backtracking control verbs are used  in  a  subpattern
        that  is  called  as  a  subroutine (whether or not recursively), their
@@ -4103,7 +4535,7 @@
        first one that is backtracked onto acts. For example,  in  the  pattern
        A(*COMMIT)B(*PRUNE)C  a  failure in B triggers (*COMMIT), but a failure
        in C triggers (*PRUNE). Perl's behaviour is more complex; in many cases
-       it is the same as PCRE2, but there are examples where it differs.
+       it is the same as PCRE2, but there are cases where it differs.
 
        11.  Most  backtracking  verbs in assertions have their normal actions.
        They are not confined to the assertion.
@@ -4117,18 +4549,18 @@
        pattern names is not as general as Perl's. This is a consequence of the
        fact  the  PCRE2  works internally just with numbers, using an external
        table to translate between numbers and names. In particular, a  pattern
-       such  as  (?|(?<a>A)|(?<b)B),  where the two capturing parentheses have
+       such  as  (?|(?<a>A)|(?<b>B),  where the two capturing parentheses have
        the same number but different names, is not supported,  and  causes  an
        error  at compile time. If it were allowed, it would not be possible to
        distinguish which parentheses matched, because both names map  to  cap-
        turing subpattern number 1. To avoid this confusing situation, an error
        is given at compile time.
 
-       14. Perl recognizes comments in some places that PCRE2  does  not,  for
-       example,  between  the  ( and ? at the start of a subpattern. If the /x
-       modifier is set, Perl allows white space between ( and ?  (though  cur-
-       rent  Perls warn that this is deprecated) but PCRE2 never does, even if
-       the PCRE2_EXTENDED option is set.
+       14. Perl used to recognize comments in some places that PCRE2 does not,
+       for  example,  between the ( and ? at the start of a subpattern. If the
+       /x modifier is set, Perl allowed white space between ( and ? though the
+       latest  Perls give an error (for a while it was just deprecated). There
+       may still be some cases where Perl behaves differently.
 
        15. Perl, when in warning mode, gives warnings  for  character  classes
        such  as  [A-\d] or [a-[:digit:]]. It then treats the hyphens as liter-
@@ -4138,50 +4570,67 @@
        16.  In  PCRE2, the upper/lower case character properties Lu and Ll are
        not affected when case-independent matching is specified. For  example,
        \p{Lu} always matches an upper case letter. I think Perl has changed in
-       this respect; in the release at the time of writing (5.16), \p{Lu}  and
+       this respect; in the release at the time of writing (5.24), \p{Lu}  and
        \p{Ll} match all letters, regardless of case, when case independence is
        specified.
 
        17. PCRE2 provides some  extensions  to  the  Perl  regular  expression
        facilities.   Perl  5.10  includes new features that are not in earlier
-       versions of Perl, some of which (such as named parentheses)  have  been
-       in PCRE2 for some time. This list is with respect to Perl 5.10:
+       versions of Perl, some of which (such as  named  parentheses)  were  in
+       PCRE2 for some time before. This list is with respect to Perl 5.26:
 
        (a)  Although  lookbehind  assertions  in PCRE2 must match fixed length
        strings, each alternative branch of a lookbehind assertion can match  a
        different  length  of  string.  Perl requires them all to have the same
        length.
 
-       (b) If PCRE2_DOLLAR_ENDONLY is set and PCRE2_MULTILINE is not set,  the
+       (b) From PCRE2 10.23, back references to groups  of  fixed  length  are
+       supported in lookbehinds, provided that there is no possibility of ref-
+       erencing a non-unique number or name. Perl does not support  backrefer-
+       ences in lookbehinds.
+
+       (c)  If PCRE2_DOLLAR_ENDONLY is set and PCRE2_MULTILINE is not set, the
        $ meta-character matches only at the very end of the string.
 
-       (c)  A  backslash  followed  by  a  letter  with  no special meaning is
+       (d) A backslash followed  by  a  letter  with  no  special  meaning  is
        faulted. (Perl can be made to issue a warning.)
 
-       (d) If PCRE2_UNGREEDY is set, the greediness of the repetition  quanti-
+       (e)  If PCRE2_UNGREEDY is set, the greediness of the repetition quanti-
        fiers is inverted, that is, by default they are not greedy, but if fol-
        lowed by a question mark they are.
 
-       (e) PCRE2_ANCHORED can be used at matching time to force a  pattern  to
+       (f)  PCRE2_ANCHORED  can be used at matching time to force a pattern to
        be tried only at the first matching position in the subject string.
 
-       (f)      The      PCRE2_NOTBOL,      PCRE2_NOTEOL,      PCRE2_NOTEMPTY,
-       PCRE2_NOTEMPTY_ATSTART, and PCRE2_NO_AUTO_CAPTURE options have no  Perl
-       equivalents.
+       (g)    The    PCRE2_NOTBOL,    PCRE2_NOTEOL,     PCRE2_NOTEMPTY     and
+       PCRE2_NOTEMPTY_ATSTART options have no Perl equivalents.
 
-       (g)  The  \R escape sequence can be restricted to match only CR, LF, or
+       (h)  The  \R escape sequence can be restricted to match only CR, LF, or
        CRLF by the PCRE2_BSR_ANYCRLF option.
 
-       (h) The callout facility is PCRE2-specific.
+       (i) The callout facility is PCRE2-specific.  Perl  supports  codeblocks
+       and variable interpolation, but not general hooks on every match.
 
-       (i) The partial matching facility is PCRE2-specific.
+       (j) The partial matching facility is PCRE2-specific.
 
-       (j) The alternative matching function (pcre2_dfa_match() matches  in  a
+       (k)  The  alternative matching function (pcre2_dfa_match() matches in a
        different way and is not Perl-compatible.
 
-       (k)  PCRE2 recognizes some special sequences such as (*CR) at the start
-       of a pattern that set overall options that cannot be changed within the
-       pattern.
+       (l) PCRE2 recognizes some special sequences such as (*CR) or  (*NO_JIT)
+       at  the  start  of  a  pattern  that set overall options that cannot be
+       changed within the pattern.
+
+       18. The Perl /a modifier restricts /d numbers to pure  ascii,  and  the
+       /aa  modifier  restricts  /i  case-insensitive  matching to pure ascii,
+       ignoring Unicode rules. This  separation  cannot  be  represented  with
+       PCRE2_UCP.
+
+       19. Perl has different limits than PCRE2. See the pcre2limit documenta-
+       tion for details. Perl went with 5.10 from recursion to iteration keep-
+       ing the intermediate matches on the heap, which is ~10% slower but does
+       not fall into any stack-overflow limit. PCRE2 made a similar change  at
+       release  10.30,  and also has many build-time and run-time customizable
+       limits.
 
 
 AUTHOR
@@ -4193,8 +4642,8 @@
 
 REVISION
 
-       Last updated: 15 March 2015
-       Copyright (c) 1997-2015 University of Cambridge.
+       Last updated: 18 April 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -4342,8 +4791,8 @@
        The error code PCRE2_ERROR_MATCHLIMIT is returned by the  JIT  code  if
        searching  a  very large pattern tree goes on for too long, as it is in
        the same circumstance when JIT is not used, but the details of  exactly
-       what  is counted are not the same. The PCRE2_ERROR_RECURSIONLIMIT error
-       code is never returned when JIT matching is used.
+       what is counted are not the same. The PCRE2_ERROR_DEPTHLIMIT error code
+       is never returned when JIT matching is used.
 
 
 CONTROLLING THE JIT STACK
@@ -4362,13 +4811,10 @@
        It returns a pointer to an opaque structure of type pcre2_jit_stack, or
        NULL if there is an error. The pcre2_jit_stack_free() function is  used
        to  free a stack that is no longer needed. (For the technically minded:
-       the address space is allocated by mmap or VirtualAlloc.)
+       the address space is allocated by  mmap  or  VirtualAlloc.)  A  maximum
+       stack size of 512K to 1M should be more than enough for any pattern.
 
-       JIT uses far less memory for recursion than the interpretive code,  and
-       a  maximum  stack size of 512K to 1M should be more than enough for any
-       pattern.
-
-       The pcre2_jit_stack_assign() function specifies which  stack  JIT  code
+       The  pcre2_jit_stack_assign()  function  specifies which stack JIT code
        should use. Its arguments are as follows:
 
          pcre2_match_context  *mcontext
@@ -4377,7 +4823,7 @@
 
        The first argument is a pointer to a match context. When this is subse-
        quently passed to a matching function, its information determines which
-       JIT  stack  is  used. There are three cases for the values of the other
+       JIT stack is used. There are three cases for the values  of  the  other
        two options:
 
          (1) If callback is NULL and data is NULL, an internal 32K block
@@ -4395,34 +4841,34 @@
              return value must be a valid JIT stack, the result of calling
              pcre2_jit_stack_create().
 
-       A callback function is obeyed whenever JIT code is about to be run;  it
+       A  callback function is obeyed whenever JIT code is about to be run; it
        is not obeyed when pcre2_match() is called with options that are incom-
-       patible for JIT matching. A callback function can therefore be used  to
-       determine  whether  a  match  operation  was  executed by JIT or by the
+       patible  for JIT matching. A callback function can therefore be used to
+       determine whether a match operation was  executed  by  JIT  or  by  the
        interpreter.
 
        You may safely use the same JIT stack for more than one pattern (either
-       by  assigning  directly  or  by  callback), as long as the patterns are
+       by assigning directly or by callback), as  long  as  the  patterns  are
        matched sequentially in the same thread. Currently, the only way to set
-       up  non-sequential matches in one thread is to use callouts: if a call-
-       out function starts another match, that match must use a different  JIT
+       up non-sequential matches in one thread is to use callouts: if a  call-
+       out  function starts another match, that match must use a different JIT
        stack to the one used for currently suspended match(es).
 
-       In  a multithread application, if you do not specify a JIT stack, or if
-       you assign or pass back NULL from  a  callback,  that  is  thread-safe,
-       because  each  thread has its own machine stack. However, if you assign
-       or pass back a non-NULL JIT stack, this must be a different  stack  for
+       In a multithread application, if you do not specify a JIT stack, or  if
+       you  assign  or  pass  back  NULL from a callback, that is thread-safe,
+       because each thread has its own machine stack. However, if  you  assign
+       or  pass  back a non-NULL JIT stack, this must be a different stack for
        each thread so that the application is thread-safe.
 
-       Strictly  speaking,  even more is allowed. You can assign the same non-
-       NULL stack to a match context that is used by any number  of  patterns,
-       as  long  as  they are not used for matching by multiple threads at the
-       same time. For example, you could use the same stack  in  all  compiled
-       patterns,  with  a global mutex in the callback to wait until the stack
+       Strictly speaking, even more is allowed. You can assign the  same  non-
+       NULL  stack  to a match context that is used by any number of patterns,
+       as long as they are not used for matching by multiple  threads  at  the
+       same  time.  For  example, you could use the same stack in all compiled
+       patterns, with a global mutex in the callback to wait until  the  stack
        is available for use. However, this is an inefficient solution, and not
        recommended.
 
-       This  is a suggestion for how a multithreaded program that needs to set
+       This is a suggestion for how a multithreaded program that needs to  set
        up non-default JIT stacks might operate:
 
          During thread initalization
@@ -4434,7 +4880,7 @@
          Use a one-line callback function
            return thread_local_var
 
-       All the functions described in this section do nothing if  JIT  is  not
+       All  the  functions  described in this section do nothing if JIT is not
        available.
 
 
@@ -4443,20 +4889,20 @@
        (1) Why do we need JIT stacks?
 
        PCRE2 (and JIT) is a recursive, depth-first engine, so it needs a stack
-       where the local data of the current node is pushed before checking  its
+       where  the local data of the current node is pushed before checking its
        child nodes.  Allocating real machine stack on some platforms is diffi-
        cult. For example, the stack chain needs to be updated every time if we
-       extend  the  stack  on  PowerPC.  Although it is possible, its updating
+       extend the stack on PowerPC.  Although it  is  possible,  its  updating
        time overhead decreases performance. So we do the recursion in memory.
 
        (2) Why don't we simply allocate blocks of memory with malloc()?
 
-       Modern operating systems have a  nice  feature:  they  can  reserve  an
+       Modern  operating  systems  have  a  nice  feature: they can reserve an
        address space instead of allocating memory. We can safely allocate mem-
-       ory pages inside this address space, so the stack  could  grow  without
+       ory  pages  inside  this address space, so the stack could grow without
        moving memory data (this is important because of pointers). Thus we can
-       allocate 1M address space, and use only a single memory  page  (usually
-       4K)  if  that is enough. However, we can still grow up to 1M anytime if
+       allocate  1M  address space, and use only a single memory page (usually
+       4K) if that is enough. However, we can still grow up to 1M  anytime  if
        needed.
 
        (3) Who "owns" a JIT stack?
@@ -4464,8 +4910,8 @@
        The owner of the stack is the user program, not the JIT studied pattern
        or anything else. The user program must ensure that if a stack is being
        used by pcre2_match(), (that is, it is assigned to a match context that
-       is  passed  to  the  pattern currently running), that stack must not be
-       used by any other threads (to avoid overwriting the same memory  area).
+       is passed to the pattern currently running), that  stack  must  not  be
+       used  by any other threads (to avoid overwriting the same memory area).
        The best practice for multithreaded programs is to allocate a stack for
        each thread, and return this stack through the JIT callback function.
 
@@ -4473,36 +4919,36 @@
 
        You can free a JIT stack at any time, as long as it will not be used by
        pcre2_match() again. When you assign the stack to a match context, only
-       a pointer is set. There is no reference counting or  any  other  magic.
+       a  pointer  is  set. There is no reference counting or any other magic.
        You can free compiled patterns, contexts, and stacks in any order, any-
-       time. Just do not call pcre2_match() with a match context  pointing  to
+       time.  Just  do not call pcre2_match() with a match context pointing to
        an already freed stack, as that will cause SEGFAULT. (Also, do not free
-       a stack currently used by pcre2_match() in  another  thread).  You  can
-       also  replace the stack in a context at any time when it is not in use.
+       a  stack  currently  used  by pcre2_match() in another thread). You can
+       also replace the stack in a context at any time when it is not in  use.
        You should free the previous stack before assigning a replacement.
 
-       (5) Should I allocate/free a  stack  every  time  before/after  calling
+       (5)  Should  I  allocate/free  a  stack every time before/after calling
        pcre2_match()?
 
-       No,  because  this  is  too  costly in terms of resources. However, you
-       could implement some clever idea which release the stack if it  is  not
-       used  in  let's  say  two minutes. The JIT callback can help to achieve
+       No, because this is too costly in  terms  of  resources.  However,  you
+       could  implement  some clever idea which release the stack if it is not
+       used in let's say two minutes. The JIT callback  can  help  to  achieve
        this without keeping a list of patterns.
 
-       (6) OK, the stack is for long term memory allocation. But what  happens
-       if  a pattern causes stack overflow with a stack of 1M? Is that 1M kept
+       (6)  OK, the stack is for long term memory allocation. But what happens
+       if a pattern causes stack overflow with a stack of 1M? Is that 1M  kept
        until the stack is freed?
 
-       Especially on embedded sytems, it might be a good idea to release  mem-
-       ory  sometimes  without  freeing the stack. There is no API for this at
-       the moment.  Probably a function call which returns with the  currently
-       allocated  memory for any stack and another which allows releasing mem-
+       Especially  on embedded sytems, it might be a good idea to release mem-
+       ory sometimes without freeing the stack. There is no API  for  this  at
+       the  moment.  Probably a function call which returns with the currently
+       allocated memory for any stack and another which allows releasing  mem-
        ory (shrinking the stack) would be a good idea if someone needs this.
 
        (7) This is too much of a headache. Isn't there any better solution for
        JIT stack handling?
 
-       No,  thanks to Windows. If POSIX threads were used everywhere, we could
+       No, thanks to Windows. If POSIX threads were used everywhere, we  could
        throw out this complicated API.
 
 
@@ -4511,18 +4957,18 @@
        void pcre2_jit_free_unused_memory(pcre2_general_context *gcontext);
 
        The JIT executable allocator does not free all memory when it is possi-
-       ble.   It expects new allocations, and keeps some free memory around to
-       improve allocation speed. However, in low memory conditions,  it  might
-       be  better to free all possible memory. You can cause this to happen by
-       calling pcre2_jit_free_unused_memory(). Its argument is a general  con-
+       ble.  It expects new allocations, and keeps some free memory around  to
+       improve  allocation  speed. However, in low memory conditions, it might
+       be better to free all possible memory. You can cause this to happen  by
+       calling  pcre2_jit_free_unused_memory(). Its argument is a general con-
        text, for custom memory management, or NULL for standard memory manage-
        ment.
 
 
 EXAMPLE CODE
 
-       This is a single-threaded example that specifies a  JIT  stack  without
-       using  a  callback.  A real program should include error checking after
+       This  is  a  single-threaded example that specifies a JIT stack without
+       using a callback. A real program should include  error  checking  after
        all the function calls.
 
          int rc;
@@ -4550,29 +4996,29 @@
 JIT FAST PATH API
 
        Because the API described above falls back to interpreted matching when
-       JIT  is  not  available, it is convenient for programs that are written
+       JIT is not available, it is convenient for programs  that  are  written
        for  general  use  in  many  environments.  However,  calling  JIT  via
        pcre2_match() does have a performance impact. Programs that are written
-       for use where JIT is known to be available, and  which  need  the  best
-       possible  performance,  can  instead  use a "fast path" API to call JIT
-       matching directly instead of calling pcre2_match() (obviously only  for
+       for  use  where  JIT  is known to be available, and which need the best
+       possible performance, can instead use a "fast path"  API  to  call  JIT
+       matching  directly instead of calling pcre2_match() (obviously only for
        patterns that have been successfully processed by pcre2_jit_compile()).
 
-       The  fast  path  function  is  called  pcre2_jit_match(),  and it takes
+       The fast path  function  is  called  pcre2_jit_match(),  and  it  takes
        exactly the same arguments as pcre2_match(). The return values are also
        the same, plus PCRE2_ERROR_JIT_BADOPTION if a matching mode (partial or
-       complete) is requested that was not compiled. Unsupported  option  bits
-       (for  example,  PCRE2_ANCHORED)  are  ignored,  as  is the PCRE2_NO_JIT
+       complete)  is  requested that was not compiled. Unsupported option bits
+       (for example, PCRE2_ANCHORED)  are  ignored,  as  is  the  PCRE2_NO_JIT
        option.
 
-       When you call pcre2_match(), as well as testing for invalid options,  a
+       When  you call pcre2_match(), as well as testing for invalid options, a
        number of other sanity checks are performed on the arguments. For exam-
        ple, if the subject pointer is NULL, an immediate error is given. Also,
-       unless  PCRE2_NO_UTF_CHECK  is  set, a UTF subject string is tested for
-       validity. In the interests of speed, these checks do not happen on  the
+       unless PCRE2_NO_UTF_CHECK is set, a UTF subject string  is  tested  for
+       validity.  In the interests of speed, these checks do not happen on the
        JIT fast path, and if invalid data is passed, the result is undefined.
 
-       Bypassing  the  sanity  checks  and the pcre2_match() wrapping can give
+       Bypassing the sanity checks and the  pcre2_match()  wrapping  can  give
        speedups of more than 10%.
 
 
@@ -4590,8 +5036,8 @@
 
 REVISION
 
-       Last updated: 05 June 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 31 March 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -4628,12 +5074,6 @@
        (that is ~(PCRE2_SIZE)0) is reserved as a special indicator  for  zero-
        terminated strings and unset offsets.
 
-       Note  that  when  using  the  traditional matching function, PCRE2 uses
-       recursion to handle subpatterns and indefinite repetition.  This  means
-       that  the  available stack space may limit the size of a subject string
-       that can be processed by certain patterns. For a  discussion  of  stack
-       issues, see the pcre2stack documentation.
-
        All values in repeating quantifiers must be less than 65536.
 
        The maximum length of a lookbehind assertion is 65535 characters.
@@ -4642,21 +5082,20 @@
        can be no more than 65535 capturing subpatterns. There is,  however,  a
        limit  to  the  depth  of  nesting  of parenthesized subpatterns of all
        kinds. This is imposed in order to limit the  amount  of  system  stack
-       used  at  compile time. The limit can be specified when PCRE2 is built;
-       the default is 250.
-
-       There is a limit to the number of forward references to subsequent sub-
-       patterns  of  around  200,000.  Repeated  forward references with fixed
-       upper limits, for example, (?2){0,100} when subpattern number 2  is  to
-       the  right,  are included in the count. There is no limit to the number
-       of backward references.
+       used  at compile time. The default limit can be specified when PCRE2 is
+       built; the default default is 250. An application can change this limit
+       by  calling pcre2_set_parens_nest_limit() to set the limit in a compile
+       context.
 
        The maximum length of name for a named subpattern is 32 code units, and
        the maximum number of named subpatterns is 10000.
 
        The  maximum  length  of  a  name  in  a (*MARK), (*PRUNE), (*SKIP), or
-       (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit  and
-       32-bit libraries.
+       (*THEN) verb is 255 code units for the 8-bit  library  and  65535  code
+       units for the 16-bit and 32-bit libraries.
+
+       The  maximum  length  of  a string argument to a callout is the largest
+       number a 32-bit unsigned integer can hold.
 
 
 AUTHOR
@@ -4668,8 +5107,8 @@
 
 REVISION
 
-       Last updated: 05 November 2015
-       Copyright (c) 1997-2015 University of Cambridge.
+       Last updated: 30 March 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -5444,19 +5883,26 @@
        attempt by the application to apply the  JIT  optimization  by  calling
        pcre2_jit_compile() is ignored.
 
-   Setting match and recursion limits
+   Setting match resource limits
 
-       The  caller of pcre2_match() can set a limit on the number of times the
-       internal match() function is called and on the maximum depth of  recur-
-       sive calls. These facilities are provided to catch runaway matches that
-       are provoked by patterns with huge matching trees (a typical example is
-       a  pattern  with  nested unlimited repeats) and to avoid running out of
-       system stack by too  much  recursion.  When  one  of  these  limits  is
-       reached,  pcre2_match()  gives  an error return. The limits can also be
-       set by items at the start of the pattern of the form
+       The pcre2_match() function contains a counter that is incremented every
+       time it goes round its main loop. The caller of pcre2_match() can set a
+       limit  on  this counter, which therefore limits the amount of computing
+       resource used for a match. The maximum depth of nested backtracking can
+       also  be  limited;  this indirectly restricts the amount of heap memory
+       that is used, but there is also an explicit memory limit  that  can  be
+       set.
 
+       These  facilities  are  provided to catch runaway matches that are pro-
+       voked by patterns with huge matching trees (a typical example is a pat-
+       tern  with  nested unlimited repeats applied to a long string that does
+       not match). When one of these limits is reached, pcre2_match() gives an
+       error  return.  The limits can also be set by items at the start of the
+       pattern of the form
+
+         (*LIMIT_HEAP=d)
          (*LIMIT_MATCH=d)
-         (*LIMIT_RECURSION=d)
+         (*LIMIT_DEPTH=d)
 
        where d is any number of decimal digits. However, the value of the set-
        ting  must  be  less than the value set (or defaulted) by the caller of
@@ -5465,23 +5911,36 @@
        If there is more than one setting of one of  these  limits,  the  lower
        value is used.
 
+       Prior  to  release  10.30, LIMIT_DEPTH was called LIMIT_RECURSION. This
+       name is still recognized for backwards compatibility.
+
+       The heap limit applies only when the pcre2_match() interpreter is  used
+       for matching. It does not apply to JIT or DFA matching. The match limit
+       is used (but in a different way)  when  JIT  is  being  used,  or  when
+       pcre2_dfa_match() is called, to limit computing resource usage by those
+       matching functions. The depth limit is ignored by JIT but  is  relevant
+       for  DFA  matching, which uses function recursion for recursions within
+       the pattern. In this case, the depth limit controls the amount of  sys-
+       tem stack that is used.
+
    Newline conventions
 
-       PCRE2 supports five different conventions for indicating line breaks in
+       PCRE2  supports six different conventions for indicating line breaks in
        strings: a single CR (carriage return) character, a  single  LF  (line-
        feed) character, the two-character sequence CRLF, any of the three pre-
-       ceding, or any Unicode newline sequence. The pcre2api page has  further
-       discussion  about newlines, and shows how to set the newline convention
-       when calling pcre2_compile().
+       ceding, any Unicode newline sequence,  or  the  NUL  character  (binary
+       zero).  The  pcre2api  page  has further discussion about newlines, and
+       shows how to set the newline convention when calling pcre2_compile().
 
        It is also possible to specify a newline convention by starting a  pat-
-       tern string with one of the following five sequences:
+       tern string with one of the following sequences:
 
          (*CR)        carriage return
          (*LF)        linefeed
          (*CRLF)      carriage return, followed by linefeed
          (*ANYCRLF)   any of the three above
          (*ANY)       all Unicode newline sequences
+         (*NUL)       the NUL character (binary zero)
 
        These override the default and the options given to the compiling func-
        tion. For example, on a Unix system where LF  is  the  default  newline
@@ -5498,9 +5957,9 @@
        acter  when  PCRE2_DOTALL is not set, and the behaviour of \N. However,
        it does not affect what the \R escape  sequence  matches.  By  default,
        this  is any Unicode newline sequence, for Perl compatibility. However,
-       this can be changed; see the description of \R in the section  entitled
-       "Newline  sequences" below. A change of \R setting can be combined with
-       a change of newline convention.
+       this can be changed; see the next section and the description of \R  in
+       the  section entitled "Newline sequences" below. A change of \R setting
+       can be combined with a change of newline convention.
 
    Specifying what \R matches
 
@@ -5514,7 +5973,7 @@
 EBCDIC CHARACTER CODES
 
        PCRE2 can be compiled to run in an environment that uses EBCDIC as  its
-       character code rather than ASCII or Unicode (typically a mainframe sys-
+       character  code instead of ASCII or Unicode (typically a mainframe sys-
        tem). In the sections below, character code values are  ASCII  or  Uni-
        code; in an EBCDIC environment these characters may have different code
        values, and there are no code points greater than 255.
@@ -5579,11 +6038,11 @@
        meaning that character may have. This use of  backslash  as  an  escape
        character applies both inside and outside character classes.
 
-       For  example,  if  you want to match a * character, you write \* in the
-       pattern.  This escaping action applies whether  or  not  the  following
+       For  example,  if you want to match a * character, you must write \* in
+       the pattern. This escaping action applies whether or not the  following
        character  would  otherwise be interpreted as a metacharacter, so it is
        always safe to precede a non-alphanumeric  with  backslash  to  specify
-       that  it stands for itself. In particular, if you want to match a back-
+       that it stands for itself.  In particular, if you want to match a back-
        slash, you write \\.
 
        In a UTF mode, only ASCII numbers and letters have any special  meaning
@@ -5614,15 +6073,16 @@
        is not followed by \E later in the pattern, the literal  interpretation
        continues  to  the  end  of  the pattern (that is, \E is assumed at the
        end). If the isolated \Q is inside a character class,  this  causes  an
-       error, because the character class is not terminated.
+       error,  because  the  character  class  is  not terminated by a closing
+       square bracket.
 
    Non-printing characters
 
        A second use of backslash provides a way of encoding non-printing char-
-       acters in patterns in a visible manner. There is no restriction on  the
-       appearance  of non-printing characters in a pattern, but when a pattern
+       acters  in patterns in a visible manner. There is no restriction on the
+       appearance of non-printing characters in a pattern, but when a  pattern
        is being prepared by text editing, it is often easier to use one of the
-       following  escape sequences than the binary character it represents. In
+       following escape sequences than the binary character it represents.  In
        an ASCII or Unicode environment, these escapes are as follows:
 
          \a        alarm, that is, the BEL character (hex 07)
@@ -5639,51 +6099,51 @@
          \x{hhh..} character with hex code hhh.. (default mode)
          \uhhhh    character with hex code hhhh (when PCRE2_ALT_BSUX is set)
 
-       The precise effect of \cx on ASCII characters is as follows: if x is  a
-       lower  case  letter,  it  is converted to upper case. Then bit 6 of the
+       The  precise effect of \cx on ASCII characters is as follows: if x is a
+       lower case letter, it is converted to upper case. Then  bit  6  of  the
        character (hex 40) is inverted. Thus \cA to \cZ become hex 01 to hex 1A
-       (A  is  41, Z is 5A), but \c{ becomes hex 3B ({ is 7B), and \c; becomes
-       hex 7B (; is 3B). If the code unit following \c has a value  less  than
-       32  or  greater  than  126, a compile-time error occurs. This locks out
-       non-printable ASCII characters in all modes.
+       (A is 41, Z is 5A), but \c{ becomes hex 3B ({ is 7B), and  \c;  becomes
+       hex  7B  (; is 3B). If the code unit following \c has a value less than
+       32 or greater than 126, a compile-time error occurs.
 
        When PCRE2 is compiled in EBCDIC mode, \a, \e, \f, \n, \r, and \t  gen-
        erate the appropriate EBCDIC code values. The \c escape is processed as
        specified for Perl in the perlebcdic document. The only characters that
        are  allowed  after  \c are A-Z, a-z, or one of @, [, \, ], ^, _, or ?.
-       Any other character provokes a  compile-time  error.  The  sequence  \@
-       encodes  character  code 0; the letters (in either case) encode charac-
-       ters 1-26 (hex 01 to hex 1A); [, \, ], ^, and _ encode characters 27-31
-       (hex 1B to hex 1F), and \? becomes either 255 (hex FF) or 95 (hex 5F).
+       Any other character provokes a compile-time  error.  The  sequence  \c@
+       encodes  character code 0; after \c the letters (in either case) encode
+       characters 1-26 (hex 01 to hex 1A); [, \, ], ^, and _ encode characters
+       27-31  (hex  1B  to  hex 1F), and \c? becomes either 255 (hex FF) or 95
+       (hex 5F).
 
-       Thus,  apart  from  \?,  these escapes generate the same character code
-       values as they do in an ASCII environment, though the meanings  of  the
-       values  mostly  differ.  For example, \G always generates code value 7,
+       Thus, apart from \c?, these escapes generate the  same  character  code
+       values  as  they do in an ASCII environment, though the meanings of the
+       values mostly differ. For example, \cG always generates code  value  7,
        which is BEL in ASCII but DEL in EBCDIC.
 
-       The sequence \? generates DEL (127, hex 7F) in  an  ASCII  environment,
-       but  because  127  is  not a control character in EBCDIC, Perl makes it
-       generate the APC character. Unfortunately, there are  several  variants
-       of  EBCDIC.  In  most  of them the APC character has the value 255 (hex
-       FF), but in the one Perl calls POSIX-BC its value is 95  (hex  5F).  If
-       certain  other characters have POSIX-BC values, PCRE2 makes \? generate
+       The  sequence  \c? generates DEL (127, hex 7F) in an ASCII environment,
+       but because 127 is not a control character in  EBCDIC,  Perl  makes  it
+       generate  the  APC character. Unfortunately, there are several variants
+       of EBCDIC. In most of them the APC character has  the  value  255  (hex
+       FF),  but  in  the one Perl calls POSIX-BC its value is 95 (hex 5F). If
+       certain other characters have POSIX-BC values, PCRE2 makes \c? generate
        95; otherwise it generates 255.
 
-       After \0 up to two further octal digits are read. If  there  are  fewer
-       than  two  digits,  just  those  that  are  present  are used. Thus the
+       After  \0  up  to two further octal digits are read. If there are fewer
+       than two digits, just  those  that  are  present  are  used.  Thus  the
        sequence \0\x\015 specifies two binary zeros followed by a CR character
        (code value 13). Make sure you supply two digits after the initial zero
        if the pattern character that follows is itself an octal digit.
 
-       The escape \o must be followed by a sequence of octal digits,  enclosed
-       in  braces.  An  error occurs if this is not the case. This escape is a
-       recent addition to Perl; it provides way of specifying  character  code
-       points  as  octal  numbers  greater than 0777, and it also allows octal
+       The  escape \o must be followed by a sequence of octal digits, enclosed
+       in braces. An error occurs if this is not the case. This  escape  is  a
+       recent  addition  to Perl; it provides way of specifying character code
+       points as octal numbers greater than 0777, and  it  also  allows  octal
        numbers and back references to be unambiguously specified.
 
        For greater clarity and unambiguity, it is best to avoid following \ by
        a digit greater than zero. Instead, use \o{} or \x{} to specify charac-
-       ter numbers, and \g{} to specify back references. The  following  para-
+       ter  numbers,  and \g{} to specify back references. The following para-
        graphs describe the old, ambiguous syntax.
 
        The handling of a backslash followed by a digit other than 0 is compli-
@@ -5691,16 +6151,16 @@
 
        Outside a character class, PCRE2 reads the digit and any following dig-
        its as a decimal number. If the number is less than 10, begins with the
-       digit 8 or 9, or if there are at least  that  many  previous  capturing
-       left  parentheses  in the expression, the entire sequence is taken as a
+       digit  8  or  9,  or if there are at least that many previous capturing
+       left parentheses in the expression, the entire sequence is taken  as  a
        back reference. A description of how this works is given later, follow-
-       ing  the  discussion  of  parenthesized  subpatterns.  Otherwise, up to
+       ing the discussion of  parenthesized  subpatterns.   Otherwise,  up  to
        three octal digits are read to form a character code.
 
-       Inside a character class, PCRE2 handles \8 and \9 as the literal  char-
-       acters  "8"  and "9", and otherwise reads up to three octal digits fol-
+       Inside  a character class, PCRE2 handles \8 and \9 as the literal char-
+       acters "8" and "9", and otherwise reads up to three octal  digits  fol-
        lowing the backslash, using them to generate a data character. Any sub-
-       sequent  digits  stand for themselves. For example, outside a character
+       sequent digits stand for themselves. For example, outside  a  character
        class:
 
          \040   is another way of writing an ASCII space
@@ -5717,69 +6177,68 @@
                    the value 255 (decimal)
          \81    is always a back reference
 
-       Note that octal values of 100 or greater that are specified using  this
-       syntax  must  not be introduced by a leading zero, because no more than
+       Note  that octal values of 100 or greater that are specified using this
+       syntax must not be introduced by a leading zero, because no  more  than
        three octal digits are ever read.
 
-       By default, after \x that is not followed by {, from zero to two  hexa-
-       decimal  digits  are  read (letters can be in upper or lower case). Any
+       By  default, after \x that is not followed by {, from zero to two hexa-
+       decimal digits are read (letters can be in upper or  lower  case).  Any
        number of hexadecimal digits may appear between \x{ and }. If a charac-
-       ter  other  than  a  hexadecimal digit appears between \x{ and }, or if
+       ter other than a hexadecimal digit appears between \x{  and  },  or  if
        there is no terminating }, an error occurs.
 
-       If the PCRE2_ALT_BSUX option is set, the interpretation  of  \x  is  as
+       If  the  PCRE2_ALT_BSUX  option  is set, the interpretation of \x is as
        just described only when it is followed by two hexadecimal digits. Oth-
-       erwise, it matches a literal "x" character. In this mode mode,  support
-       for  code points greater than 256 is provided by \u, which must be fol-
-       lowed by four hexadecimal digits; otherwise it matches  a  literal  "u"
-       character.
+       erwise,  it  matches a literal "x" character. In this mode, support for
+       code points greater than 256 is provided by \u, which must be  followed
+       by  four hexadecimal digits; otherwise it matches a literal "u" charac-
+       ter.
 
        Characters whose value is less than 256 can be defined by either of the
        two syntaxes for \x (or by \u in PCRE2_ALT_BSUX mode). There is no dif-
-       ference  in  the way they are handled. For example, \xdc is exactly the
+       ference in the way they are handled. For example, \xdc is  exactly  the
        same as \x{dc} (or \u00dc in PCRE2_ALT_BSUX mode).
 
    Constraints on character values
 
-       Characters that are specified using octal or  hexadecimal  numbers  are
+       Characters  that  are  specified using octal or hexadecimal numbers are
        limited to certain values, as follows:
 
-         8-bit non-UTF mode    less than 0x100
-         8-bit UTF-8 mode      less than 0x10ffff and a valid codepoint
-         16-bit non-UTF mode   less than 0x10000
-         16-bit UTF-16 mode    less than 0x10ffff and a valid codepoint
-         32-bit non-UTF mode   less than 0x100000000
-         32-bit UTF-32 mode    less than 0x10ffff and a valid codepoint
+         8-bit non-UTF mode    no greater than 0xff
+         16-bit non-UTF mode   no greater than 0xffff
+         32-bit non-UTF mode   no greater than 0xffffffff
+         All UTF modes         no greater than 0x10ffff and a valid codepoint
 
-       Invalid  Unicode  codepoints  are  the  range 0xd800 to 0xdfff (the so-
-       called "surrogate" codepoints), and 0xffef.
+       Invalid Unicode codepoints are all those in the range 0xd800 to  0xdfff
+       (the so-called "surrogate" codepoints). The check for these can be dis-
+       abled  by  the  caller  of  pcre2_compile()  by  setting   the   option
+       PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES.
 
    Escape sequences in character classes
 
        All the sequences that define a single character value can be used both
-       inside  and  outside character classes. In addition, inside a character
+       inside and outside character classes. In addition, inside  a  character
        class, \b is interpreted as the backspace character (hex 08).
 
-       \N is not allowed in a character class. \B, \R, and \X are not  special
-       inside  a  character  class.  Like other unrecognized alphabetic escape
-       sequences, they cause  an  error.  Outside  a  character  class,  these
+       \N  is not allowed in a character class. \B, \R, and \X are not special
+       inside a character class. Like  other  unrecognized  alphabetic  escape
+       sequences,  they  cause  an  error.  Outside  a  character class, these
        sequences have different meanings.
 
    Unsupported escape sequences
 
-       In  Perl, the sequences \l, \L, \u, and \U are recognized by its string
-       handler and used  to  modify  the  case  of  following  characters.  By
+       In Perl, the sequences \l, \L, \u, and \U are recognized by its  string
+       handler  and  used  to  modify  the  case  of  following characters. By
        default, PCRE2 does not support these escape sequences. However, if the
        PCRE2_ALT_BSUX option is set, \U matches a "U" character, and \u can be
-       used  to define a character by code point, as described in the previous
-       section.
+       used to define a character by code point, as described above.
 
    Absolute and relative back references
 
-       The sequence \g followed by an unsigned or a negative  number,  option-
-       ally  enclosed  in braces, is an absolute or relative back reference. A
-       named back reference can be coded as \g{name}. Back references are dis-
-       cussed later, following the discussion of parenthesized subpatterns.
+       The sequence \g followed by a signed  or  unsigned  number,  optionally
+       enclosed  in braces, is an absolute or relative back reference. A named
+       back reference can be coded as \g{name}. Back references are  discussed
+       later, following the discussion of parenthesized subpatterns.
 
    Absolute and relative subroutine calls
 
@@ -5941,59 +6400,64 @@
        tional escape sequences that match characters with specific  properties
        are  available.  In 8-bit non-UTF-8 mode, these sequences are of course
        limited to testing characters whose codepoints are less than  256,  but
-       they do work in this mode.  The extra escape sequences are:
+       they  do work in this mode.  In 32-bit non-UTF mode, codepoints greater
+       than 0x10ffff (the Unicode limit) may be  encountered.  These  are  all
+       treated  as being in the Common script and with an unassigned type. The
+       extra escape sequences are:
 
          \p{xx}   a character with the xx property
          \P{xx}   a character without the xx property
          \X       a Unicode extended grapheme cluster
 
-       The  property  names represented by xx above are limited to the Unicode
+       The property names represented by xx above are limited to  the  Unicode
        script names, the general category properties, "Any", which matches any
        character  (including  newline),  and  some  special  PCRE2  properties
-       (described in the next section).  Other Perl properties such as  "InMu-
-       sicalSymbols"  are  not supported by PCRE2.  Note that \P{Any} does not
+       (described  in the next section).  Other Perl properties such as "InMu-
+       sicalSymbols" are not supported by PCRE2.  Note that \P{Any}  does  not
        match any characters, so always causes a match failure.
 
        Sets of Unicode characters are defined as belonging to certain scripts.
-       A  character from one of these sets can be matched using a script name.
+       A character from one of these sets can be matched using a script  name.
        For example:
 
          \p{Greek}
          \P{Han}
 
-       Those that are not part of an identified script are lumped together  as
+       Those  that are not part of an identified script are lumped together as
        "Common". The current list of scripts is:
 
-       Ahom,   Anatolian_Hieroglyphs,  Arabic,  Armenian,  Avestan,  Balinese,
-       Bamum, Bassa_Vah, Batak, Bengali, Bopomofo, Brahmi, Braille,  Buginese,
-       Buhid,  Canadian_Aboriginal,  Carian, Caucasian_Albanian, Chakma, Cham,
-       Cherokee,  Common,  Coptic,  Cuneiform,  Cypriot,  Cyrillic,   Deseret,
-       Devanagari,  Duployan,  Egyptian_Hieroglyphs,  Elbasan, Ethiopic, Geor-
-       gian, Glagolitic, Gothic,  Grantha,  Greek,  Gujarati,  Gurmukhi,  Han,
-       Hangul, Hanunoo, Hatran, Hebrew, Hiragana, Imperial_Aramaic, Inherited,
-       Inscriptional_Pahlavi, Inscriptional_Parthian, Javanese,  Kaithi,  Kan-
-       nada,  Katakana,  Kayah_Li,  Kharoshthi, Khmer, Khojki, Khudawadi, Lao,
-       Latin, Lepcha, Limbu, Linear_A, Linear_B, Lisu, Lycian,  Lydian,  Maha-
-       jani,  Malayalam,  Mandaic,  Manichaean,  Meetei_Mayek,  Mende_Kikakui,
-       Meroitic_Cursive, Meroitic_Hieroglyphs,  Miao,  Modi,  Mongolian,  Mro,
-       Multani,   Myanmar,   Nabataean,  New_Tai_Lue,  Nko,  Ogham,  Ol_Chiki,
-       Old_Hungarian, Old_Italic, Old_North_Arabian, Old_Permic,  Old_Persian,
-       Old_South_Arabian, Old_Turkic, Oriya, Osmanya, Pahawh_Hmong, Palmyrene,
-       Pau_Cin_Hau,  Phags_Pa,  Phoenician,  Psalter_Pahlavi,  Rejang,  Runic,
-       Samaritan, Saurashtra, Sharada, Shavian, Siddham, SignWriting, Sinhala,
-       Sora_Sompeng,  Sundanese,  Syloti_Nagri,  Syriac,  Tagalog,   Tagbanwa,
-       Tai_Le,   Tai_Tham,  Tai_Viet,  Takri,  Tamil,  Telugu,  Thaana,  Thai,
-       Tibetan, Tifinagh, Tirhuta, Ugaritic, Vai, Warang_Citi, Yi.
+       Adlam, Ahom, Anatolian_Hieroglyphs, Arabic,  Armenian,  Avestan,  Bali-
+       nese,  Bamum,  Bassa_Vah,  Batak, Bengali, Bhaiksuki, Bopomofo, Brahmi,
+       Braille, Buginese, Buhid, Canadian_Aboriginal, Carian,  Caucasian_Alba-
+       nian,  Chakma,  Cham,  Cherokee,  Common,  Coptic,  Cuneiform, Cypriot,
+       Cyrillic, Deseret, Devanagari, Duployan, Egyptian_Hieroglyphs, Elbasan,
+       Ethiopic,  Georgian, Glagolitic, Gothic, Grantha, Greek, Gujarati, Gur-
+       mukhi, Han, Hangul, Hanunoo, Hatran,  Hebrew,  Hiragana,  Imperial_Ara-
+       maic,    Inherited,    Inscriptional_Pahlavi,   Inscriptional_Parthian,
+       Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer,  Kho-
+       jki,  Khudawadi,  Lao,  Latin, Lepcha, Limbu, Linear_A, Linear_B, Lisu,
+       Lycian, Lydian,  Mahajani,  Malayalam,  Mandaic,  Manichaean,  Marchen,
+       Masaram_Gondi,     Meetei_Mayek,    Mende_Kikakui,    Meroitic_Cursive,
+       Meroitic_Hieroglyphs, Miao, Modi,  Mongolian,  Mro,  Multani,  Myanmar,
+       Nabataean,  New_Tai_Lue, Newa, Nko, Nushu, Ogham, Ol_Chiki, Old_Hungar-
+       ian,   Old_Italic,    Old_North_Arabian,    Old_Permic,    Old_Persian,
+       Old_South_Arabian,  Old_Turkic,  Oriya,  Osage,  Osmanya, Pahawh_Hmong,
+       Palmyrene, Pau_Cin_Hau, Phags_Pa, Phoenician, Psalter_Pahlavi,  Rejang,
+       Runic,  Samaritan,  Saurashtra, Sharada, Shavian, Siddham, SignWriting,
+       Sinhala, Sora_Sompeng, Soyombo, Sundanese, Syloti_Nagri, Syriac,  Taga-
+       log,  Tagbanwa,  Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Tangut, Tel-
+       ugu,  Thaana,  Thai,  Tibetan,  Tifinagh,   Tirhuta,   Ugaritic,   Vai,
+       Warang_Citi, Yi, Zanabazar_Square.
 
        Each character has exactly one Unicode general category property, spec-
-       ified  by a two-letter abbreviation. For compatibility with Perl, nega-
-       tion can be specified by including a  circumflex  between  the  opening
-       brace  and  the  property  name.  For  example,  \p{^Lu} is the same as
+       ified by a two-letter abbreviation. For compatibility with Perl,  nega-
+       tion  can  be  specified  by including a circumflex between the opening
+       brace and the property name.  For  example,  \p{^Lu}  is  the  same  as
        \P{Lu}.
 
        If only one letter is specified with \p or \P, it includes all the gen-
-       eral  category properties that start with that letter. In this case, in
-       the absence of negation, the curly brackets in the escape sequence  are
+       eral category properties that start with that letter. In this case,  in
+       the  absence of negation, the curly brackets in the escape sequence are
        optional; these two examples have the same effect:
 
          \p{L}
@@ -6045,45 +6509,48 @@
          Zp    Paragraph separator
          Zs    Space separator
 
-       The  special property L& is also supported: it matches a character that
-       has the Lu, Ll, or Lt property, in other words, a letter  that  is  not
+       The special property L& is also supported: it matches a character  that
+       has  the  Lu,  Ll, or Lt property, in other words, a letter that is not
        classified as a modifier or "other".
 
-       The  Cs  (Surrogate)  property  applies only to characters in the range
-       U+D800 to U+DFFF. Such characters are not valid in Unicode strings  and
-       so  cannot  be  tested  by PCRE2, unless UTF validity checking has been
-       turned off (see the discussion of PCRE2_NO_UTF_CHECK  in  the  pcre2api
+       The Cs (Surrogate) property applies only to  characters  in  the  range
+       U+D800  to U+DFFF. Such characters are not valid in Unicode strings and
+       so cannot be tested by PCRE2, unless UTF  validity  checking  has  been
+       turned  off  (see  the discussion of PCRE2_NO_UTF_CHECK in the pcre2api
        page). Perl does not support the Cs property.
 
-       The  long  synonyms  for  property  names  that  Perl supports (such as
-       \p{Letter}) are not supported by PCRE2, nor is it permitted  to  prefix
+       The long synonyms for  property  names  that  Perl  supports  (such  as
+       \p{Letter})  are  not supported by PCRE2, nor is it permitted to prefix
        any of these properties with "Is".
 
        No character that is in the Unicode table has the Cn (unassigned) prop-
        erty.  Instead, this property is assumed for any code point that is not
        in the Unicode table.
 
-       Specifying  caseless  matching  does not affect these escape sequences.
-       For example, \p{Lu} always matches only upper  case  letters.  This  is
+       Specifying caseless matching does not affect  these  escape  sequences.
+       For  example,  \p{Lu}  always  matches only upper case letters. This is
        different from the behaviour of current versions of Perl.
 
-       Matching  characters by Unicode property is not fast, because PCRE2 has
-       to do a multistage table lookup in order to find  a  character's  prop-
+       Matching characters by Unicode property is not fast, because PCRE2  has
+       to  do  a  multistage table lookup in order to find a character's prop-
        erty. That is why the traditional escape sequences such as \d and \w do
-       not use Unicode properties in PCRE2 by default,  though  you  can  make
-       them  do  so by setting the PCRE2_UCP option or by starting the pattern
+       not  use  Unicode  properties  in PCRE2 by default, though you can make
+       them do so by setting the PCRE2_UCP option or by starting  the  pattern
        with (*UCP).
 
    Extended grapheme clusters
 
-       The \X escape matches any number of Unicode  characters  that  form  an
+       The  \X  escape  matches  any number of Unicode characters that form an
        "extended grapheme cluster", and treats the sequence as an atomic group
-       (see below).  Unicode supports various kinds of composite character  by
-       giving  each  character  a grapheme breaking property, and having rules
+       (see  below).  Unicode supports various kinds of composite character by
+       giving each character a grapheme breaking property,  and  having  rules
        that use these properties to define the boundaries of extended grapheme
-       clusters.  \X  always  matches  at least one character. Then it decides
-       whether to add additional characters according to the  following  rules
-       for ending a cluster:
+       clusters. The rules are defined in Unicode Standard Annex 29,  "Unicode
+       Text Segmentation".
+
+       \X  always  matches  at least one character. Then it decides whether to
+       add additional characters according to the following rules for ending a
+       cluster:
 
        1. End at the end of the subject string.
 
@@ -6096,20 +6563,31 @@
        be followed by a V or T character; an LVT or T character may be follwed
        only by a T character.
 
-       4. Do not end before extending characters or spacing marks.  Characters
-       with  the  "mark"  property  always have the "extend" grapheme breaking
-       property.
+       4. Do not end before extending  characters  or  spacing  marks  or  the
+       "zero-width  joiner"  characters.  Characters  with the "mark" property
+       always have the "extend" grapheme breaking property.
 
        5. Do not end after prepend characters.
 
+       6. Do not break within emoji modifier sequences (a base character  fol-
+       lowed by a modifier). Extending characters are allowed before the modi-
+       fier.
+
+       7. Do not break within emoji zwj sequences (zero-width jointer followed
+       by "glue after ZWJ" or "base glue after ZWJ").
+
+       8.  Do  not  break  within  emoji flag sequences. That is, do not break
+       between regional indicator (RI) characters if there are an  odd  number
+       of RI characters before the break point.
+
        6. Otherwise, end the cluster.
 
    PCRE2's additional properties
 
-       As well as the standard Unicode properties described above, PCRE2  sup-
-       ports  four  more  that  make it possible to convert traditional escape
+       As  well as the standard Unicode properties described above, PCRE2 sup-
+       ports four more that make it possible  to  convert  traditional  escape
        sequences such as \w and \s to use Unicode properties. PCRE2 uses these
-       non-standard,  non-Perl  properties  internally  when PCRE2_UCP is set.
+       non-standard, non-Perl properties internally  when  PCRE2_UCP  is  set.
        However, they may also be used explicitly. These properties are:
 
          Xan   Any alphanumeric character
@@ -6117,53 +6595,53 @@
          Xsp   Any Perl space character
          Xwd   Any Perl "word" character
 
-       Xan matches characters that have either the L (letter) or the  N  (num-
-       ber)  property. Xps matches the characters tab, linefeed, vertical tab,
-       form feed, or carriage return, and any other character that has  the  Z
-       (separator)  property.   Xsp  is  the  same as Xps; in PCRE1 it used to
-       exclude vertical tab, for Perl compatibility,  but  Perl  changed.  Xwd
+       Xan  matches  characters that have either the L (letter) or the N (num-
+       ber) property. Xps matches the characters tab, linefeed, vertical  tab,
+       form  feed,  or carriage return, and any other character that has the Z
+       (separator) property.  Xsp is the same as Xps;  in  PCRE1  it  used  to
+       exclude  vertical  tab,  for  Perl compatibility, but Perl changed. Xwd
        matches the same characters as Xan, plus underscore.
 
-       There  is another non-standard property, Xuc, which matches any charac-
-       ter that can be represented by a Universal Character Name  in  C++  and
-       other  programming  languages.  These are the characters $, @, ` (grave
-       accent), and all characters with Unicode code points  greater  than  or
-       equal  to U+00A0, except for the surrogates U+D800 to U+DFFF. Note that
-       most base (ASCII) characters are excluded. (Universal  Character  Names
-       are  of  the  form \uHHHH or \UHHHHHHHH where H is a hexadecimal digit.
+       There is another non-standard property, Xuc, which matches any  charac-
+       ter  that  can  be represented by a Universal Character Name in C++ and
+       other programming languages. These are the characters $,  @,  `  (grave
+       accent),  and  all  characters with Unicode code points greater than or
+       equal to U+00A0, except for the surrogates U+D800 to U+DFFF. Note  that
+       most  base  (ASCII) characters are excluded. (Universal Character Names
+       are of the form \uHHHH or \UHHHHHHHH where H is  a  hexadecimal  digit.
        Note that the Xuc property does not match these sequences but the char-
        acters that they represent.)
 
    Resetting the match start
 
-       The  escape sequence \K causes any previously matched characters not to
+       The escape sequence \K causes any previously matched characters not  to
        be included in the final matched sequence. For example, the pattern:
 
          foo\Kbar
 
-       matches "foobar", but reports that it has matched "bar".  This  feature
-       is  similar  to  a lookbehind assertion (described below).  However, in
-       this case, the part of the subject before the real match does not  have
-       to  be of fixed length, as lookbehind assertions do. The use of \K does
-       not interfere with the setting of captured  substrings.   For  example,
+       matches  "foobar",  but reports that it has matched "bar". This feature
+       is similar to a lookbehind assertion (described  below).   However,  in
+       this  case, the part of the subject before the real match does not have
+       to be of fixed length, as lookbehind assertions do. The use of \K  does
+       not  interfere  with  the setting of captured substrings.  For example,
        when the pattern
 
          (foo)\Kbar
 
        matches "foobar", the first substring is still set to "foo".
 
-       Perl  documents  that  the  use  of  \K  within assertions is "not well
-       defined". In PCRE2, \K is acted upon when  it  occurs  inside  positive
-       assertions,  but  is  ignored  in negative assertions. Note that when a
-       pattern such as (?=ab\K) matches, the reported start of the  match  can
+       Perl documents that the use  of  \K  within  assertions  is  "not  well
+       defined".  In  PCRE2,  \K  is acted upon when it occurs inside positive
+       assertions, but is ignored in negative assertions.  Note  that  when  a
+       pattern  such  as (?=ab\K) matches, the reported start of the match can
        be greater than the end of the match.
 
    Simple assertions
 
-       The  final use of backslash is for certain simple assertions. An asser-
-       tion specifies a condition that has to be met at a particular point  in
-       a  match, without consuming any characters from the subject string. The
-       use of subpatterns for more complicated assertions is described  below.
+       The final use of backslash is for certain simple assertions. An  asser-
+       tion  specifies a condition that has to be met at a particular point in
+       a match, without consuming any characters from the subject string.  The
+       use  of subpatterns for more complicated assertions is described below.
        The backslashed assertions are:
 
          \b     matches at a word boundary
@@ -6174,184 +6652,184 @@
          \z     matches only at the end of the subject
          \G     matches at the first matching position in the subject
 
-       Inside  a  character  class, \b has a different meaning; it matches the
-       backspace character. If any other of  these  assertions  appears  in  a
+       Inside a character class, \b has a different meaning;  it  matches  the
+       backspace  character.  If  any  other  of these assertions appears in a
        character class, an "invalid escape sequence" error is generated.
 
-       A  word  boundary is a position in the subject string where the current
-       character and the previous character do not both match \w or  \W  (i.e.
-       one  matches  \w  and the other matches \W), or the start or end of the
-       string if the first or last character matches \w,  respectively.  In  a
-       UTF  mode,  the  meanings  of  \w  and \W can be changed by setting the
+       A word boundary is a position in the subject string where  the  current
+       character  and  the previous character do not both match \w or \W (i.e.
+       one matches \w and the other matches \W), or the start or  end  of  the
+       string  if  the  first or last character matches \w, respectively. In a
+       UTF mode, the meanings of \w and \W  can  be  changed  by  setting  the
        PCRE2_UCP option. When this is done, it also affects \b and \B. Neither
-       PCRE2  nor Perl has a separate "start of word" or "end of word" metase-
-       quence. However, whatever follows \b normally determines which  it  is.
+       PCRE2 nor Perl has a separate "start of word" or "end of word"  metase-
+       quence.  However,  whatever follows \b normally determines which it is.
        For example, the fragment \ba matches "a" at the start of a word.
 
-       The  \A,  \Z,  and \z assertions differ from the traditional circumflex
+       The \A, \Z, and \z assertions differ from  the  traditional  circumflex
        and dollar (described in the next section) in that they only ever match
-       at  the  very start and end of the subject string, whatever options are
-       set. Thus, they are independent of multiline mode. These  three  asser-
-       tions  are  not  affected  by the PCRE2_NOTBOL or PCRE2_NOTEOL options,
-       which affect only the behaviour of the circumflex and dollar  metachar-
-       acters.  However,  if the startoffset argument of pcre2_match() is non-
-       zero, indicating that matching is to start at a point  other  than  the
-       beginning  of  the subject, \A can never match.  The difference between
-       \Z and \z is that \Z matches before a newline at the end of the  string
+       at the very start and end of the subject string, whatever  options  are
+       set.  Thus,  they are independent of multiline mode. These three asser-
+       tions are not affected by the  PCRE2_NOTBOL  or  PCRE2_NOTEOL  options,
+       which  affect only the behaviour of the circumflex and dollar metachar-
+       acters. However, if the startoffset argument of pcre2_match()  is  non-
+       zero,  indicating  that  matching is to start at a point other than the
+       beginning of the subject, \A can never match.  The  difference  between
+       \Z  and \z is that \Z matches before a newline at the end of the string
        as well as at the very end, whereas \z matches only at the end.
 
-       The  \G assertion is true only when the current matching position is at
-       the start point of the match, as specified by the startoffset  argument
-       of  pcre2_match().  It differs from \A when the value of startoffset is
-       non-zero. By calling  pcre2_match()  multiple  times  with  appropriate
-       arguments,  you  can  mimic Perl's /g option, and it is in this kind of
+       The \G assertion is true only when the current matching position is  at
+       the  start point of the match, as specified by the startoffset argument
+       of pcre2_match(). It differs from \A when the value of  startoffset  is
+       non-zero.  By  calling  pcre2_match()  multiple  times with appropriate
+       arguments, you can mimic Perl's /g option, and it is in  this  kind  of
        implementation where \G can be useful.
 
-       Note, however, that PCRE2's interpretation of \G, as the start  of  the
+       Note,  however,  that PCRE2's interpretation of \G, as the start of the
        current match, is subtly different from Perl's, which defines it as the
-       end of the previous match. In Perl, these can  be  different  when  the
-       previously  matched string was empty. Because PCRE2 does just one match
+       end  of  the  previous  match. In Perl, these can be different when the
+       previously matched string was empty. Because PCRE2 does just one  match
        at a time, it cannot reproduce this behaviour.
 
-       If all the alternatives of a pattern begin with \G, the  expression  is
+       If  all  the alternatives of a pattern begin with \G, the expression is
        anchored to the starting match position, and the "anchored" flag is set
        in the compiled regular expression.
 
 
 CIRCUMFLEX AND DOLLAR
 
-       The circumflex and dollar  metacharacters  are  zero-width  assertions.
-       That  is,  they test for a particular condition being true without con-
+       The  circumflex  and  dollar  metacharacters are zero-width assertions.
+       That is, they test for a particular condition being true  without  con-
        suming any characters from the subject string. These two metacharacters
-       are  concerned  with matching the starts and ends of lines. If the new-
-       line convention is set so that only the two-character sequence CRLF  is
-       recognized  as  a newline, isolated CR and LF characters are treated as
+       are concerned with matching the starts and ends of lines. If  the  new-
+       line  convention is set so that only the two-character sequence CRLF is
+       recognized as a newline, isolated CR and LF characters are  treated  as
        ordinary data characters, and are not recognized as newlines.
 
        Outside a character class, in the default matching mode, the circumflex
-       character  is  an  assertion  that is true only if the current matching
-       point is at the start of the subject string. If the  startoffset  argu-
-       ment  of  pcre2_match() is non-zero, or if PCRE2_NOTBOL is set, circum-
-       flex can never match if the PCRE2_MULTILINE option is unset.  Inside  a
-       character  class,  circumflex  has  an  entirely different meaning (see
+       character is an assertion that is true only  if  the  current  matching
+       point  is  at the start of the subject string. If the startoffset argu-
+       ment of pcre2_match() is non-zero, or if PCRE2_NOTBOL is  set,  circum-
+       flex  can  never match if the PCRE2_MULTILINE option is unset. Inside a
+       character class, circumflex has  an  entirely  different  meaning  (see
        below).
 
-       Circumflex need not be the first character of the pattern if  a  number
-       of  alternatives are involved, but it should be the first thing in each
-       alternative in which it appears if the pattern is ever  to  match  that
-       branch.  If all possible alternatives start with a circumflex, that is,
-       if the pattern is constrained to match only at the start  of  the  sub-
-       ject,  it  is  said  to be an "anchored" pattern. (There are also other
+       Circumflex  need  not be the first character of the pattern if a number
+       of alternatives are involved, but it should be the first thing in  each
+       alternative  in  which  it appears if the pattern is ever to match that
+       branch. If all possible alternatives start with a circumflex, that  is,
+       if  the  pattern  is constrained to match only at the start of the sub-
+       ject, it is said to be an "anchored" pattern.  (There  are  also  other
        constructs that can cause a pattern to be anchored.)
 
-       The dollar character is an assertion that is true only if  the  current
-       matching  point  is  at  the  end of the subject string, or immediately
-       before a newline  at  the  end  of  the  string  (by  default),  unless
+       The  dollar  character is an assertion that is true only if the current
+       matching point is at the end of  the  subject  string,  or  immediately
+       before  a  newline  at  the  end  of  the  string  (by default), unless
        PCRE2_NOTEOL is set. Note, however, that it does not actually match the
        newline. Dollar need not be the last character of the pattern if a num-
        ber of alternatives are involved, but it should be the last item in any
-       branch in which it appears. Dollar has no special meaning in a  charac-
+       branch  in which it appears. Dollar has no special meaning in a charac-
        ter class.
 
-       The  meaning  of  dollar  can be changed so that it matches only at the
-       very end of the string, by setting the PCRE2_DOLLAR_ENDONLY  option  at
+       The meaning of dollar can be changed so that it  matches  only  at  the
+       very  end  of the string, by setting the PCRE2_DOLLAR_ENDONLY option at
        compile time. This does not affect the \Z assertion.
 
        The meanings of the circumflex and dollar metacharacters are changed if
-       the PCRE2_MULTILINE option is set. When this  is  the  case,  a  dollar
-       character  matches before any newlines in the string, as well as at the
-       very end, and a circumflex matches immediately after internal  newlines
-       as  well as at the start of the subject string. It does not match after
-       a newline that ends the string, for compatibility with  Perl.  However,
+       the  PCRE2_MULTILINE  option  is  set.  When this is the case, a dollar
+       character matches before any newlines in the string, as well as at  the
+       very  end, and a circumflex matches immediately after internal newlines
+       as well as at the start of the subject string. It does not match  after
+       a  newline  that ends the string, for compatibility with Perl. However,
        this can be changed by setting the PCRE2_ALT_CIRCUMFLEX option.
 
-       For  example, the pattern /^abc$/ matches the subject string "def\nabc"
-       (where \n represents a newline) in multiline mode, but  not  otherwise.
-       Consequently,  patterns  that  are anchored in single line mode because
-       all branches start with ^ are not anchored in  multiline  mode,  and  a
-       match  for  circumflex  is  possible  when  the startoffset argument of
-       pcre2_match() is non-zero. The PCRE2_DOLLAR_ENDONLY option  is  ignored
+       For example, the pattern /^abc$/ matches the subject string  "def\nabc"
+       (where  \n  represents a newline) in multiline mode, but not otherwise.
+       Consequently, patterns that are anchored in single  line  mode  because
+       all  branches  start  with  ^ are not anchored in multiline mode, and a
+       match for circumflex is  possible  when  the  startoffset  argument  of
+       pcre2_match()  is  non-zero. The PCRE2_DOLLAR_ENDONLY option is ignored
        if PCRE2_MULTILINE is set.
 
-       When  the  newline  convention (see "Newline conventions" below) recog-
-       nizes the two-character sequence CRLF as a newline, this is  preferred,
-       even  if  the  single  characters CR and LF are also recognized as new-
-       lines. For example, if the newline convention  is  "any",  a  multiline
-       mode  circumflex matches before "xyz" in the string "abc\r\nxyz" rather
-       than after CR, even though CR on its own is a valid newline.  (It  also
+       When the newline convention (see "Newline  conventions"  below)  recog-
+       nizes  the two-character sequence CRLF as a newline, this is preferred,
+       even if the single characters CR and LF are  also  recognized  as  new-
+       lines.  For  example,  if  the newline convention is "any", a multiline
+       mode circumflex matches before "xyz" in the string "abc\r\nxyz"  rather
+       than  after  CR, even though CR on its own is a valid newline. (It also
        matches at the very start of the string, of course.)
 
-       Note  that  the sequences \A, \Z, and \z can be used to match the start
-       and end of the subject in both modes, and if all branches of a  pattern
-       start  with \A it is always anchored, whether or not PCRE2_MULTILINE is
+       Note that the sequences \A, \Z, and \z can be used to match  the  start
+       and  end of the subject in both modes, and if all branches of a pattern
+       start with \A it is always anchored, whether or not PCRE2_MULTILINE  is
        set.
 
 
 FULL STOP (PERIOD, DOT) AND \N
 
        Outside a character class, a dot in the pattern matches any one charac-
-       ter  in  the subject string except (by default) a character that signi-
+       ter in the subject string except (by default) a character  that  signi-
        fies the end of a line.
 
-       When a line ending is defined as a single character, dot never  matches
-       that  character; when the two-character sequence CRLF is used, dot does
-       not match CR if it is immediately followed  by  LF,  but  otherwise  it
-       matches  all characters (including isolated CRs and LFs). When any Uni-
-       code line endings are being recognized, dot does not match CR or LF  or
+       When  a line ending is defined as a single character, dot never matches
+       that character; when the two-character sequence CRLF is used, dot  does
+       not  match  CR  if  it  is immediately followed by LF, but otherwise it
+       matches all characters (including isolated CRs and LFs). When any  Uni-
+       code  line endings are being recognized, dot does not match CR or LF or
        any of the other line ending characters.
 
-       The  behaviour  of  dot  with regard to newlines can be changed. If the
-       PCRE2_DOTALL option is set, a dot matches any  one  character,  without
-       exception.   If  the two-character sequence CRLF is present in the sub-
+       The behaviour of dot with regard to newlines can  be  changed.  If  the
+       PCRE2_DOTALL  option  is  set, a dot matches any one character, without
+       exception.  If the two-character sequence CRLF is present in  the  sub-
        ject string, it takes two dots to match it.
 
-       The handling of dot is entirely independent of the handling of  circum-
-       flex  and  dollar,  the  only relationship being that they both involve
+       The  handling of dot is entirely independent of the handling of circum-
+       flex and dollar, the only relationship being  that  they  both  involve
        newlines. Dot has no special meaning in a character class.
 
-       The escape sequence \N behaves like  a  dot,  except  that  it  is  not
-       affected  by  the  PCRE2_DOTALL  option. In other words, it matches any
-       character except one that signifies the end of a line. Perl  also  uses
+       The  escape  sequence  \N  behaves  like  a  dot, except that it is not
+       affected by the PCRE2_DOTALL option. In other  words,  it  matches  any
+       character  except  one that signifies the end of a line. Perl also uses
        \N to match characters by name; PCRE2 does not support this.
 
 
 MATCHING A SINGLE CODE UNIT
 
-       Outside  a character class, the escape sequence \C matches any one code
-       unit, whether or not a UTF mode is set. In the 8-bit library, one  code
-       unit  is  one  byte;  in the 16-bit library it is a 16-bit unit; in the
-       32-bit library it is a 32-bit unit. Unlike a  dot,  \C  always  matches
-       line-ending  characters.  The  feature  is provided in Perl in order to
+       Outside a character class, the escape sequence \C matches any one  code
+       unit,  whether or not a UTF mode is set. In the 8-bit library, one code
+       unit is one byte; in the 16-bit library it is a  16-bit  unit;  in  the
+       32-bit  library  it  is  a 32-bit unit. Unlike a dot, \C always matches
+       line-ending characters. The feature is provided in  Perl  in  order  to
        match individual bytes in UTF-8 mode, but it is unclear how it can use-
        fully be used.
 
-       Because  \C  breaks  up characters into individual code units, matching
-       one unit with \C in UTF-8 or UTF-16 mode means that  the  rest  of  the
-       string  may  start  with  a malformed UTF character. This has undefined
+       Because \C breaks up characters into individual  code  units,  matching
+       one  unit  with  \C  in UTF-8 or UTF-16 mode means that the rest of the
+       string may start with a malformed UTF  character.  This  has  undefined
        results, because PCRE2 assumes that it is matching character by charac-
-       ter  in  a  valid UTF string (by default it checks the subject string's
-       validity at the  start  of  processing  unless  the  PCRE2_NO_UTF_CHECK
+       ter in a valid UTF string (by default it checks  the  subject  string's
+       validity  at  the  start  of  processing  unless the PCRE2_NO_UTF_CHECK
        option is used).
 
-       An   application   can   lock   out  the  use  of  \C  by  setting  the
-       PCRE2_NEVER_BACKSLASH_C option when compiling a  pattern.  It  is  also
+       An  application  can  lock  out  the  use  of   \C   by   setting   the
+       PCRE2_NEVER_BACKSLASH_C  option  when  compiling  a pattern. It is also
        possible to build PCRE2 with the use of \C permanently disabled.
 
-       PCRE2  does  not allow \C to appear in lookbehind assertions (described
-       below) in UTF-8 or UTF-16 modes, because this would make it  impossible
-       to  calculate  the  length  of  the lookbehind. Neither the alternative
+       PCRE2 does not allow \C to appear in lookbehind  assertions  (described
+       below)  in UTF-8 or UTF-16 modes, because this would make it impossible
+       to calculate the length of  the  lookbehind.  Neither  the  alternative
        matching function pcre2_dfa_match() nor the JIT optimizer support \C in
        these UTF modes.  The former gives a match-time error; the latter fails
        to optimize and so the match is always run using the interpreter.
 
-       In the 32-bit library,  however,  \C  is  always  supported  (when  not
-       explicitly  locked  out)  because it always matches a single code unit,
+       In  the  32-bit  library,  however,  \C  is  always supported (when not
+       explicitly locked out) because it always matches a  single  code  unit,
        whether or not UTF-32 is specified.
 
        In general, the \C escape sequence is best avoided. However, one way of
-       using  it  that avoids the problem of malformed UTF-8 or UTF-16 charac-
-       ters is to use a lookahead to check the length of the  next  character,
-       as  in  this  pattern,  which could be used with a UTF-8 string (ignore
+       using it that avoids the problem of malformed UTF-8 or  UTF-16  charac-
+       ters  is  to use a lookahead to check the length of the next character,
+       as in this pattern, which could be used with  a  UTF-8  string  (ignore
        white space and line breaks):
 
          (?| (?=[\x00-\x7f])(\C) |
@@ -6359,10 +6837,10 @@
              (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) |
              (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C))
 
-       In this example, a group that starts  with  (?|  resets  the  capturing
+       In  this  example,  a  group  that starts with (?| resets the capturing
        parentheses numbers in each alternative (see "Duplicate Subpattern Num-
        bers" below). The assertions at the start of each branch check the next
-       UTF-8  character  for  values  whose encoding uses 1, 2, 3, or 4 bytes,
+       UTF-8 character for values whose encoding uses 1, 2,  3,  or  4  bytes,
        respectively. The character's individual bytes are then captured by the
        appropriate number of \C groups.
 
@@ -6371,48 +6849,67 @@
 
        An opening square bracket introduces a character class, terminated by a
        closing square bracket. A closing square bracket on its own is not spe-
-       cial  by  default.  If a closing square bracket is required as a member
+       cial by default.  If a closing square bracket is required as  a  member
        of the class, it should be the first data character in the class (after
-       an  initial  circumflex,  if present) or escaped with a backslash. This
-       means that, by default, an empty class cannot be defined.  However,  if
-       the  PCRE2_ALLOW_EMPTY_CLASS option is set, a closing square bracket at
+       an initial circumflex, if present) or escaped with  a  backslash.  This
+       means  that,  by default, an empty class cannot be defined. However, if
+       the PCRE2_ALLOW_EMPTY_CLASS option is set, a closing square bracket  at
        the start does end the (empty) class.
 
-       A character class matches a single character in the subject. A  matched
+       A  character class matches a single character in the subject. A matched
        character must be in the set of characters defined by the class, unless
-       the first character in the class definition is a circumflex,  in  which
+       the  first  character in the class definition is a circumflex, in which
        case the subject character must not be in the set defined by the class.
-       If a circumflex is actually required as a member of the  class,  ensure
+       If  a  circumflex is actually required as a member of the class, ensure
        it is not the first character, or escape it with a backslash.
 
-       For  example, the character class [aeiou] matches any lower case vowel,
-       while [^aeiou] matches any character that is not a  lower  case  vowel.
+       For example, the character class [aeiou] matches any lower case  vowel,
+       while  [^aeiou]  matches  any character that is not a lower case vowel.
        Note that a circumflex is just a convenient notation for specifying the
-       characters that are in the class by enumerating those that are  not.  A
-       class  that starts with a circumflex is not an assertion; it still con-
-       sumes a character from the subject string, and therefore  it  fails  if
+       characters  that  are in the class by enumerating those that are not. A
+       class that starts with a circumflex is not an assertion; it still  con-
+       sumes  a  character  from the subject string, and therefore it fails if
        the current pointer is at the end of the string.
 
-       When  caseless  matching  is set, any letters in a class represent both
-       their upper case and lower case versions, so for  example,  a  caseless
-       [aeiou]  matches  "A"  as well as "a", and a caseless [^aeiou] does not
+       When caseless matching is set, any letters in a  class  represent  both
+       their  upper  case  and lower case versions, so for example, a caseless
+       [aeiou] matches "A" as well as "a", and a caseless  [^aeiou]  does  not
        match "A", whereas a caseful version would.
 
-       Characters that might indicate line breaks are  never  treated  in  any
-       special  way  when  matching  character  classes,  whatever line-ending
-       sequence is in use,  and  whatever  setting  of  the  PCRE2_DOTALL  and
-       PCRE2_MULTILINE  options  is  used. A class such as [^a] always matches
+       Characters  that  might  indicate  line breaks are never treated in any
+       special way  when  matching  character  classes,  whatever  line-ending
+       sequence  is  in  use,  and  whatever  setting  of the PCRE2_DOTALL and
+       PCRE2_MULTILINE options is used. A class such as  [^a]  always  matches
        one of these characters.
 
-       The minus (hyphen) character can be used to specify a range of  charac-
-       ters  in  a  character  class.  For  example,  [d-m] matches any letter
-       between d and m, inclusive. If a  minus  character  is  required  in  a
-       class,  it  must  be  escaped  with a backslash or appear in a position
-       where it cannot be interpreted as indicating a range, typically as  the
+       The  character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V,
+       \w, and \W may appear in a character class, and add the characters that
+       they  match to the class. For example, [\dABCDEF] matches any hexadeci-
+       mal digit. In UTF modes, the PCRE2_UCP option affects the  meanings  of
+       \d,  \s,  \w  and  their upper case partners, just as it does when they
+       appear outside a character class, as described in the section  entitled
+       "Generic character types" above. The escape sequence \b has a different
+       meaning inside a character class; it matches the  backspace  character.
+       The  sequences  \B,  \N,  \R, and \X are not special inside a character
+       class. Like any other unrecognized  escape  sequences,  they  cause  an
+       error.
+
+       The  minus (hyphen) character can be used to specify a range of charac-
+       ters in a character  class.  For  example,  [d-m]  matches  any  letter
+       between  d  and  m,  inclusive.  If  a minus character is required in a
+       class, it must be escaped with a backslash  or  appear  in  a  position
+       where  it cannot be interpreted as indicating a range, typically as the
        first or last character in the class, or immediately after a range. For
-       example, [b-d-z] matches letters in the range b to d, a hyphen  charac-
+       example,  [b-d-z] matches letters in the range b to d, a hyphen charac-
        ter, or z.
 
+       Perl treats a hyphen as a literal if it appears before or after a POSIX
+       class (see below) or before or after a character type escape such as as
+       \d or \H.  However, unless the hyphen is  the  last  character  in  the
+       class,  Perl  outputs  a  warning  in its warning mode, as this is most
+       likely a user error. As PCRE2 has no facility for warning, an error  is
+       given in these cases.
+
        It is not possible to have the literal character "]" as the end charac-
        ter of a range. A pattern such as [W-]46] is interpreted as a class  of
        two  characters ("W" and "-") followed by a literal string "46]", so it
@@ -6422,15 +6919,15 @@
        The  octal or hexadecimal representation of "]" can also be used to end
        a range.
 
-       An error is generated if a POSIX character  class  (see  below)  or  an
-       escape  sequence other than one that defines a single character appears
-       at a point where a range ending character  is  expected.  For  example,
-       [z-\xff] is valid, but [A-\d] and [A-[:digit:]] are not.
-
        Ranges normally include all code points between the start and end char-
-       acters, inclusive. They can also be  used  for  code  points  specified
+       acters,  inclusive.  They  can  also  be used for code points specified
        numerically, for example [\000-\037]. Ranges can include any characters
-       that are valid for the current mode.
+       that  are  valid  for  the current mode. In any UTF mode, the so-called
+       "surrogate" characters (those whose code points lie between 0xd800  and
+       0xdfff  inclusive)  may  not  be  specified  explicitly by default (the
+       PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES option disables this  check).  How-
+       ever, ranges such as [\x{d7ff}-\x{e000}], which include the surrogates,
+       are always permitted.
 
        There is a special case in EBCDIC environments  for  ranges  whose  end
        points are both specified as literal letters in the same case. For com-
@@ -6446,18 +6943,6 @@
        character  tables  for  a French locale are in use, [\xc8-\xcb] matches
        accented E characters in both cases.
 
-       The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v,  \V,
-       \w, and \W may appear in a character class, and add the characters that
-       they match to the class. For example, [\dABCDEF] matches any  hexadeci-
-       mal  digit.  In UTF modes, the PCRE2_UCP option affects the meanings of
-       \d, \s, \w and their upper case partners, just as  it  does  when  they
-       appear  outside a character class, as described in the section entitled
-       "Generic character types" above. The escape sequence \b has a different
-       meaning  inside  a character class; it matches the backspace character.
-       The sequences \B, \N, \R, and \X are not  special  inside  a  character
-       class.  Like  any  other  unrecognized  escape sequences, they cause an
-       error.
-
        A circumflex can conveniently be used with  the  upper  case  character
        types  to specify a more restricted set of characters than the matching
        lower case type.  For example, the class [^\W_] matches any  letter  or
@@ -6594,20 +7079,26 @@
 
 INTERNAL OPTION SETTING
 
-       The  settings of the PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL, and
-       PCRE2_EXTENDED options (which are Perl-compatible) can be changed  from
-       within  the  pattern  by  a  sequence  of  Perl option letters enclosed
-       between "(?" and ")".  The option letters are
+       The  settings  of  the  PCRE2_CASELESS,  PCRE2_MULTILINE, PCRE2_DOTALL,
+       PCRE2_EXTENDED, PCRE2_EXTENDED_MORE, and PCRE2_NO_AUTO_CAPTURE  options
+       (which are Perl-compatible) can be changed from within the pattern by a
+       sequence of Perl option letters enclosed  between  "(?"  and  ")".  The
+       option letters are
 
          i  for PCRE2_CASELESS
          m  for PCRE2_MULTILINE
+         n  for PCRE2_NO_AUTO_CAPTURE
          s  for PCRE2_DOTALL
          x  for PCRE2_EXTENDED
+         xx for PCRE2_EXTENDED_MORE
 
        For example, (?im) sets caseless, multiline matching. It is also possi-
-       ble to unset these options by preceding the letter with a hyphen, and a
-       combined setting and unsetting such as (?im-sx), which sets PCRE2_CASE-
-       LESS    and    PCRE2_MULTILINE   while   unsetting   PCRE2_DOTALL   and
+       ble to unset these options by preceding the letter with a  hyphen.  The
+       two  "extended"  options are not independent; unsetting either one can-
+       cels the effects of both of them.
+
+       A  combined  setting  and  unsetting  such  as  (?im-sx),  which   sets
+       PCRE2_CASELESS  and  PCRE2_MULTILINE  while  unsetting PCRE2_DOTALL and
        PCRE2_EXTENDED, is also permitted. If a letter appears both before  and
        after  the  hyphen, the option is unset. An empty options setting "(?)"
        is allowed. Needless to say, it has no effect.
@@ -6618,32 +7109,27 @@
 
        When one of these option changes occurs at  top  level  (that  is,  not
        inside  subpattern parentheses), the change applies to the remainder of
-       the pattern that follows. If the change is placed right at the start of
-       a  pattern,  PCRE2  extracts  it  into  the global options (and it will
-       therefore show up in data extracted by the  pcre2_pattern_info()  func-
-       tion).
-
-       An  option  change  within a subpattern (see below for a description of
-       subpatterns) affects only that part of the subpattern that follows  it,
-       so
+       the pattern that follows. An option change  within  a  subpattern  (see
+       below  for  a description of subpatterns) affects only that part of the
+       subpattern that follows it, so
 
          (a(?i)b)c
 
-       matches  abc  and  aBc and no other strings (assuming PCRE2_CASELESS is
-       not used).  By this means, options can be made to have  different  set-
+       matches abc and aBc and no other strings  (assuming  PCRE2_CASELESS  is
+       not  used).   By this means, options can be made to have different set-
        tings in different parts of the pattern. Any changes made in one alter-
        native do carry on into subsequent branches within the same subpattern.
        For example,
 
          (a(?i)b|c)
 
-       matches  "ab",  "aB",  "c",  and "C", even though when matching "C" the
-       first branch is abandoned before the option setting.  This  is  because
-       the  effects  of option settings happen at compile time. There would be
+       matches "ab", "aB", "c", and "C", even though  when  matching  "C"  the
+       first  branch  is  abandoned before the option setting. This is because
+       the effects of option settings happen at compile time. There  would  be
        some very weird behaviour otherwise.
 
-       As a convenient shorthand, if any option settings are required  at  the
-       start  of a non-capturing subpattern (see the next section), the option
+       As  a  convenient shorthand, if any option settings are required at the
+       start of a non-capturing subpattern (see the next section), the  option
        letters may appear between the "?" and the ":". Thus the two patterns
 
          (?i:saturday|sunday)
@@ -6651,14 +7137,14 @@
 
        match exactly the same set of strings.
 
-       Note: There are other PCRE2-specific options that can  be  set  by  the
+       Note:  There  are  other  PCRE2-specific options that can be set by the
        application when the compiling function is called. The pattern can con-
-       tain special leading sequences such as (*CRLF)  to  override  what  the
-       application  has  set  or what has been defaulted. Details are given in
-       the section entitled "Newline sequences"  above.  There  are  also  the
-       (*UTF)  and  (*UCP)  leading  sequences that can be used to set UTF and
-       Unicode property modes; they are equivalent to  setting  the  PCRE2_UTF
-       and  PCRE2_UCP  options, respectively. However, the application can set
+       tain  special  leading  sequences  such as (*CRLF) to override what the
+       application has set or what has been defaulted. Details  are  given  in
+       the  section  entitled  "Newline  sequences"  above. There are also the
+       (*UTF) and (*UCP) leading sequences that can be used  to  set  UTF  and
+       Unicode  property  modes;  they are equivalent to setting the PCRE2_UTF
+       and PCRE2_UCP options, respectively. However, the application  can  set
        the PCRE2_NEVER_UTF and PCRE2_NEVER_UCP options, which lock out the use
        of the (*UTF) and (*UCP) sequences.
 
@@ -6672,18 +7158,18 @@
 
          cat(aract|erpillar|)
 
-       matches "cataract", "caterpillar", or "cat". Without  the  parentheses,
+       matches  "cataract",  "caterpillar", or "cat". Without the parentheses,
        it would match "cataract", "erpillar" or an empty string.
 
-       2.  It  sets  up  the  subpattern as a capturing subpattern. This means
+       2. It sets up the subpattern as  a  capturing  subpattern.  This  means
        that, when the whole pattern matches, the portion of the subject string
-       that  matched  the  subpattern is passed back to the caller, separately
-       from the portion that matched the whole pattern. (This applies only  to
-       the  traditional  matching function; the DFA matching function does not
+       that matched the subpattern is passed back to  the  caller,  separately
+       from  the portion that matched the whole pattern. (This applies only to
+       the traditional matching function; the DFA matching function  does  not
        support capturing.)
 
        Opening parentheses are counted from left to right (starting from 1) to
-       obtain  numbers  for  the  capturing  subpatterns.  For example, if the
+       obtain numbers for the  capturing  subpatterns.  For  example,  if  the
        string "the red king" is matched against the pattern
 
          the ((red|white) (king|queen))
@@ -6691,12 +7177,12 @@
        the captured substrings are "red king", "red", and "king", and are num-
        bered 1, 2, and 3, respectively.
 
-       The  fact  that  plain  parentheses  fulfil two functions is not always
-       helpful.  There are often times when a grouping subpattern is  required
-       without  a capturing requirement. If an opening parenthesis is followed
-       by a question mark and a colon, the subpattern does not do any  captur-
-       ing,  and  is  not  counted when computing the number of any subsequent
-       capturing subpatterns. For example, if the string "the white queen"  is
+       The fact that plain parentheses fulfil  two  functions  is  not  always
+       helpful.   There are often times when a grouping subpattern is required
+       without a capturing requirement. If an opening parenthesis is  followed
+       by  a question mark and a colon, the subpattern does not do any captur-
+       ing, and is not counted when computing the  number  of  any  subsequent
+       capturing  subpatterns. For example, if the string "the white queen" is
        matched against the pattern
 
          the ((?:red|white) (king|queen))
@@ -6704,37 +7190,37 @@
        the captured substrings are "white queen" and "queen", and are numbered
        1 and 2. The maximum number of capturing subpatterns is 65535.
 
-       As a convenient shorthand, if any option settings are required  at  the
-       start  of  a  non-capturing  subpattern,  the option letters may appear
+       As  a  convenient shorthand, if any option settings are required at the
+       start of a non-capturing subpattern,  the  option  letters  may  appear
        between the "?" and the ":". Thus the two patterns
 
          (?i:saturday|sunday)
          (?:(?i)saturday|sunday)
 
        match exactly the same set of strings. Because alternative branches are
-       tried  from  left  to right, and options are not reset until the end of
-       the subpattern is reached, an option setting in one branch does  affect
-       subsequent  branches,  so  the above patterns match "SUNDAY" as well as
+       tried from left to right, and options are not reset until  the  end  of
+       the  subpattern is reached, an option setting in one branch does affect
+       subsequent branches, so the above patterns match "SUNDAY"  as  well  as
        "Saturday".
 
 
 DUPLICATE SUBPATTERN NUMBERS
 
        Perl 5.10 introduced a feature whereby each alternative in a subpattern
-       uses  the same numbers for its capturing parentheses. Such a subpattern
-       starts with (?| and is itself a non-capturing subpattern. For  example,
+       uses the same numbers for its capturing parentheses. Such a  subpattern
+       starts  with (?| and is itself a non-capturing subpattern. For example,
        consider this pattern:
 
          (?|(Sat)ur|(Sun))day
 
-       Because  the two alternatives are inside a (?| group, both sets of cap-
-       turing parentheses are numbered one. Thus, when  the  pattern  matches,
-       you  can  look  at captured substring number one, whichever alternative
-       matched. This construct is useful when you want to  capture  part,  but
+       Because the two alternatives are inside a (?| group, both sets of  cap-
+       turing  parentheses  are  numbered one. Thus, when the pattern matches,
+       you can look at captured substring number  one,  whichever  alternative
+       matched.  This  construct  is useful when you want to capture part, but
        not all, of one of a number of alternatives. Inside a (?| group, paren-
-       theses are numbered as usual, but the number is reset at the  start  of
-       each  branch.  The numbers of any capturing parentheses that follow the
-       subpattern start after the highest number used in any branch. The  fol-
+       theses  are  numbered as usual, but the number is reset at the start of
+       each branch. The numbers of any capturing parentheses that  follow  the
+       subpattern  start after the highest number used in any branch. The fol-
        lowing example is taken from the Perl documentation. The numbers under-
        neath show in which buffer the captured content will be stored.
 
@@ -6742,14 +7228,14 @@
          / ( a )  (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x
          # 1            2         2  3        2     3     4
 
-       A back reference to a numbered subpattern uses the  most  recent  value
-       that  is  set  for that number by any subpattern. The following pattern
+       A  back  reference  to a numbered subpattern uses the most recent value
+       that is set for that number by any subpattern.  The  following  pattern
        matches "abcabc" or "defdef":
 
          /(?|(abc)|(def))\1/
 
-       In contrast, a subroutine call to a numbered subpattern  always  refers
-       to  the  first  one in the pattern with the given number. The following
+       In  contrast,  a subroutine call to a numbered subpattern always refers
+       to the first one in the pattern with the given  number.  The  following
        pattern matches "abcabc" or "defabc":
 
          /(?|(abc)|(def))(?1)/
@@ -6757,47 +7243,47 @@
        A relative reference such as (?-1) is no different: it is just a conve-
        nient way of computing an absolute group number.
 
-       If  a condition test for a subpattern's having matched refers to a non-
-       unique number, the test is true if any of the subpatterns of that  num-
+       If a condition test for a subpattern's having matched refers to a  non-
+       unique  number, the test is true if any of the subpatterns of that num-
        ber have matched.
 
-       An  alternative approach to using this "branch reset" feature is to use
+       An alternative approach to using this "branch reset" feature is to  use
        duplicate named subpatterns, as described in the next section.
 
 
 NAMED SUBPATTERNS
 
-       Identifying capturing parentheses by number is simple, but  it  can  be
-       very  hard  to keep track of the numbers in complicated regular expres-
-       sions. Furthermore, if an  expression  is  modified,  the  numbers  may
+       Identifying  capturing  parentheses  by number is simple, but it can be
+       very hard to keep track of the numbers in complicated  regular  expres-
+       sions.  Furthermore,  if  an  expression  is  modified, the numbers may
        change. To help with this difficulty, PCRE2 supports the naming of sub-
        patterns. This feature was not added to Perl until release 5.10. Python
-       had  the feature earlier, and PCRE1 introduced it at release 4.0, using
-       the Python syntax. PCRE2 supports both the Perl and the Python  syntax.
-       Perl  allows  identically numbered subpatterns to have different names,
+       had the feature earlier, and PCRE1 introduced it at release 4.0,  using
+       the  Python syntax. PCRE2 supports both the Perl and the Python syntax.
+       Perl allows identically numbered subpatterns to have  different  names,
        but PCRE2 does not.
 
-       In PCRE2, a subpattern can be named in one of three ways:  (?<name>...)
-       or  (?'name'...)  as in Perl, or (?P<name>...) as in Python. References
-       to capturing parentheses from other parts of the pattern, such as  back
-       references,  recursion,  and conditions, can be made by name as well as
+       In  PCRE2, a subpattern can be named in one of three ways: (?<name>...)
+       or (?'name'...) as in Perl, or (?P<name>...) as in  Python.  References
+       to  capturing parentheses from other parts of the pattern, such as back
+       references, recursion, and conditions, can be made by name as  well  as
        by number.
 
-       Names consist of up to 32 alphanumeric characters and underscores,  but
-       must  start  with  a  non-digit.  Named capturing parentheses are still
-       allocated numbers as well as names, exactly as if the  names  were  not
+       Names  consist of up to 32 alphanumeric characters and underscores, but
+       must start with a non-digit.  Named  capturing  parentheses  are  still
+       allocated  numbers  as  well as names, exactly as if the names were not
        present. The PCRE2 API provides function calls for extracting the name-
-       to-number translation table from a compiled  pattern.  There  are  also
+       to-number  translation  table  from  a compiled pattern. There are also
        convenience functions for extracting a captured substring by name.
 
-       By  default, a name must be unique within a pattern, but it is possible
-       to relax this constraint by setting the PCRE2_DUPNAMES option  at  com-
-       pile  time.  (Duplicate names are also always permitted for subpatterns
-       with the same number, set up as described  in  the  previous  section.)
-       Duplicate  names  can be useful for patterns where only one instance of
+       By default, a name must be unique within a pattern, but it is  possible
+       to  relax  this constraint by setting the PCRE2_DUPNAMES option at com-
+       pile time.  (Duplicate names are also always permitted for  subpatterns
+       with  the  same  number,  set up as described in the previous section.)
+       Duplicate names can be useful for patterns where only one  instance  of
        the named parentheses can match.  Suppose you want to match the name of
-       a  weekday,  either as a 3-letter abbreviation or as the full name, and
-       in both cases you  want  to  extract  the  abbreviation.  This  pattern
+       a weekday, either as a 3-letter abbreviation or as the full  name,  and
+       in  both  cases  you  want  to  extract  the abbreviation. This pattern
        (ignoring the line breaks) does the job:
 
          (?<DN>Mon|Fri|Sun)(?:day)?|
@@ -6806,18 +7292,18 @@
          (?<DN>Thu)(?:rsday)?|
          (?<DN>Sat)(?:urday)?
 
-       There  are  five capturing substrings, but only one is ever set after a
+       There are five capturing substrings, but only one is ever set  after  a
        match.  (An alternative way of solving this problem is to use a "branch
        reset" subpattern, as described in the previous section.)
 
-       The  convenience  functions for extracting the data by name returns the
-       substring for the first (and in this example, the only)  subpattern  of
-       that  name  that  matched.  This saves searching to find which numbered
+       The convenience functions for extracting the data by name  returns  the
+       substring  for  the first (and in this example, the only) subpattern of
+       that name that matched. This saves searching  to  find  which  numbered
        subpattern it was.
 
-       If you make a back reference to  a  non-unique  named  subpattern  from
-       elsewhere  in the pattern, the subpatterns to which the name refers are
-       checked in the order in which they appear in the overall  pattern.  The
+       If  you  make  a  back  reference to a non-unique named subpattern from
+       elsewhere in the pattern, the subpatterns to which the name refers  are
+       checked  in  the order in which they appear in the overall pattern. The
        first one that is set is used for the reference. For example, this pat-
        tern matches both "foofoo" and "barbar" but not "foobar" or "barfoo":
 
@@ -6825,29 +7311,29 @@
 
 
        If you make a subroutine call to a non-unique named subpattern, the one
-       that  corresponds  to  the first occurrence of the name is used. In the
+       that corresponds to the first occurrence of the name is  used.  In  the
        absence of duplicate numbers (see the previous section) this is the one
        with the lowest number.
 
        If you use a named reference in a condition test (see the section about
        conditions below), either to check whether a subpattern has matched, or
-       to  check for recursion, all subpatterns with the same name are tested.
-       If the condition is true for any one of them, the overall condition  is
-       true.  This  is  the  same  behaviour as testing by number. For further
-       details of the interfaces  for  handling  named  subpatterns,  see  the
+       to check for recursion, all subpatterns with the same name are  tested.
+       If  the condition is true for any one of them, the overall condition is
+       true. This is the same behaviour as  testing  by  number.  For  further
+       details  of  the  interfaces  for  handling  named subpatterns, see the
        pcre2api documentation.
 
        Warning: You cannot use different names to distinguish between two sub-
-       patterns with the same number because PCRE2 uses only the numbers  when
+       patterns  with the same number because PCRE2 uses only the numbers when
        matching. For this reason, an error is given at compile time if differ-
-       ent names are given to subpatterns with the same number.  However,  you
+       ent  names  are given to subpatterns with the same number. However, you
        can always give the same name to subpatterns with the same number, even
        when PCRE2_DUPNAMES is not set.
 
 
 REPETITION
 
-       Repetition is specified by quantifiers, which can  follow  any  of  the
+       Repetition  is  specified  by  quantifiers, which can follow any of the
        following items:
 
          a literal data character
@@ -6861,17 +7347,17 @@
          a parenthesized subpattern (including most assertions)
          a subroutine call to a subpattern (recursive or otherwise)
 
-       The  general repetition quantifier specifies a minimum and maximum num-
-       ber of permitted matches, by giving the two numbers in  curly  brackets
-       (braces),  separated  by  a comma. The numbers must be less than 65536,
+       The general repetition quantifier specifies a minimum and maximum  num-
+       ber  of  permitted matches, by giving the two numbers in curly brackets
+       (braces), separated by a comma. The numbers must be  less  than  65536,
        and the first must be less than or equal to the second. For example:
 
          z{2,4}
 
-       matches "zz", "zzz", or "zzzz". A closing brace on its  own  is  not  a
-       special  character.  If  the second number is omitted, but the comma is
-       present, there is no upper limit; if the second number  and  the  comma
-       are  both omitted, the quantifier specifies an exact number of required
+       matches  "zz",  "zzz",  or  "zzzz". A closing brace on its own is not a
+       special character. If the second number is omitted, but  the  comma  is
+       present,  there  is  no upper limit; if the second number and the comma
+       are both omitted, the quantifier specifies an exact number of  required
        matches. Thus
 
          [aeiou]{3,}
@@ -6880,50 +7366,50 @@
 
          \d{8}
 
-       matches exactly 8 digits. An opening curly bracket that  appears  in  a
-       position  where a quantifier is not allowed, or one that does not match
-       the syntax of a quantifier, is taken as a literal character. For  exam-
+       matches  exactly  8  digits. An opening curly bracket that appears in a
+       position where a quantifier is not allowed, or one that does not  match
+       the  syntax of a quantifier, is taken as a literal character. For exam-
        ple, {,6} is not a quantifier, but a literal string of four characters.
 
        In UTF modes, quantifiers apply to characters rather than to individual
-       code units. Thus, for example, \x{100}{2} matches two characters,  each
+       code  units. Thus, for example, \x{100}{2} matches two characters, each
        of which is represented by a two-byte sequence in a UTF-8 string. Simi-
-       larly, \X{3} matches three Unicode extended grapheme clusters, each  of
-       which  may  be  several  code  units long (and they may be of different
+       larly,  \X{3} matches three Unicode extended grapheme clusters, each of
+       which may be several code units long (and  they  may  be  of  different
        lengths).
 
        The quantifier {0} is permitted, causing the expression to behave as if
        the previous item and the quantifier were not present. This may be use-
-       ful for subpatterns that are referenced as subroutines  from  elsewhere
+       ful  for  subpatterns that are referenced as subroutines from elsewhere
        in the pattern (but see also the section entitled "Defining subpatterns
-       for use by reference only" below). Items other  than  subpatterns  that
+       for  use  by  reference only" below). Items other than subpatterns that
        have a {0} quantifier are omitted from the compiled pattern.
 
-       For  convenience, the three most common quantifiers have single-charac-
+       For convenience, the three most common quantifiers have  single-charac-
        ter abbreviations:
 
          *    is equivalent to {0,}
          +    is equivalent to {1,}
          ?    is equivalent to {0,1}
 
-       It is possible to construct infinite loops by  following  a  subpattern
+       It  is  possible  to construct infinite loops by following a subpattern
        that can match no characters with a quantifier that has no upper limit,
        for example:
 
          (a?)*
 
-       Earlier versions of Perl and PCRE1 used to give  an  error  at  compile
+       Earlier  versions  of  Perl  and PCRE1 used to give an error at compile
        time for such patterns. However, because there are cases where this can
        be useful, such patterns are now accepted, but if any repetition of the
-       subpattern  does in fact match no characters, the loop is forcibly bro-
+       subpattern does in fact match no characters, the loop is forcibly  bro-
        ken.
 
-       By default, the quantifiers are "greedy", that is, they match  as  much
-       as  possible  (up  to  the  maximum number of permitted times), without
-       causing the rest of the pattern to fail. The classic example  of  where
+       By  default,  the quantifiers are "greedy", that is, they match as much
+       as possible (up to the maximum  number  of  permitted  times),  without
+       causing  the  rest of the pattern to fail. The classic example of where
        this gives problems is in trying to match comments in C programs. These
-       appear between /* and */ and within the comment,  individual  *  and  /
-       characters  may  appear. An attempt to match C comments by applying the
+       appear  between  /*  and  */ and within the comment, individual * and /
+       characters may appear. An attempt to match C comments by  applying  the
        pattern
 
          /\*.*\*/
@@ -6932,19 +7418,19 @@
 
          /* first comment */  not comment  /* second comment */
 
-       fails, because it matches the entire string owing to the greediness  of
+       fails,  because it matches the entire string owing to the greediness of
        the .*  item.
 
        If a quantifier is followed by a question mark, it ceases to be greedy,
-       and instead matches the minimum number of times possible, so  the  pat-
+       and  instead  matches the minimum number of times possible, so the pat-
        tern
 
          /\*.*?\*/
 
-       does  the  right  thing with the C comments. The meaning of the various
-       quantifiers is not otherwise changed,  just  the  preferred  number  of
-       matches.   Do  not  confuse this use of question mark with its use as a
-       quantifier in its own right. Because it has two uses, it can  sometimes
+       does the right thing with the C comments. The meaning  of  the  various
+       quantifiers  is  not  otherwise  changed,  just the preferred number of
+       matches.  Do not confuse this use of question mark with its  use  as  a
+       quantifier  in its own right. Because it has two uses, it can sometimes
        appear doubled, as in
 
          \d??\d
@@ -6953,45 +7439,45 @@
        only way the rest of the pattern matches.
 
        If the PCRE2_UNGREEDY option is set (an option that is not available in
-       Perl),  the  quantifiers are not greedy by default, but individual ones
-       can be made greedy by following them with a  question  mark.  In  other
+       Perl), the quantifiers are not greedy by default, but  individual  ones
+       can  be  made  greedy  by following them with a question mark. In other
        words, it inverts the default behaviour.
 
-       When  a  parenthesized  subpattern  is quantified with a minimum repeat
-       count that is greater than 1 or with a limited maximum, more memory  is
-       required  for  the  compiled  pattern, in proportion to the size of the
+       When a parenthesized subpattern is quantified  with  a  minimum  repeat
+       count  that is greater than 1 or with a limited maximum, more memory is
+       required for the compiled pattern, in proportion to  the  size  of  the
        minimum or maximum.
 
-       If a pattern starts with  .*  or  .{0,}  and  the  PCRE2_DOTALL  option
-       (equivalent  to  Perl's /s) is set, thus allowing the dot to match new-
-       lines, the pattern is implicitly  anchored,  because  whatever  follows
-       will  be  tried against every character position in the subject string,
-       so there is no point in retrying the  overall  match  at  any  position
+       If  a  pattern  starts  with  .*  or  .{0,} and the PCRE2_DOTALL option
+       (equivalent to Perl's /s) is set, thus allowing the dot to  match  new-
+       lines,  the  pattern  is  implicitly anchored, because whatever follows
+       will be tried against every character position in the  subject  string,
+       so  there  is  no  point  in retrying the overall match at any position
        after the first. PCRE2 normally treats such a pattern as though it were
        preceded by \A.
 
-       In cases where it is known that the subject  string  contains  no  new-
-       lines,  it  is worth setting PCRE2_DOTALL in order to obtain this opti-
+       In  cases  where  it  is known that the subject string contains no new-
+       lines, it is worth setting PCRE2_DOTALL in order to obtain  this  opti-
        mization, or alternatively, using ^ to indicate anchoring explicitly.
 
-       However, there are some cases where the optimization  cannot  be  used.
+       However,  there  are  some cases where the optimization cannot be used.
        When .*  is inside capturing parentheses that are the subject of a back
        reference elsewhere in the pattern, a match at the start may fail where
        a later one succeeds. Consider, for example:
 
          (.*)abc\1
 
-       If  the subject is "xyz123abc123" the match point is the fourth charac-
+       If the subject is "xyz123abc123" the match point is the fourth  charac-
        ter. For this reason, such a pattern is not implicitly anchored.
 
-       Another case where implicit anchoring is not applied is when the  lead-
-       ing  .* is inside an atomic group. Once again, a match at the start may
+       Another  case where implicit anchoring is not applied is when the lead-
+       ing .* is inside an atomic group. Once again, a match at the start  may
        fail where a later one succeeds. Consider this pattern:
 
          (?>.*?a)b
 
-       It matches "ab" in the subject "aab". The use of the backtracking  con-
-       trol  verbs  (*PRUNE)  and  (*SKIP) also disable this optimization, and
+       It  matches "ab" in the subject "aab". The use of the backtracking con-
+       trol verbs (*PRUNE) and (*SKIP) also  disable  this  optimization,  and
        there is an option, PCRE2_NO_DOTSTAR_ANCHOR, to do so explicitly.
 
        When a capturing subpattern is repeated, the value captured is the sub-
@@ -7000,8 +7486,8 @@
          (tweedle[dume]{3}\s*)+
 
        has matched "tweedledum tweedledee" the value of the captured substring
-       is "tweedledee". However, if there are  nested  capturing  subpatterns,
-       the  corresponding captured values may have been set in previous itera-
+       is  "tweedledee".  However,  if there are nested capturing subpatterns,
+       the corresponding captured values may have been set in previous  itera-
        tions. For example, after
 
          (a|(b))+
@@ -7011,53 +7497,53 @@
 
 ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
 
-       With both maximizing ("greedy") and minimizing ("ungreedy"  or  "lazy")
-       repetition,  failure  of what follows normally causes the repeated item
-       to be re-evaluated to see if a different number of repeats  allows  the
-       rest  of  the pattern to match. Sometimes it is useful to prevent this,
-       either to change the nature of the match, or to cause it  fail  earlier
-       than  it otherwise might, when the author of the pattern knows there is
+       With  both  maximizing ("greedy") and minimizing ("ungreedy" or "lazy")
+       repetition, failure of what follows normally causes the  repeated  item
+       to  be  re-evaluated to see if a different number of repeats allows the
+       rest of the pattern to match. Sometimes it is useful to  prevent  this,
+       either  to  change the nature of the match, or to cause it fail earlier
+       than it otherwise might, when the author of the pattern knows there  is
        no point in carrying on.
 
-       Consider, for example, the pattern \d+foo when applied to  the  subject
+       Consider,  for  example, the pattern \d+foo when applied to the subject
        line
 
          123456bar
 
        After matching all 6 digits and then failing to match "foo", the normal
-       action of the matcher is to try again with only 5 digits  matching  the
-       \d+  item,  and  then  with  4,  and  so on, before ultimately failing.
-       "Atomic grouping" (a term taken from Jeffrey  Friedl's  book)  provides
-       the  means for specifying that once a subpattern has matched, it is not
+       action  of  the matcher is to try again with only 5 digits matching the
+       \d+ item, and then with  4,  and  so  on,  before  ultimately  failing.
+       "Atomic  grouping"  (a  term taken from Jeffrey Friedl's book) provides
+       the means for specifying that once a subpattern has matched, it is  not
        to be re-evaluated in this way.
 
-       If we use atomic grouping for the previous example, the  matcher  gives
-       up  immediately  on failing to match "foo" the first time. The notation
+       If  we  use atomic grouping for the previous example, the matcher gives
+       up immediately on failing to match "foo" the first time.  The  notation
        is a kind of special parenthesis, starting with (?> as in this example:
 
          (?>\d+)foo
 
-       This kind of parenthesis "locks up" the  part of the  pattern  it  con-
-       tains  once  it  has matched, and a failure further into the pattern is
-       prevented from backtracking into it. Backtracking past it  to  previous
+       This  kind  of  parenthesis "locks up" the  part of the pattern it con-
+       tains once it has matched, and a failure further into  the  pattern  is
+       prevented  from  backtracking into it. Backtracking past it to previous
        items, however, works as normal.
 
-       An  alternative  description  is that a subpattern of this type matches
-       exactly the string of characters that an identical  standalone  pattern
+       An alternative description is that a subpattern of  this  type  matches
+       exactly  the  string of characters that an identical standalone pattern
        would match, if anchored at the current point in the subject string.
 
        Atomic grouping subpatterns are not capturing subpatterns. Simple cases
        such as the above example can be thought of as a maximizing repeat that
-       must  swallow  everything  it can. So, while both \d+ and \d+? are pre-
-       pared to adjust the number of digits they match in order  to  make  the
+       must swallow everything it can. So, while both \d+ and  \d+?  are  pre-
+       pared  to  adjust  the number of digits they match in order to make the
        rest of the pattern match, (?>\d+) can only match an entire sequence of
        digits.
 
-       Atomic groups in general can of course contain arbitrarily  complicated
-       subpatterns,  and  can  be  nested. However, when the subpattern for an
+       Atomic  groups in general can of course contain arbitrarily complicated
+       subpatterns, and can be nested. However, when  the  subpattern  for  an
        atomic group is just a single repeated item, as in the example above, a
-       simpler  notation,  called  a "possessive quantifier" can be used. This
-       consists of an additional + character  following  a  quantifier.  Using
+       simpler notation, called a "possessive quantifier" can  be  used.  This
+       consists  of  an  additional  + character following a quantifier. Using
        this notation, the previous example can be rewritten as
 
          \d++foo
@@ -7067,46 +7553,46 @@
 
          (abc|xyz){2,3}+
 
-       Possessive  quantifiers  are  always  greedy;  the   setting   of   the
-       PCRE2_UNGREEDY  option  is  ignored. They are a convenient notation for
-       the simpler forms of atomic group. However, there is no  difference  in
+       Possessive   quantifiers   are   always  greedy;  the  setting  of  the
+       PCRE2_UNGREEDY option is ignored. They are a  convenient  notation  for
+       the  simpler  forms of atomic group. However, there is no difference in
        the meaning of a possessive quantifier and the equivalent atomic group,
-       though there may be a performance  difference;  possessive  quantifiers
+       though  there  may  be a performance difference; possessive quantifiers
        should be slightly faster.
 
-       The  possessive  quantifier syntax is an extension to the Perl 5.8 syn-
-       tax.  Jeffrey Friedl originated the idea (and the name)  in  the  first
+       The possessive quantifier syntax is an extension to the Perl  5.8  syn-
+       tax.   Jeffrey  Friedl  originated the idea (and the name) in the first
        edition of his book. Mike McCloskey liked it, so implemented it when he
        built Sun's Java package, and PCRE1 copied it from there. It ultimately
        found its way into Perl at release 5.10.
 
-       PCRE2  has  an  optimization  that automatically "possessifies" certain
-       simple pattern constructs. For example, the sequence A+B is treated  as
-       A++B  because  there is no point in backtracking into a sequence of A's
+       PCRE2 has an optimization  that  automatically  "possessifies"  certain
+       simple  pattern constructs. For example, the sequence A+B is treated as
+       A++B because there is no point in backtracking into a sequence  of  A's
        when B must follow.  This feature can be disabled by the PCRE2_NO_AUTO-
        POSSESS option, or starting the pattern with (*NO_AUTO_POSSESS).
 
-       When  a  pattern  contains an unlimited repeat inside a subpattern that
-       can itself be repeated an unlimited number of  times,  the  use  of  an
-       atomic  group  is  the  only way to avoid some failing matches taking a
+       When a pattern contains an unlimited repeat inside  a  subpattern  that
+       can  itself  be  repeated  an  unlimited number of times, the use of an
+       atomic group is the only way to avoid some  failing  matches  taking  a
        very long time indeed. The pattern
 
          (\D+|<\d+>)*[!?]
 
-       matches an unlimited number of substrings that either consist  of  non-
-       digits,  or  digits  enclosed in <>, followed by either ! or ?. When it
+       matches  an  unlimited number of substrings that either consist of non-
+       digits, or digits enclosed in <>, followed by either ! or  ?.  When  it
        matches, it runs quickly. However, if it is applied to
 
          aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 
-       it takes a long time before reporting  failure.  This  is  because  the
-       string  can be divided between the internal \D+ repeat and the external
-       * repeat in a large number of ways, and all  have  to  be  tried.  (The
-       example  uses  [!?]  rather than a single character at the end, because
-       both PCRE2 and Perl have an optimization that allows for  fast  failure
-       when  a single character is used. They remember the last single charac-
-       ter that is required for a match, and fail early if it is  not  present
-       in  the  string.)  If  the pattern is changed so that it uses an atomic
+       it  takes  a  long  time  before reporting failure. This is because the
+       string can be divided between the internal \D+ repeat and the  external
+       *  repeat  in  a  large  number of ways, and all have to be tried. (The
+       example uses [!?] rather than a single character at  the  end,  because
+       both  PCRE2  and Perl have an optimization that allows for fast failure
+       when a single character is used. They remember the last single  charac-
+       ter  that  is required for a match, and fail early if it is not present
+       in the string.) If the pattern is changed so that  it  uses  an  atomic
        group, like this:
 
          ((?>\D+)|<\d+>)*[!?]
@@ -7118,71 +7604,75 @@
 
        Outside a character class, a backslash followed by a digit greater than
        0 (and possibly further digits) is a back reference to a capturing sub-
-       pattern earlier (that is, to its left) in the pattern,  provided  there
+       pattern  earlier  (that is, to its left) in the pattern, provided there
        have been that many previous capturing left parentheses.
 
-       However,  if the decimal number following the backslash is less than 8,
-       it is always taken as a back reference, and causes  an  error  only  if
-       there  are  not that many capturing left parentheses in the entire pat-
-       tern. In other words, the parentheses that are referenced need  not  be
-       to  the  left of the reference for numbers less than 8. A "forward back
-       reference" of this type can make sense when a  repetition  is  involved
-       and  the  subpattern to the right has participated in an earlier itera-
+       However, if the decimal number following the backslash is less than  8,
+       it  is  always  taken  as a back reference, and causes an error only if
+       there are not that many capturing left parentheses in the  entire  pat-
+       tern.  In  other words, the parentheses that are referenced need not be
+       to the left of the reference for numbers less than 8. A  "forward  back
+       reference"  of  this  type can make sense when a repetition is involved
+       and the subpattern to the right has participated in an  earlier  itera-
        tion.
 
-       It is not possible to have a numerical "forward back  reference"  to  a
-       subpattern  whose  number  is  8  or  more  using this syntax because a
-       sequence such as \50 is interpreted as a character  defined  in  octal.
+       It  is  not  possible to have a numerical "forward back reference" to a
+       subpattern whose number is 8  or  more  using  this  syntax  because  a
+       sequence  such  as  \50 is interpreted as a character defined in octal.
        See the subsection entitled "Non-printing characters" above for further
-       details of the handling of digits following a backslash.  There  is  no
-       such  problem  when named parentheses are used. A back reference to any
+       details  of  the  handling of digits following a backslash. There is no
+       such problem when named parentheses are used. A back reference  to  any
        subpattern is possible using named parentheses (see below).
 
-       Another way of avoiding the ambiguity inherent in  the  use  of  digits
-       following  a  backslash  is  to use the \g escape sequence. This escape
-       must be followed by an unsigned number or a negative number, optionally
-       enclosed in braces. These examples are all identical:
+       Another  way  of  avoiding  the ambiguity inherent in the use of digits
+       following a backslash is to use the \g  escape  sequence.  This  escape
+       must be followed by a signed or unsigned number, optionally enclosed in
+       braces. These examples are all identical:
 
          (ring), \1
          (ring), \g1
          (ring), \g{1}
 
-       An  unsigned number specifies an absolute reference without the ambigu-
+       An unsigned number specifies an absolute reference without the  ambigu-
        ity that is present in the older syntax. It is also useful when literal
-       digits follow the reference. A negative number is a relative reference.
+       digits follow the reference. A signed number is a  relative  reference.
        Consider this example:
 
          (abc(def)ghi)\g{-1}
 
        The sequence \g{-1} is a reference to the most recently started captur-
        ing subpattern before \g, that is, is it equivalent to \2 in this exam-
-       ple.  Similarly, \g{-2} would be equivalent to \1. The use of  relative
-       references  can  be helpful in long patterns, and also in patterns that
-       are created by  joining  together  fragments  that  contain  references
+       ple.   Similarly, \g{-2} would be equivalent to \1. The use of relative
+       references can be helpful in long patterns, and also in  patterns  that
+       are  created  by  joining  together  fragments  that contain references
        within themselves.
 
-       A  back  reference matches whatever actually matched the capturing sub-
-       pattern in the current subject string, rather  than  anything  matching
+       The sequence \g{+1} is a reference to the  next  capturing  subpattern.
+       This  kind  of forward reference can be useful it patterns that repeat.
+       Perl does not support the use of + in this way.
+
+       A back reference matches whatever actually matched the  capturing  sub-
+       pattern  in  the  current subject string, rather than anything matching
        the subpattern itself (see "Subpatterns as subroutines" below for a way
        of doing that). So the pattern
 
          (sens|respons)e and \1ibility
 
-       matches "sense and sensibility" and "response and responsibility",  but
-       not  "sense and responsibility". If caseful matching is in force at the
-       time of the back reference, the case of letters is relevant. For  exam-
+       matches  "sense and sensibility" and "response and responsibility", but
+       not "sense and responsibility". If caseful matching is in force at  the
+       time  of the back reference, the case of letters is relevant. For exam-
        ple,
 
          ((?i)rah)\s+\1
 
-       matches  "rah  rah"  and  "RAH RAH", but not "RAH rah", even though the
+       matches "rah rah" and "RAH RAH", but not "RAH  rah",  even  though  the
        original capturing subpattern is matched caselessly.
 
-       There are several different ways of writing back  references  to  named
-       subpatterns.  The  .NET syntax \k{name} and the Perl syntax \k<name> or
-       \k'name' are supported, as is the Python syntax (?P=name). Perl  5.10's
+       There  are  several  different ways of writing back references to named
+       subpatterns. The .NET syntax \k{name} and the Perl syntax  \k<name>  or
+       \k'name'  are supported, as is the Python syntax (?P=name). Perl 5.10's
        unified back reference syntax, in which \g can be used for both numeric
-       and named references, is also supported. We  could  rewrite  the  above
+       and  named  references,  is  also supported. We could rewrite the above
        example in any of the following ways:
 
          (?<p1>(?i)rah)\s+\k<p1>
@@ -7190,86 +7680,96 @@
          (?P<p1>(?i)rah)\s+(?P=p1)
          (?<p1>(?i)rah)\s+\g{p1}
 
-       A  subpattern  that  is  referenced  by  name may appear in the pattern
+       A subpattern that is referenced by  name  may  appear  in  the  pattern
        before or after the reference.
 
-       There may be more than one back reference to the same subpattern. If  a
-       subpattern  has  not actually been used in a particular match, any back
+       There  may be more than one back reference to the same subpattern. If a
+       subpattern has not actually been used in a particular match,  any  back
        references to it always fail by default. For example, the pattern
 
          (a|(bc))\2
 
-       always fails if it starts to match "a" rather than  "bc".  However,  if
-       the  PCRE2_MATCH_UNSET_BACKREF  option  is  set at compile time, a back
+       always  fails  if  it starts to match "a" rather than "bc". However, if
+       the PCRE2_MATCH_UNSET_BACKREF option is set at  compile  time,  a  back
        reference to an unset value matches an empty string.
 
-       Because there may be many capturing parentheses in a pattern, all  dig-
-       its  following a backslash are taken as part of a potential back refer-
-       ence number.  If the pattern continues with  a  digit  character,  some
-       delimiter  must  be  used  to  terminate  the  back  reference.  If the
-       PCRE2_EXTENDED option is set, this can be white space.  Otherwise,  the
+       Because  there may be many capturing parentheses in a pattern, all dig-
+       its following a backslash are taken as part of a potential back  refer-
+       ence  number.   If  the  pattern continues with a digit character, some
+       delimiter must  be  used  to  terminate  the  back  reference.  If  the
+       PCRE2_EXTENDED  option  is set, this can be white space. Otherwise, the
        \g{ syntax or an empty comment (see "Comments" below) can be used.
 
    Recursive back references
 
-       A  back reference that occurs inside the parentheses to which it refers
-       fails when the subpattern is first used, so, for example,  (a\1)  never
-       matches.   However,  such references can be useful inside repeated sub-
+       A back reference that occurs inside the parentheses to which it  refers
+       fails  when  the subpattern is first used, so, for example, (a\1) never
+       matches.  However, such references can be useful inside  repeated  sub-
        patterns. For example, the pattern
 
          (a|b\1)+
 
        matches any number of "a"s and also "aba", "ababbaa" etc. At each iter-
-       ation  of  the  subpattern,  the  back  reference matches the character
-       string corresponding to the previous iteration. In order  for  this  to
-       work,  the  pattern must be such that the first iteration does not need
-       to match the back reference. This can be done using alternation, as  in
+       ation of the subpattern,  the  back  reference  matches  the  character
+       string  corresponding  to  the previous iteration. In order for this to
+       work, the pattern must be such that the first iteration does  not  need
+       to  match the back reference. This can be done using alternation, as in
        the example above, or by a quantifier with a minimum of zero.
 
-       Back  references of this type cause the group that they reference to be
-       treated as an atomic group.  Once the whole group has been  matched,  a
-       subsequent  matching  failure cannot cause backtracking into the middle
+       Back references of this type cause the group that they reference to  be
+       treated  as  an atomic group.  Once the whole group has been matched, a
+       subsequent matching failure cannot cause backtracking into  the  middle
        of the group.
 
 
 ASSERTIONS
 
-       An assertion is a test on the characters  following  or  preceding  the
+       An  assertion  is  a  test on the characters following or preceding the
        current matching point that does not consume any characters. The simple
-       assertions coded as \b, \B, \A, \G, \Z,  \z,  ^  and  $  are  described
+       assertions  coded  as  \b,  \B,  \A,  \G, \Z, \z, ^ and $ are described
        above.
 
-       More  complicated  assertions  are  coded as subpatterns. There are two
-       kinds: those that look ahead of the current  position  in  the  subject
-       string,  and  those  that  look  behind  it. An assertion subpattern is
-       matched in the normal way, except that it does not  cause  the  current
-       matching position to be changed.
+       More complicated assertions are coded as  subpatterns.  There  are  two
+       kinds:  those  that  look  ahead of the current position in the subject
+       string, and those that look behind it, and in each  case  an  assertion
+       may  be  positive  (must  succeed for matching to continue) or negative
+       (must not succeed for matching to continue). An assertion subpattern is
+       matched  in the normal way, except that, when matching continues after-
+       wards, the matching position in the subject string is as it was at  the
+       start of the assertion.
 
-       Assertion  subpatterns are not capturing subpatterns. If such an asser-
-       tion contains capturing subpatterns within it, these  are  counted  for
-       the  purposes  of numbering the capturing subpatterns in the whole pat-
-       tern. However, substring capturing is carried  out  only  for  positive
-       assertions. (Perl sometimes, but not always, does do capturing in nega-
-       tive assertions.)
+       Assertion  subpatterns  are  not capturing subpatterns. If an assertion
+       contains capturing subpatterns within it, these  are  counted  for  the
+       purposes  of  numbering the capturing subpatterns in the whole pattern.
+       However, substring capturing is carried out only  for  positive  asser-
+       tions that succeed, that is, one of their branches matches, so matching
+       continues after the assertion. If all branches of a positive  assertion
+       fail to match, nothing is captured, and control is passed to the previ-
+       ous backtracking point.
 
-       For  compatibility  with  Perl,  most  assertion  subpatterns  may   be
-       repeated;  though  it  makes  no sense to assert the same thing several
-       times, the side effect of capturing  parentheses  may  occasionally  be
-       useful.  However,  an  assertion  that forms the condition for a condi-
-       tional subpattern may not be quantified. In practice, for other  asser-
+       No capturing is done for a negative assertion unless it is  being  used
+       as  a condition in a conditional subpattern (see the discussion below).
+       Matching continues after a non-conditional negative assertion  only  if
+       all its branches fail to match.
+
+       For   compatibility  with  Perl,  most  assertion  subpatterns  may  be
+       repeated; though it makes no sense to assert  the  same  thing  several
+       times,  the  side  effect  of capturing parentheses may occasionally be
+       useful. However, an assertion that forms the  condition  for  a  condi-
+       tional  subpattern may not be quantified. In practice, for other asser-
        tions, there only three cases:
 
-       (1)  If  the  quantifier  is  {0}, the assertion is never obeyed during
-       matching.  However, it may  contain  internal  capturing  parenthesized
+       (1) If the quantifier is {0}, the  assertion  is  never  obeyed  during
+       matching.   However,  it  may  contain internal capturing parenthesized
        groups that are called from elsewhere via the subroutine mechanism.
 
-       (2)  If quantifier is {0,n} where n is greater than zero, it is treated
-       as if it were {0,1}. At run time, the rest  of  the  pattern  match  is
+       (2) If quantifier is {0,n} where n is greater than zero, it is  treated
+       as  if  it  were  {0,1}.  At run time, the rest of the pattern match is
        tried with and without the assertion, the order depending on the greed-
        iness of the quantifier.
 
-       (3) If the minimum repetition is greater than zero, the  quantifier  is
-       ignored.   The  assertion  is  obeyed just once when encountered during
+       (3)  If  the minimum repetition is greater than zero, the quantifier is
+       ignored.  The assertion is obeyed just  once  when  encountered  during
        matching.
 
    Lookahead assertions
@@ -7279,38 +7779,38 @@
 
          \w+(?=;)
 
-       matches  a word followed by a semicolon, but does not include the semi-
+       matches a word followed by a semicolon, but does not include the  semi-
        colon in the match, and
 
          foo(?!bar)
 
-       matches any occurrence of "foo" that is not  followed  by  "bar".  Note
+       matches  any  occurrence  of  "foo" that is not followed by "bar". Note
        that the apparently similar pattern
 
          (?!foo)bar
 
-       does  not  find  an  occurrence  of "bar" that is preceded by something
-       other than "foo"; it finds any occurrence of "bar" whatsoever,  because
+       does not find an occurrence of "bar"  that  is  preceded  by  something
+       other  than "foo"; it finds any occurrence of "bar" whatsoever, because
        the assertion (?!foo) is always true when the next three characters are
        "bar". A lookbehind assertion is needed to achieve the other effect.
 
        If you want to force a matching failure at some point in a pattern, the
-       most  convenient  way  to  do  it  is with (?!) because an empty string
-       always matches, so an assertion that requires there not to be an  empty
+       most convenient way to do it is  with  (?!)  because  an  empty  string
+       always  matches, so an assertion that requires there not to be an empty
        string must always fail.  The backtracking control verb (*FAIL) or (*F)
        is a synonym for (?!).
 
    Lookbehind assertions
 
-       Lookbehind assertions start with (?<= for positive assertions and  (?<!
+       Lookbehind  assertions start with (?<= for positive assertions and (?<!
        for negative assertions. For example,
 
          (?<!foo)bar
 
-       does  find  an  occurrence  of "bar" that is not preceded by "foo". The
-       contents of a lookbehind assertion are restricted  such  that  all  the
+       does find an occurrence of "bar" that is not  preceded  by  "foo".  The
+       contents  of  a  lookbehind  assertion are restricted such that all the
        strings it matches must have a fixed length. However, if there are sev-
-       eral top-level alternatives, they do not all  have  to  have  the  same
+       eral  top-level  alternatives,  they  do  not all have to have the same
        fixed length. Thus
 
          (?<=bullock|donkey)
@@ -7319,62 +7819,74 @@
 
          (?<!dogs?|cats?)
 
-       causes  an  error at compile time. Branches that match different length
-       strings are permitted only at the top level of a lookbehind  assertion.
+       causes an error at compile time. Branches that match  different  length
+       strings  are permitted only at the top level of a lookbehind assertion.
        This is an extension compared with Perl, which requires all branches to
        match the same length of string. An assertion such as
 
          (?<=ab(c|de))
 
-       is not permitted, because its single top-level  branch  can  match  two
-       different  lengths,  but  it is acceptable to PCRE2 if rewritten to use
+       is  not  permitted,  because  its single top-level branch can match two
+       different lengths, but it is acceptable to PCRE2 if  rewritten  to  use
        two top-level branches:
 
          (?<=abc|abde)
 
-       In some cases, the escape sequence \K (see above) can be  used  instead
+       In  some  cases, the escape sequence \K (see above) can be used instead
        of a lookbehind assertion to get round the fixed-length restriction.
 
-       The  implementation  of lookbehind assertions is, for each alternative,
-       to temporarily move the current position back by the fixed  length  and
+       The implementation of lookbehind assertions is, for  each  alternative,
+       to  temporarily  move the current position back by the fixed length and
        then try to match. If there are insufficient characters before the cur-
        rent position, the assertion fails.
 
-       In a UTF mode, PCRE2 does not allow the \C escape (which matches a sin-
-       gle  code  unit even in a UTF mode) to appear in lookbehind assertions,
-       because it makes it impossible to calculate the length of  the  lookbe-
-       hind.  The \X and \R escapes, which can match different numbers of code
-       units, are also not permitted.
+       In  UTF-8  and  UTF-16 modes, PCRE2 does not allow the \C escape (which
+       matches a single code unit even in a UTF mode) to appear in  lookbehind
+       assertions,  because  it makes it impossible to calculate the length of
+       the lookbehind. The \X and \R escapes, which can match  different  num-
+       bers of code units, are never permitted in lookbehinds.
 
-       "Subroutine" calls (see below) such as (?2) or (?&X) are  permitted  in
-       lookbehinds,  as  long as the subpattern matches a fixed-length string.
-       Recursion, however, is not supported.
+       "Subroutine"  calls  (see below) such as (?2) or (?&X) are permitted in
+       lookbehinds, as long as the subpattern matches a  fixed-length  string.
+       However,  recursion,  that is, a "subroutine" call into a group that is
+       already active, is not supported.
 
-       Possessive quantifiers can  be  used  in  conjunction  with  lookbehind
+       Perl does not support back references in lookbehinds. PCRE2  does  sup-
+       port   them,   but   only   if   certain   conditions   are   met.  The
+       PCRE2_MATCH_UNSET_BACKREF option must not be set, there must be no  use
+       of (?| in the pattern (it creates duplicate subpattern numbers), and if
+       the back reference is by name, the name must be unique. Of course,  the
+       referenced  subpattern  must  itself  be of fixed length. The following
+       pattern matches words containing at least two characters that begin and
+       end with the same character:
+
+          \b(\w)\w++(?<=\1)
+
+       Possessive  quantifiers  can  be  used  in  conjunction with lookbehind
        assertions to specify efficient matching of fixed-length strings at the
        end of subject strings. Consider a simple pattern such as
 
          abcd$
 
-       when applied to a long string that does  not  match.  Because  matching
-       proceeds  from  left to right, PCRE2 will look for each "a" in the sub-
-       ject and then see if what follows matches the rest of the  pattern.  If
+       when  applied  to  a  long string that does not match. Because matching
+       proceeds from left to right, PCRE2 will look for each "a" in  the  sub-
+       ject  and  then see if what follows matches the rest of the pattern. If
        the pattern is specified as
 
          ^.*abcd$
 
-       the  initial .* matches the entire string at first, but when this fails
+       the initial .* matches the entire string at first, but when this  fails
        (because there is no following "a"), it backtracks to match all but the
-       last  character,  then all but the last two characters, and so on. Once
-       again the search for "a" covers the entire string, from right to  left,
+       last character, then all but the last two characters, and so  on.  Once
+       again  the search for "a" covers the entire string, from right to left,
        so we are no better off. However, if the pattern is written as
 
          ^.*+(?<=abcd)
 
        there can be no backtracking for the .*+ item because of the possessive
        quantifier; it can match only the entire string. The subsequent lookbe-
-       hind  assertion  does  a single test on the last four characters. If it
-       fails, the match fails immediately. For  long  strings,  this  approach
+       hind assertion does a single test on the last four  characters.  If  it
+       fails,  the  match  fails  immediately. For long strings, this approach
        makes a significant difference to the processing time.
 
    Using multiple assertions
@@ -7383,18 +7895,18 @@
 
          (?<=\d{3})(?<!999)foo
 
-       matches  "foo" preceded by three digits that are not "999". Notice that
-       each of the assertions is applied independently at the  same  point  in
-       the  subject  string.  First  there  is a check that the previous three
-       characters are all digits, and then there is  a  check  that  the  same
+       matches "foo" preceded by three digits that are not "999". Notice  that
+       each  of  the  assertions is applied independently at the same point in
+       the subject string. First there is a  check  that  the  previous  three
+       characters  are  all  digits,  and  then there is a check that the same
        three characters are not "999".  This pattern does not match "foo" pre-
-       ceded by six characters, the first of which are  digits  and  the  last
-       three  of  which  are not "999". For example, it doesn't match "123abc-
+       ceded  by  six  characters,  the first of which are digits and the last
+       three of which are not "999". For example, it  doesn't  match  "123abc-
        foo". A pattern to do that is
 
          (?<=\d{3}...)(?<!999)foo
 
-       This time the first assertion looks at the  preceding  six  characters,
+       This  time  the  first assertion looks at the preceding six characters,
        checking that the first three are digits, and then the second assertion
        checks that the preceding three characters are not "999".
 
@@ -7402,29 +7914,29 @@
 
          (?<=(?<!foo)bar)baz
 
-       matches an occurrence of "baz" that is preceded by "bar" which in  turn
+       matches  an occurrence of "baz" that is preceded by "bar" which in turn
        is not preceded by "foo", while
 
          (?<=\d{3}(?!999)...)foo
 
-       is  another pattern that matches "foo" preceded by three digits and any
+       is another pattern that matches "foo" preceded by three digits and  any
        three characters that are not "999".
 
 
 CONDITIONAL SUBPATTERNS
 
-       It is possible to cause the matching process to obey a subpattern  con-
-       ditionally  or to choose between two alternative subpatterns, depending
-       on the result of an assertion, or whether a specific capturing  subpat-
-       tern  has  already  been matched. The two possible forms of conditional
+       It  is possible to cause the matching process to obey a subpattern con-
+       ditionally or to choose between two alternative subpatterns,  depending
+       on  the result of an assertion, or whether a specific capturing subpat-
+       tern has already been matched. The two possible  forms  of  conditional
        subpattern are:
 
          (?(condition)yes-pattern)
          (?(condition)yes-pattern|no-pattern)
 
-       If the condition is satisfied, the yes-pattern is used;  otherwise  the
-       no-pattern  (if  present)  is used. If there are more than two alterna-
-       tives in the subpattern, a compile-time error occurs. Each of  the  two
+       If  the  condition is satisfied, the yes-pattern is used; otherwise the
+       no-pattern (if present) is used. If there are more  than  two  alterna-
+       tives  in  the subpattern, a compile-time error occurs. Each of the two
        alternatives may itself contain nested subpatterns of any form, includ-
        ing  conditional  subpatterns;  the  restriction  to  two  alternatives
        applies only at the level of the condition. This pattern fragment is an
@@ -7433,93 +7945,114 @@
          (?(1) (A|B|C) | (D | (?(2)E|F) | E) )
 
 
-       There are five kinds of condition: references  to  subpatterns,  refer-
-       ences  to  recursion,  two pseudo-conditions called DEFINE and VERSION,
+       There  are  five  kinds of condition: references to subpatterns, refer-
+       ences to recursion, two pseudo-conditions called  DEFINE  and  VERSION,
        and assertions.
 
    Checking for a used subpattern by number
 
-       If the text between the parentheses consists of a sequence  of  digits,
+       If  the  text between the parentheses consists of a sequence of digits,
        the condition is true if a capturing subpattern of that number has pre-
-       viously matched. If there is more than one  capturing  subpattern  with
-       the  same  number  (see  the earlier section about duplicate subpattern
-       numbers), the condition is true if any of them have matched. An  alter-
-       native  notation is to precede the digits with a plus or minus sign. In
-       this case, the subpattern number is relative rather than absolute.  The
-       most  recently opened parentheses can be referenced by (?(-1), the next
-       most recent by (?(-2), and so on. Inside loops it can also  make  sense
+       viously  matched.  If  there is more than one capturing subpattern with
+       the same number (see the earlier  section  about  duplicate  subpattern
+       numbers),  the condition is true if any of them have matched. An alter-
+       native notation is to precede the digits with a plus or minus sign.  In
+       this  case, the subpattern number is relative rather than absolute. The
+       most recently opened parentheses can be referenced by (?(-1), the  next
+       most  recent  by (?(-2), and so on. Inside loops it can also make sense
        to refer to subsequent groups. The next parentheses to be opened can be
-       referenced as (?(+1), and so on. (The value zero in any of these  forms
+       referenced  as (?(+1), and so on. (The value zero in any of these forms
        is not used; it provokes a compile-time error.)
 
-       Consider  the  following  pattern, which contains non-significant white
-       space to make it more readable (assume the PCRE2_EXTENDED  option)  and
+       Consider the following pattern, which  contains  non-significant  white
+       space  to  make it more readable (assume the PCRE2_EXTENDED option) and
        to divide it into three parts for ease of discussion:
 
          ( \( )?    [^()]+    (?(1) \) )
 
-       The  first  part  matches  an optional opening parenthesis, and if that
+       The first part matches an optional opening  parenthesis,  and  if  that
        character is present, sets it as the first captured substring. The sec-
-       ond  part  matches one or more characters that are not parentheses. The
-       third part is a conditional subpattern that tests whether  or  not  the
-       first  set  of  parentheses  matched.  If they did, that is, if subject
-       started with an opening parenthesis, the condition is true, and so  the
-       yes-pattern  is  executed and a closing parenthesis is required. Other-
-       wise, since no-pattern is not present, the subpattern matches  nothing.
-       In  other  words,  this  pattern matches a sequence of non-parentheses,
+       ond part matches one or more characters that are not  parentheses.  The
+       third  part  is  a conditional subpattern that tests whether or not the
+       first set of parentheses matched. If they  did,  that  is,  if  subject
+       started  with an opening parenthesis, the condition is true, and so the
+       yes-pattern is executed and a closing parenthesis is  required.  Other-
+       wise,  since no-pattern is not present, the subpattern matches nothing.
+       In other words, this pattern matches  a  sequence  of  non-parentheses,
        optionally enclosed in parentheses.
 
-       If you were embedding this pattern in a larger one,  you  could  use  a
+       If  you  were  embedding  this pattern in a larger one, you could use a
        relative reference:
 
          ...other stuff... ( \( )?    [^()]+    (?(-1) \) ) ...
 
-       This  makes  the  fragment independent of the parentheses in the larger
+       This makes the fragment independent of the parentheses  in  the  larger
        pattern.
 
    Checking for a used subpattern by name
 
-       Perl uses the syntax (?(<name>)...) or (?('name')...)  to  test  for  a
-       used  subpattern  by  name.  For compatibility with earlier versions of
-       PCRE1, which had this facility before Perl, the syntax (?(name)...)  is
-       also recognized.
+       Perl  uses  the  syntax  (?(<name>)...) or (?('name')...) to test for a
+       used subpattern by name. For compatibility  with  earlier  versions  of
+       PCRE1,  which had this facility before Perl, the syntax (?(name)...) is
+       also recognized. Note, however, that undelimited  names  consisting  of
+       the  letter  R followed by digits are ambiguous (see the following sec-
+       tion).
 
        Rewriting the above example to use a named subpattern gives this:
 
          (?<OPEN> \( )?    [^()]+    (?(<OPEN>) \) )
 
-       If  the  name used in a condition of this kind is a duplicate, the test
-       is applied to all subpatterns of the same name, and is true if any  one
+       If the name used in a condition of this kind is a duplicate,  the  test
+       is  applied to all subpatterns of the same name, and is true if any one
        of them has matched.
 
    Checking for pattern recursion
 
-       If the condition is the string (R), and there is no subpattern with the
-       name R, the condition is true if a recursive call to the whole  pattern
-       or any subpattern has been made. If digits or a name preceded by amper-
-       sand follow the letter R, for example:
+       "Recursion" in this sense refers to any subroutine-like call  from  one
+       part  of  the  pattern to another, whether or not it is actually recur-
+       sive. See the sections entitled "Recursive patterns"  and  "Subpatterns
+       as subroutines" below for details of recursion and subpattern calls.
 
-         (?(R3)...) or (?(R&name)...)
+       If  a  condition is the string (R), and there is no subpattern with the
+       name R, the condition is true if matching is currently in  a  recursion
+       or  subroutine  call  to the whole pattern or any subpattern. If digits
+       follow the letter R, and there is no subpattern  with  that  name,  the
+       condition is true if the most recent call is into a subpattern with the
+       given number, which must exist somewhere in the overall  pattern.  This
+       is a contrived example that is equivalent to a+b:
+
+         ((?(R1)a+|(?1)b))
+
+       However,  in both cases, if there is a subpattern with a matching name,
+       the condition tests for its being set,  as  described  in  the  section
+       above,  instead of testing for recursion. For example, creating a group
+       with the name R1 by adding (?<R1>)  to  the  above  pattern  completely
+       changes its meaning.
+
+       If a name preceded by ampersand follows the letter R, for example:
+
+         (?(R&name)...)
 
        the condition is true if the most recent recursion is into a subpattern
-       whose number or name is given. This condition does not check the entire
-       recursion stack. If the name used in a condition  of  this  kind  is  a
+       of that name (which must exist within the pattern).
+
+       This condition does not check the entire recursion stack. It tests only
+       the  current  level.  If the name used in a condition of this kind is a
        duplicate, the test is applied to all subpatterns of the same name, and
        is true if any one of them is the most recent recursion.
 
-       At "top level", all these recursion test  conditions  are  false.   The
-       syntax for recursive patterns is described below.
+       At "top level", all these recursion test conditions are false.
 
    Defining subpatterns for use by reference only
 
-       If  the  condition  is  the string (DEFINE), and there is no subpattern
-       with the name DEFINE, the condition is  always  false.  In  this  case,
-       there  may  be  only  one  alternative  in the subpattern. It is always
-       skipped if control reaches this point  in  the  pattern;  the  idea  of
-       DEFINE  is that it can be used to define subroutines that can be refer-
-       enced from elsewhere. (The use of subroutines is described below.)  For
-       example,  a  pattern  to match an IPv4 address such as "192.168.23.245"
-       could be written like this (ignore white space and line breaks):
+       If the condition is the string (DEFINE), the condition is always false,
+       even if there is a group with the name DEFINE. In this case, there  may
+       be only one alternative in the subpattern. It is always skipped if con-
+       trol reaches this point in the pattern; the idea of DEFINE is  that  it
+       can  be  used  to  define subroutines that can be referenced from else-
+       where. (The use of subroutines is described below.) For example, a pat-
+       tern to match an IPv4 address such as "192.168.23.245" could be written
+       like this (ignore white space and line breaks):
 
          (?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
          \b (?&byte) (\.(?&byte)){3} \b
@@ -7566,48 +8099,55 @@
        strings in one of the two forms dd-aaa-dd or dd-dd-dd,  where  aaa  are
        letters and dd are digits.
 
+       When  an  assertion that is a condition contains capturing subpatterns,
+       any capturing that occurs in a matching branch is retained  afterwards,
+       for both positive and negative assertions, because matching always con-
+       tinues after the assertion, whether it succeeds or fails. (Compare non-
+       conditional  assertions,  when  captures are retained only for positive
+       assertions that succeed.)
+
 
 COMMENTS
 
        There are two ways of including comments in patterns that are processed
-       by PCRE2. In both cases, the start of the comment  must  not  be  in  a
-       character  class,  nor  in  the middle of any other sequence of related
-       characters such as (?: or a subpattern name or number.  The  characters
+       by  PCRE2.  In  both  cases,  the start of the comment must not be in a
+       character class, nor in the middle of any  other  sequence  of  related
+       characters  such  as (?: or a subpattern name or number. The characters
        that make up a comment play no part in the pattern matching.
 
-       The  sequence (?# marks the start of a comment that continues up to the
-       next closing parenthesis. Nested parentheses are not permitted. If  the
-       PCRE2_EXTENDED  option is set, an unescaped # character also introduces
-       a comment, which in this case continues to immediately after  the  next
-       newline  character  or character sequence in the pattern. Which charac-
-       ters are interpreted as newlines is controlled by an option  passed  to
-       the  compiling  function  or  by a special sequence at the start of the
-       pattern, as described in the  section  entitled  "Newline  conventions"
-       above.  Note  that the end of this type of comment is a literal newline
-       sequence in the pattern; escape sequences that happen  to  represent  a
-       newline   do  not  count.  For  example,  consider  this  pattern  when
-       PCRE2_EXTENDED is set, and the default  newline  convention  (a  single
+       The sequence (?# marks the start of a comment that continues up to  the
+       next  closing parenthesis. Nested parentheses are not permitted. If the
+       PCRE2_EXTENDED option is set, an unescaped # character also  introduces
+       a  comment,  which in this case continues to immediately after the next
+       newline character or character sequence in the pattern.  Which  charac-
+       ters  are  interpreted as newlines is controlled by an option passed to
+       the compiling function or by a special sequence at  the  start  of  the
+       pattern,  as  described  in  the section entitled "Newline conventions"
+       above. Note that the end of this type of comment is a  literal  newline
+       sequence  in  the  pattern; escape sequences that happen to represent a
+       newline  do  not  count.  For  example,  consider  this  pattern   when
+       PCRE2_EXTENDED  is  set,  and  the default newline convention (a single
        linefeed character) is in force:
 
          abc #comment \n still comment
 
-       On  encountering  the # character, pcre2_compile() skips along, looking
-       for a newline in the pattern. The sequence \n is still literal at  this
-       stage,  so  it does not terminate the comment. Only an actual character
+       On encountering the # character, pcre2_compile() skips  along,  looking
+       for  a newline in the pattern. The sequence \n is still literal at this
+       stage, so it does not terminate the comment. Only an  actual  character
        with the code value 0x0a (the default newline) does so.
 
 
 RECURSIVE PATTERNS
 
-       Consider the problem of matching a string in parentheses, allowing  for
-       unlimited  nested  parentheses.  Without the use of recursion, the best
-       that can be done is to use a pattern that  matches  up  to  some  fixed
-       depth  of  nesting.  It  is not possible to handle an arbitrary nesting
+       Consider  the problem of matching a string in parentheses, allowing for
+       unlimited nested parentheses. Without the use of  recursion,  the  best
+       that  can  be  done  is  to use a pattern that matches up to some fixed
+       depth of nesting. It is not possible to  handle  an  arbitrary  nesting
        depth.
 
        For some time, Perl has provided a facility that allows regular expres-
-       sions  to recurse (amongst other things). It does this by interpolating
-       Perl code in the expression at run time, and the code can refer to  the
+       sions to recurse (amongst other things). It does this by  interpolating
+       Perl  code in the expression at run time, and the code can refer to the
        expression itself. A Perl pattern using code interpolation to solve the
        parentheses problem can be created like this:
 
@@ -7617,206 +8157,171 @@
        refers recursively to the pattern in which it appears.
 
        Obviously,  PCRE2  cannot  support  the  interpolation  of  Perl  code.
-       Instead, it supports special syntax for recursion of  the  entire  pat-
+       Instead,  it  supports  special syntax for recursion of the entire pat-
        tern, and also for individual subpattern recursion. After its introduc-
-       tion in PCRE1 and Python,  this  kind  of  recursion  was  subsequently
+       tion  in  PCRE1  and  Python,  this  kind of recursion was subsequently
        introduced into Perl at release 5.10.
 
-       A  special  item  that consists of (? followed by a number greater than
-       zero and a closing parenthesis is a recursive subroutine  call  of  the
-       subpattern  of  the  given  number, provided that it occurs inside that
-       subpattern. (If not, it is a non-recursive subroutine  call,  which  is
-       described  in  the  next  section.)  The special item (?R) or (?0) is a
+       A special item that consists of (? followed by a  number  greater  than
+       zero  and  a  closing parenthesis is a recursive subroutine call of the
+       subpattern of the given number, provided that  it  occurs  inside  that
+       subpattern.  (If  not,  it is a non-recursive subroutine call, which is
+       described in the next section.) The special item  (?R)  or  (?0)  is  a
        recursive call of the entire regular expression.
 
-       This PCRE2 pattern solves the nested parentheses  problem  (assume  the
+       This  PCRE2  pattern  solves the nested parentheses problem (assume the
        PCRE2_EXTENDED option is set so that white space is ignored):
 
          \( ( [^()]++ | (?R) )* \)
 
-       First  it matches an opening parenthesis. Then it matches any number of
-       substrings which can either be a  sequence  of  non-parentheses,  or  a
-       recursive  match  of the pattern itself (that is, a correctly parenthe-
+       First it matches an opening parenthesis. Then it matches any number  of
+       substrings  which  can  either  be  a sequence of non-parentheses, or a
+       recursive match of the pattern itself (that is, a  correctly  parenthe-
        sized substring).  Finally there is a closing parenthesis. Note the use
        of a possessive quantifier to avoid backtracking into sequences of non-
        parentheses.
 
-       If this were part of a larger pattern, you would not  want  to  recurse
+       If  this  were  part of a larger pattern, you would not want to recurse
        the entire pattern, so instead you could use this:
 
          ( \( ( [^()]++ | (?1) )* \) )
 
-       We  have  put the pattern into parentheses, and caused the recursion to
+       We have put the pattern into parentheses, and caused the  recursion  to
        refer to them instead of the whole pattern.
 
-       In a larger pattern,  keeping  track  of  parenthesis  numbers  can  be
-       tricky.  This is made easier by the use of relative references. Instead
+       In  a  larger  pattern,  keeping  track  of  parenthesis numbers can be
+       tricky. This is made easier by the use of relative references.  Instead
        of (?1) in the pattern above you can write (?-2) to refer to the second
-       most  recently  opened  parentheses  preceding  the recursion. In other
-       words, a negative number counts capturing  parentheses  leftwards  from
+       most recently opened parentheses  preceding  the  recursion.  In  other
+       words,  a  negative  number counts capturing parentheses leftwards from
        the point at which it is encountered.
 
        Be aware however, that if duplicate subpattern numbers are in use, rel-
-       ative references refer to the earliest subpattern with the  appropriate
+       ative  references refer to the earliest subpattern with the appropriate
        number. Consider, for example:
 
          (?|(a)|(b)) (c) (?-2)
 
-       The  first  two  capturing  groups (a) and (b) are both numbered 1, and
-       group (c) is number 2. When the reference  (?-2)  is  encountered,  the
+       The first two capturing groups (a) and (b) are  both  numbered  1,  and
+       group  (c)  is  number  2. When the reference (?-2) is encountered, the
        second most recently opened parentheses has the number 1, but it is the
-       first such group (the (a) group) to which the  recursion  refers.  This
-       would  be  the  same  if  an absolute reference (?1) was used. In other
-       words, relative references are just a shorthand for computing  a  group
+       first  such  group  (the (a) group) to which the recursion refers. This
+       would be the same if an absolute reference  (?1)  was  used.  In  other
+       words,  relative  references are just a shorthand for computing a group
        number.
 
-       It  is  also  possible  to refer to subsequently opened parentheses, by
-       writing references such as (?+2). However, these  cannot  be  recursive
-       because  the  reference  is  not inside the parentheses that are refer-
-       enced. They are always non-recursive subroutine calls, as described  in
+       It is also possible to refer to  subsequently  opened  parentheses,  by
+       writing  references  such  as (?+2). However, these cannot be recursive
+       because the reference is not inside the  parentheses  that  are  refer-
+       enced.  They are always non-recursive subroutine calls, as described in
        the next section.
 
-       An  alternative  approach  is to use named parentheses. The Perl syntax
-       for this is (?&name); PCRE1's earlier syntax  (?P>name)  is  also  sup-
+       An alternative approach is to use named parentheses.  The  Perl  syntax
+       for  this  is  (?&name);  PCRE1's earlier syntax (?P>name) is also sup-
        ported. We could rewrite the above example as follows:
 
          (?<pn> \( ( [^()]++ | (?&pn) )* \) )
 
-       If  there  is more than one subpattern with the same name, the earliest
+       If there is more than one subpattern with the same name,  the  earliest
        one is used.
 
        The example pattern that we have been looking at contains nested unlim-
-       ited  repeats,  and  so the use of a possessive quantifier for matching
-       strings of non-parentheses is important when applying  the  pattern  to
+       ited repeats, and so the use of a possessive  quantifier  for  matching
+       strings  of  non-parentheses  is important when applying the pattern to
        strings that do not match. For example, when this pattern is applied to
 
          (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
 
-       it  yields  "no  match" quickly. However, if a possessive quantifier is
-       not used, the match runs for a very long time indeed because there  are
-       so  many  different  ways the + and * repeats can carve up the subject,
+       it yields "no match" quickly. However, if a  possessive  quantifier  is
+       not  used, the match runs for a very long time indeed because there are
+       so many different ways the + and * repeats can carve  up  the  subject,
        and all have to be tested before failure can be reported.
 
-       At the end of a match, the values of capturing  parentheses  are  those
-       from  the outermost level. If you want to obtain intermediate values, a
+       At  the  end  of a match, the values of capturing parentheses are those
+       from the outermost level. If you want to obtain intermediate values,  a
        callout function can be used (see below and the pcre2callout documenta-
        tion). If the pattern above is matched against
 
          (ab(cd)ef)
 
-       the  value  for  the  inner capturing parentheses (numbered 2) is "ef",
-       which is the last value taken on at the top level. If a capturing  sub-
-       pattern  is  not  matched at the top level, its final captured value is
-       unset, even if it was (temporarily) set at a deeper  level  during  the
+       the value for the inner capturing parentheses  (numbered  2)  is  "ef",
+       which  is the last value taken on at the top level. If a capturing sub-
+       pattern is not matched at the top level, its final  captured  value  is
+       unset,  even  if  it was (temporarily) set at a deeper level during the
        matching process.
 
        If there are more than 15 capturing parentheses in a pattern, PCRE2 has
-       to obtain extra memory from the heap to store data during a  recursion.
-       If   no   memory   can   be   obtained,   the   match  fails  with  the
+       to  obtain extra memory from the heap to store data during a recursion.
+       If  no  memory  can   be   obtained,   the   match   fails   with   the
        PCRE2_ERROR_NOMEMORY error.
 
-       Do not confuse the (?R) item with the condition (R),  which  tests  for
-       recursion.   Consider  this pattern, which matches text in angle brack-
-       ets, allowing for arbitrary nesting. Only digits are allowed in  nested
-       brackets  (that is, when recursing), whereas any characters are permit-
+       Do  not  confuse  the (?R) item with the condition (R), which tests for
+       recursion.  Consider this pattern, which matches text in  angle  brack-
+       ets,  allowing for arbitrary nesting. Only digits are allowed in nested
+       brackets (that is, when recursing), whereas any characters are  permit-
        ted at the outer level.
 
          < (?: (?(R) \d++  | [^<>]*+) | (?R)) * >
 
-       In this pattern, (?(R) is the start of a conditional  subpattern,  with
-       two  different  alternatives for the recursive and non-recursive cases.
+       In  this  pattern, (?(R) is the start of a conditional subpattern, with
+       two different alternatives for the recursive and  non-recursive  cases.
        The (?R) item is the actual recursive call.
 
    Differences in recursion processing between PCRE2 and Perl
 
-       Recursion processing in PCRE2 differs from Perl in two important  ways.
-       In PCRE2 (like Python, but unlike Perl), a recursive subpattern call is
-       always treated as an atomic group. That is, once it has matched some of
-       the subject string, it is never re-entered, even if it contains untried
-       alternatives and there is a subsequent matching failure.  This  can  be
-       illustrated  by the following pattern, which purports to match a palin-
-       dromic string that contains an odd number of characters  (for  example,
-       "a", "aba", "abcba", "abcdcba"):
+       Some former differences between PCRE2 and Perl no longer exist.
 
-         ^(.|(.)(?1)\2)$
+       Before  release 10.30, recursion processing in PCRE2 differed from Perl
+       in that a recursive subpattern call was always  treated  as  an  atomic
+       group.  That is, once it had matched some of the subject string, it was
+       never re-entered, even if it contained untried alternatives  and  there
+       was  a  subsequent matching failure. (Historical note: PCRE implemented
+       recursion before Perl did.)
 
-       The idea is that it either matches a single character, or two identical
-       characters surrounding a sub-palindrome. In Perl, this  pattern  works;
-       in  PCRE2  it  does not if the pattern is longer than three characters.
-       Consider the subject string "abcba":
+       Starting with release 10.30, recursive subroutine calls are  no  longer
+       treated as atomic. That is, they can be re-entered to try unused alter-
+       natives if there is a matching failure later in the  pattern.  This  is
+       now  compatible  with the way Perl works. If you want a subroutine call
+       to be atomic, you must explicitly enclose it in an atomic group.
 
-       At the top level, the first character is matched, but as it is  not  at
-       the end of the string, the first alternative fails; the second alterna-
-       tive is taken and the recursion kicks in. The recursive call to subpat-
-       tern  1  successfully  matches the next character ("b"). (Note that the
-       beginning and end of line tests are not part of the recursion).
-
-       Back at the top level, the next character ("c") is compared  with  what
-       subpattern  2 matched, which was "a". This fails. Because the recursion
-       is treated as an atomic group, there are now  no  backtracking  points,
-       and  so  the  entire  match fails. (Perl is able, at this point, to re-
-       enter the recursion and try the second alternative.)  However,  if  the
-       pattern is written with the alternatives in the other order, things are
-       different:
-
-         ^((.)(?1)\2|.)$
-
-       This time, the recursing alternative is tried first, and  continues  to
-       recurse  until  it runs out of characters, at which point the recursion
-       fails. But this time we do have  another  alternative  to  try  at  the
-       higher  level.  That  is  the  big difference: in the previous case the
-       remaining alternative is at a deeper recursion level, which PCRE2  can-
-       not use.
-
-       To  change  the pattern so that it matches all palindromic strings, not
-       just those with an odd number of characters, it is tempting  to  change
-       the pattern to this:
+       Supporting backtracking into recursions  simplifies  certain  types  of
+       recursive  pattern.  For  example,  this  pattern  matches  palindromic
+       strings:
 
          ^((.)(?1)\2|.?)$
 
-       Again,  this  works in Perl, but not in PCRE2, and for the same reason.
-       When a deeper recursion has matched a single character,  it  cannot  be
-       entered  again  in  order  to match an empty string. The solution is to
-       separate the two cases, and write out the odd and even cases as  alter-
-       natives at the higher level:
+       The second branch in the group matches a single  central  character  in
+       the  palindrome  when there are an odd number of characters, or nothing
+       when there are an even number of characters, but in order  to  work  it
+       has  to  be  able  to  try the second case when the rest of the pattern
+       match fails. If you want to match typical palindromic phrases, the pat-
+       tern  has  to  ignore  all  non-word characters, which can be done like
+       this:
 
-         ^(?:((.)(?1)\2|)|((.)(?3)\4|.))
-
-       If  you  want  to match typical palindromic phrases, the pattern has to
-       ignore all non-word characters, which can be done like this:
-
-         ^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$
+         ^\W*+((.)\W*+(?1)\W*+\2|\W*+.?)\W*+$
 
        If run with the PCRE2_CASELESS option,  this  pattern  matches  phrases
-       such  as  "A  man, a plan, a canal: Panama!" and it works in both PCRE2
-       and Perl. Note the use of the possessive quantifier *+ to  avoid  back-
-       tracking  into  sequences  of  non-word characters. Without this, PCRE2
-       takes a great deal longer (ten times or more) to match typical phrases,
-       and Perl takes so long that you think it has gone into a loop.
+       such  as "A man, a plan, a canal: Panama!". Note the use of the posses-
+       sive quantifier *+ to avoid backtracking  into  sequences  of  non-word
+       characters. Without this, PCRE2 takes a great deal longer (ten times or
+       more) to match typical phrases, and Perl takes so long that  you  think
+       it has gone into a loop.
 
-       WARNING:  The  palindrome-matching patterns above work only if the sub-
-       ject string does not start with a palindrome that is shorter  than  the
-       entire  string.  For example, although "abcba" is correctly matched, if
-       the subject is "ababa", PCRE2 finds the palindrome "aba" at the  start,
-       then  fails at top level because the end of the string does not follow.
-       Once again, it cannot jump back into the recursion to try other  alter-
-       natives, so the entire match fails.
-
-       The  second  way in which PCRE2 and Perl differ in their recursion pro-
-       cessing is in the handling of captured values. In Perl, when a  subpat-
-       tern  is  called recursively or as a subpattern (see the next section),
-       it has no access to any values that were captured  outside  the  recur-
-       sion,  whereas  in  PCRE2 these values can be referenced. Consider this
-       pattern:
+       Another  way  in which PCRE2 and Perl used to differ in their recursion
+       processing is in the handling of captured  values.  Formerly  in  Perl,
+       when  a  subpattern  was called recursively or as a subpattern (see the
+       next section), it had no access to any values that were  captured  out-
+       side  the  recursion,  whereas in PCRE2 these values can be referenced.
+       Consider this pattern:
 
          ^(.)(\1|a(?2))
 
-       In PCRE2, this pattern matches "bab". The first  capturing  parentheses
-       match  "b",  then in the second group, when the back reference \1 fails
-       to match "b", the second alternative matches "a" and then recurses.  In
-       the  recursion,  \1 does now match "b" and so the whole match succeeds.
-       In Perl, the pattern fails to match because inside the  recursive  call
-       \1 cannot access the externally set value.
+       This pattern matches "bab". The first capturing parentheses match  "b",
+       then  in  the  second  group, when the back reference \1 fails to match
+       "b", the second alternative matches  "a"  and  then  recurses.  In  the
+       recursion,  \1 does now match "b" and so the whole match succeeds. This
+       match used to fail in Perl, but in later versions (I  tried  5.024)  it
+       now works.
 
 
 SUBPATTERNS AS SUBROUTINES
@@ -7844,12 +8349,10 @@
        two  strings.  Another  example  is  given  in the discussion of DEFINE
        above.
 
-       All subroutine calls, whether recursive or not, are always  treated  as
-       atomic  groups. That is, once a subroutine has matched some of the sub-
-       ject string, it is never re-entered, even if it contains untried alter-
-       natives  and  there  is  a  subsequent  matching failure. Any capturing
-       parentheses that are set during the subroutine  call  revert  to  their
-       previous values afterwards.
+       Like recursions, subroutine calls used to be  treated  as  atomic,  but
+       this  changed  at  PCRE2 release 10.30, so backtracking into subroutine
+       calls can now occur. However, any capturing parentheses  that  are  set
+       during the subroutine call revert to their previous values afterwards.
 
        Processing  options  such as case-independence are fixed when a subpat-
        tern is defined, so if it is used as a subroutine, such options  cannot
@@ -7956,43 +8459,46 @@
 
 BACKTRACKING CONTROL
 
-       Perl 5.10 introduced a number of "Special Backtracking Control  Verbs",
-       which  are  still  described in the Perl documentation as "experimental
-       and subject to change or removal in a future version of Perl". It  goes
-       on  to  say:  "Their  usage in production code should be noted to avoid
-       problems during upgrades." The same remarks apply to the PCRE2 features
-       described in this section.
-
-       The  new verbs make use of what was previously invalid syntax: an open-
-       ing parenthesis followed by an asterisk. They are generally of the form
-       (*VERB) or (*VERB:NAME). Some verbs take either form, possibly behaving
-       differently depending on whether or not a name is present.
+       There are a number of special  "Backtracking  Control  Verbs"  (to  use
+       Perl's  terminology)  that  modify the behaviour of backtracking during
+       matching. They are generally of the form (*VERB) or (*VERB:NAME).  Some
+       verbs  take  either  form,  possibly  behaving differently depending on
+       whether or not a name is present.
 
        By default, for compatibility with Perl, a  name  is  any  sequence  of
        characters that does not include a closing parenthesis. The name is not
        processed in any way, and it is  not  possible  to  include  a  closing
-       parenthesis in the name.  However, if the PCRE2_ALT_VERBNAMES option is
-       set, normal backslash processing is applied to verb names and  only  an
-       unescaped  closing parenthesis terminates the name. A closing parenthe-
-       sis can be included in a name either as \) or between \Q and \E. If the
-       PCRE2_EXTENDED  option  is  set,  unescaped whitespace in verb names is
-       skipped and #-comments are recognized, exactly as in the  rest  of  the
-       pattern.
+       parenthesis   in  the  name.   This  can  be  changed  by  setting  the
+       PCRE2_ALT_VERBNAMES option, but the result is no  longer  Perl-compati-
+       ble.
 
-       The  maximum  length of a name is 255 in the 8-bit library and 65535 in
-       the 16-bit and 32-bit libraries. If the name is empty, that is, if  the
-       closing  parenthesis immediately follows the colon, the effect is as if
+       When  PCRE2_ALT_VERBNAMES  is  set,  backslash processing is applied to
+       verb names and only an unescaped  closing  parenthesis  terminates  the
+       name.  However, the only backslash items that are permitted are \Q, \E,
+       and sequences such as \x{100} that define character code points.  Char-
+       acter type escapes such as \d are faulted.
+
+       A closing parenthesis can be included in a name either as \) or between
+       \Q and \E. In addition to backslash processing, if  the  PCRE2_EXTENDED
+       option  is also set, unescaped whitespace in verb names is skipped, and
+       #-comments are recognized, exactly as  in  the  rest  of  the  pattern.
+       PCRE2_EXTENDED does not affect verb names unless PCRE2_ALT_VERBNAMES is
+       also set.
+
+       The maximum length of a name is 255 in the 8-bit library and  65535  in
+       the  16-bit and 32-bit libraries. If the name is empty, that is, if the
+       closing parenthesis immediately follows the colon, the effect is as  if
        the colon were not there. Any number of these verbs may occur in a pat-
        tern.
 
-       Since  these  verbs  are  specifically related to backtracking, most of
-       them can be used only when the pattern is to be matched using the  tra-
-       ditional matching function, because these use a backtracking algorithm.
-       With the exception of (*FAIL), which behaves like  a  failing  negative
+       Since these verbs are specifically related  to  backtracking,  most  of
+       them  can be used only when the pattern is to be matched using the tra-
+       ditional matching function, because that uses a backtracking algorithm.
+       With  the  exception  of (*FAIL), which behaves like a failing negative
        assertion, the backtracking control verbs cause an error if encountered
        by the DFA matching function.
 
-       The behaviour of these verbs in repeated  groups,  assertions,  and  in
+       The  behaviour  of  these  verbs in repeated groups, assertions, and in
        subpatterns called as subroutines (whether or not recursively) is docu-
        mented below.
 
@@ -8000,71 +8506,71 @@
 
        PCRE2 contains some optimizations that are used to speed up matching by
        running some checks at the start of each match attempt. For example, it
-       may know the minimum length of matching subject, or that  a  particular
+       may  know  the minimum length of matching subject, or that a particular
        character must be present. When one of these optimizations bypasses the
-       running of a match,  any  included  backtracking  verbs  will  not,  of
+       running  of  a  match,  any  included  backtracking  verbs will not, of
        course, be processed. You can suppress the start-of-match optimizations
-       by setting the PCRE2_NO_START_OPTIMIZE option when  calling  pcre2_com-
-       pile(),  or by starting the pattern with (*NO_START_OPT). There is more
+       by  setting  the PCRE2_NO_START_OPTIMIZE option when calling pcre2_com-
+       pile(), or by starting the pattern with (*NO_START_OPT). There is  more
        discussion of this option in the section entitled "Compiling a pattern"
        in the pcre2api documentation.
 
-       Experiments  with  Perl  suggest that it too has similar optimizations,
+       Experiments with Perl suggest that it too  has  similar  optimizations,
        sometimes leading to anomalous results.
 
    Verbs that act immediately
 
-       The following verbs act as soon as they are encountered. They  may  not
+       The  following  verbs act as soon as they are encountered. They may not
        be followed by a name.
 
           (*ACCEPT)
 
-       This  verb causes the match to end successfully, skipping the remainder
-       of the pattern. However, when it is inside a subpattern that is  called
-       as  a  subroutine, only that subpattern is ended successfully. Matching
+       This verb causes the match to end successfully, skipping the  remainder
+       of  the pattern. However, when it is inside a subpattern that is called
+       as a subroutine, only that subpattern is ended  successfully.  Matching
        then continues at the outer level. If (*ACCEPT) in triggered in a posi-
-       tive  assertion,  the  assertion succeeds; in a negative assertion, the
+       tive assertion, the assertion succeeds; in a  negative  assertion,  the
        assertion fails.
 
-       If (*ACCEPT) is inside capturing parentheses, the data so far  is  cap-
+       If  (*ACCEPT)  is inside capturing parentheses, the data so far is cap-
        tured. For example:
 
          A((?:A|B(*ACCEPT)|C)D)
 
-       This  matches  "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap-
+       This matches "AB", "AAD", or "ACD"; when it matches "AB", "B"  is  cap-
        tured by the outer parentheses.
 
          (*FAIL) or (*F)
 
-       This verb causes a matching failure, forcing backtracking to occur.  It
-       is  equivalent to (?!) but easier to read. The Perl documentation notes
-       that it is probably useful only when combined  with  (?{})  or  (??{}).
-       Those  are, of course, Perl features that are not present in PCRE2. The
-       nearest equivalent is the callout feature, as for example in this  pat-
+       This  verb causes a matching failure, forcing backtracking to occur. It
+       is equivalent to (?!) but easier to read. The Perl documentation  notes
+       that  it  is  probably  useful only when combined with (?{}) or (??{}).
+       Those are, of course, Perl features that are not present in PCRE2.  The
+       nearest  equivalent is the callout feature, as for example in this pat-
        tern:
 
          a+(?C)(*FAIL)
 
-       A  match  with the string "aaaa" always fails, but the callout is taken
+       A match with the string "aaaa" always fails, but the callout  is  taken
        before each backtrack happens (in this example, 10 times).
 
    Recording which path was taken
 
-       There is one verb whose main purpose  is  to  track  how  a  match  was
-       arrived  at,  though  it  also  has a secondary use in conjunction with
+       There  is  one  verb  whose  main  purpose  is to track how a match was
+       arrived at, though it also has a  secondary  use  in  conjunction  with
        advancing the match starting point (see (*SKIP) below).
 
          (*MARK:NAME) or (*:NAME)
 
-       A name is always  required  with  this  verb.  There  may  be  as  many
-       instances  of  (*MARK) as you like in a pattern, and their names do not
+       A  name  is  always  required  with  this  verb.  There  may be as many
+       instances of (*MARK) as you like in a pattern, and their names  do  not
        have to be unique.
 
-       When a match succeeds, the name of the  last-encountered  (*MARK:NAME),
-       (*PRUNE:NAME),  or  (*THEN:NAME) on the matching path is passed back to
-       the caller as described in  the  section  entitled  "Other  information
-       about  the  match" in the pcre2api documentation. Here is an example of
-       pcre2test output, where the "mark" modifier requests the retrieval  and
+       When  a  match succeeds, the name of the last-encountered (*MARK:NAME),
+       (*PRUNE:NAME), or (*THEN:NAME) on the matching path is passed  back  to
+       the  caller  as  described  in  the section entitled "Other information
+       about the match" in the pcre2api documentation. Here is an  example  of
+       pcre2test  output, where the "mark" modifier requests the retrieval and
        outputting of (*MARK) data:
 
            re> /X(*MARK:A)Y|X(*MARK:B)Z/mark
@@ -8076,72 +8582,72 @@
          MK: B
 
        The (*MARK) name is tagged with "MK:" in this output, and in this exam-
-       ple it indicates which of the two alternatives matched. This is a  more
-       efficient  way of obtaining this information than putting each alterna-
+       ple  it indicates which of the two alternatives matched. This is a more
+       efficient way of obtaining this information than putting each  alterna-
        tive in its own capturing parentheses.
 
-       If a verb with a name is encountered in a positive  assertion  that  is
-       true,  the  name  is recorded and passed back if it is the last-encoun-
+       If  a  verb  with a name is encountered in a positive assertion that is
+       true, the name is recorded and passed back if it  is  the  last-encoun-
        tered. This does not happen for negative assertions or failing positive
        assertions.
 
-       After  a  partial match or a failed match, the last encountered name in
+       After a partial match or a failed match, the last encountered  name  in
        the entire match process is returned. For example:
 
            re> /X(*MARK:A)Y|X(*MARK:B)Z/mark
          data> XP
          No match, mark = B
 
-       Note that in this unanchored example the  mark  is  retained  from  the
+       Note  that  in  this  unanchored  example the mark is retained from the
        match attempt that started at the letter "X" in the subject. Subsequent
        match attempts starting at "P" and then with an empty string do not get
        as far as the (*MARK) item, but nevertheless do not reset it.
 
-       If  you  are  interested  in  (*MARK)  values after failed matches, you
-       should probably set the PCRE2_NO_START_OPTIMIZE option (see  above)  to
+       If you are interested in  (*MARK)  values  after  failed  matches,  you
+       should  probably  set the PCRE2_NO_START_OPTIMIZE option (see above) to
        ensure that the match is always attempted.
 
    Verbs that act after backtracking
 
        The following verbs do nothing when they are encountered. Matching con-
-       tinues with what follows, but if there is no subsequent match,  causing
-       a  backtrack  to  the  verb, a failure is forced. That is, backtracking
-       cannot pass to the left of the verb. However, when one of  these  verbs
-       appears inside an atomic group (which includes any group that is called
-       as a subroutine) or in an assertion that is true, its  effect  is  con-
-       fined  to that group, because once the group has been matched, there is
-       never any backtracking into it. In this situation, backtracking has  to
-       jump to the left of the entire atomic group or assertion.
+       tinues  with what follows, but if there is no subsequent match, causing
+       a backtrack to the verb, a failure is  forced.  That  is,  backtracking
+       cannot  pass  to the left of the verb. However, when one of these verbs
+       appears inside an atomic group or in an assertion  that  is  true,  its
+       effect  is  confined  to  that  group,  because once the group has been
+       matched, there is never any backtracking into it.  In  this  situation,
+       backtracking  has  to  jump  to  the left of the entire atomic group or
+       assertion.
 
-       These  verbs  differ  in exactly what kind of failure occurs when back-
-       tracking reaches them. The behaviour described below  is  what  happens
-       when  the  verb is not in a subroutine or an assertion. Subsequent sec-
+       These verbs differ in exactly what kind of failure  occurs  when  back-
+       tracking  reaches  them.  The behaviour described below is what happens
+       when the verb is not in a subroutine or an assertion.  Subsequent  sec-
        tions cover these special cases.
 
          (*COMMIT)
 
-       This verb, which may not be followed by a name, causes the whole  match
+       This  verb, which may not be followed by a name, causes the whole match
        to fail outright if there is a later matching failure that causes back-
-       tracking to reach it. Even if the pattern  is  unanchored,  no  further
+       tracking  to  reach  it.  Even if the pattern is unanchored, no further
        attempts to find a match by advancing the starting point take place. If
-       (*COMMIT) is the only backtracking verb that is  encountered,  once  it
-       has  been  passed  pcre2_match() is committed to finding a match at the
+       (*COMMIT)  is  the  only backtracking verb that is encountered, once it
+       has been passed pcre2_match() is committed to finding a  match  at  the
        current starting point, or not at all. For example:
 
          a+(*COMMIT)b
 
-       This matches "xxaab" but not "aacaab". It can be thought of as  a  kind
+       This  matches  "xxaab" but not "aacaab". It can be thought of as a kind
        of dynamic anchor, or "I've started, so I must finish." The name of the
-       most recently passed (*MARK) in the path is passed back when  (*COMMIT)
+       most  recently passed (*MARK) in the path is passed back when (*COMMIT)
        forces a match failure.
 
-       If  there  is more than one backtracking verb in a pattern, a different
-       one that follows (*COMMIT) may be triggered first,  so  merely  passing
+       If there is more than one backtracking verb in a pattern,  a  different
+       one  that  follows  (*COMMIT) may be triggered first, so merely passing
        (*COMMIT) during a match does not always guarantee that a match must be
        at this starting point.
 
-       Note that (*COMMIT) at the start of a pattern is not  the  same  as  an
-       anchor,  unless PCRE2's start-of-match optimizations are turned off, as
+       Note  that  (*COMMIT)  at  the start of a pattern is not the same as an
+       anchor, unless PCRE2's start-of-match optimizations are turned off,  as
        shown in this output from pcre2test:
 
            re> /(*COMMIT)abc/
@@ -8152,33 +8658,32 @@
          data> xyzabc
          No match
 
-       For the first pattern, PCRE2 knows that any match must start with  "a",
-       so  the optimization skips along the subject to "a" before applying the
-       pattern to the first set of data. The match attempt then succeeds.  The
-       second  pattern disables the optimization that skips along to the first
-       character. The pattern is now applied  starting  at  "x",  and  so  the
-       (*COMMIT)  causes  the  match to fail without trying any other starting
+       For  the first pattern, PCRE2 knows that any match must start with "a",
+       so the optimization skips along the subject to "a" before applying  the
+       pattern  to the first set of data. The match attempt then succeeds. The
+       second pattern disables the optimization that skips along to the  first
+       character.  The  pattern  is  now  applied  starting at "x", and so the
+       (*COMMIT) causes the match to fail without trying  any  other  starting
        points.
 
          (*PRUNE) or (*PRUNE:NAME)
 
-       This verb causes the match to fail at the current starting position  in
+       This  verb causes the match to fail at the current starting position in
        the subject if there is a later matching failure that causes backtrack-
-       ing to reach it. If the pattern is unanchored, the  normal  "bumpalong"
-       advance  to  the next starting character then happens. Backtracking can
-       occur as usual to the left of (*PRUNE), before it is reached,  or  when
-       matching  to  the  right  of  (*PRUNE), but if there is no match to the
-       right, backtracking cannot cross (*PRUNE). In simple cases, the use  of
-       (*PRUNE)  is just an alternative to an atomic group or possessive quan-
+       ing  to  reach it. If the pattern is unanchored, the normal "bumpalong"
+       advance to the next starting character then happens.  Backtracking  can
+       occur  as  usual to the left of (*PRUNE), before it is reached, or when
+       matching to the right of (*PRUNE), but if there  is  no  match  to  the
+       right,  backtracking cannot cross (*PRUNE). In simple cases, the use of
+       (*PRUNE) is just an alternative to an atomic group or possessive  quan-
        tifier, but there are some uses of (*PRUNE) that cannot be expressed in
-       any  other  way. In an anchored pattern (*PRUNE) has the same effect as
+       any other way. In an anchored pattern (*PRUNE) has the same  effect  as
        (*COMMIT).
 
-       The   behaviour   of   (*PRUNE:NAME)   is   the   not   the   same   as
-       (*MARK:NAME)(*PRUNE).   It  is  like  (*MARK:NAME)  in that the name is
-       remembered for  passing  back  to  the  caller.  However,  (*SKIP:NAME)
-       searches  only  for  names  set  with  (*MARK),  ignoring  those set by
-       (*PRUNE) or (*THEN).
+       The behaviour of (*PRUNE:NAME) is not the same as (*MARK:NAME)(*PRUNE).
+       It is like (*MARK:NAME) in that the name is remembered for passing back
+       to  the  caller. However, (*SKIP:NAME) searches only for names set with
+       (*MARK), ignoring those set by (*PRUNE) or (*THEN).
 
          (*SKIP)
 
@@ -8311,50 +8816,55 @@
 
    Backtracking verbs in assertions
 
-       (*FAIL)  in  an assertion has its normal effect: it forces an immediate
-       backtrack.
+       (*FAIL)  in any assertion has its normal effect: it forces an immediate
+       backtrack. The behaviour of the other  backtracking  verbs  depends  on
+       whether  or  not the assertion is standalone or acting as the condition
+       in a conditional subpattern.
 
-       (*ACCEPT) in a positive assertion causes the assertion to succeed with-
-       out  any  further processing. In a negative assertion, (*ACCEPT) causes
-       the assertion to fail without any further processing.
+       (*ACCEPT) in a standalone positive assertion causes  the  assertion  to
+       succeed  without any further processing; captured strings are retained.
+       In a standalone negative assertion, (*ACCEPT) causes the  assertion  to
+       fail without any further processing; captured substrings are discarded.
 
-       The other backtracking verbs are not treated specially if  they  appear
-       in  a  positive  assertion.  In  particular,  (*THEN) skips to the next
-       alternative in the innermost enclosing  group  that  has  alternations,
-       whether or not this is within the assertion.
+       If  the  assertion is a condition, (*ACCEPT) causes the condition to be
+       true for a positive assertion and false for a  negative  one;  captured
+       substrings are retained in both cases.
 
-       Negative  assertions  are,  however, different, in order to ensure that
-       changing a positive assertion into a  negative  assertion  changes  its
-       result. Backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes a neg-
-       ative assertion to be true, without considering any further alternative
-       branches in the assertion.  Backtracking into (*THEN) causes it to skip
-       to the next enclosing alternative within the assertion (the normal  be-
-       haviour),  but  if  the  assertion  does  not have such an alternative,
-       (*THEN) behaves like (*PRUNE).
+       The  effect of (*THEN) is not allowed to escape beyond an assertion. If
+       there are no more branches to try, (*THEN) causes a positive  assertion
+       to be false, and a negative assertion to be true.
+
+       The  other  backtracking verbs are not treated specially if they appear
+       in a standalone positive assertion. In a  conditional  positive  asser-
+       tion, backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes the con-
+       dition to be false. However, for both standalone and conditional  nega-
+       tive  assertions,  backtracking  into  (*COMMIT),  (*SKIP), or (*PRUNE)
+       causes the assertion to be true, without considering any further alter-
+       native branches.
 
    Backtracking verbs in subroutines
 
-       These behaviours occur whether or not the subpattern is  called  recur-
+       These  behaviours  occur whether or not the subpattern is called recur-
        sively.  Perl's treatment of subroutines is different in some cases.
 
-       (*FAIL)  in  a subpattern called as a subroutine has its normal effect:
+       (*FAIL) in a subpattern called as a subroutine has its  normal  effect:
        it forces an immediate backtrack.
 
-       (*ACCEPT) in a subpattern called as a subroutine causes the  subroutine
-       match  to succeed without any further processing. Matching then contin-
+       (*ACCEPT)  in a subpattern called as a subroutine causes the subroutine
+       match to succeed without any further processing. Matching then  contin-
        ues after the subroutine call.
 
        (*COMMIT), (*SKIP), and (*PRUNE) in a subpattern called as a subroutine
        cause the subroutine match to fail.
 
-       (*THEN)  skips to the next alternative in the innermost enclosing group
-       within the subpattern that has alternatives. If there is no such  group
+       (*THEN) skips to the next alternative in the innermost enclosing  group
+       within  the subpattern that has alternatives. If there is no such group
        within the subpattern, (*THEN) causes the subroutine match to fail.
 
 
 SEE ALSO
 
-       pcre2api(3),    pcre2callout(3),    pcre2matching(3),   pcre2syntax(3),
+       pcre2api(3),   pcre2callout(3),    pcre2matching(3),    pcre2syntax(3),
        pcre2(3).
 
 
@@ -8367,8 +8877,8 @@
 
 REVISION
 
-       Last updated: 20 June 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 12 September 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -8389,11 +8899,12 @@
 COMPILED PATTERN MEMORY USAGE
 
        Patterns are compiled by PCRE2 into a reasonably efficient interpretive
-       code, so that most simple patterns do not  use  much  memory.  However,
-       there  is  one case where the memory usage of a compiled pattern can be
-       unexpectedly large. If a parenthesized subpattern has a quantifier with
-       a minimum greater than 1 and/or a limited maximum, the whole subpattern
-       is repeated in the compiled code. For example, the pattern
+       code, so that most simple patterns do not use much memory  for  storing
+       the compiled version. However, there is one case where the memory usage
+       of a compiled pattern can be unexpectedly  large.  If  a  parenthesized
+       subpattern has a quantifier with a minimum greater than 1 and/or a lim-
+       ited maximum, the whole subpattern is repeated in  the  compiled  code.
+       For example, the pattern
 
          (abc|def){2,4}
 
@@ -8401,134 +8912,188 @@
 
          (abc|def)(abc|def)((abc|def)(abc|def)?)?
 
-       (Technical aside: It is done this way so that backtrack  points  within
+       (Technical  aside:  It is done this way so that backtrack points within
        each of the repetitions can be independently maintained.)
 
-       For  regular expressions whose quantifiers use only small numbers, this
-       is not usually a problem. However, if the numbers are large,  and  par-
-       ticularly  if  such repetitions are nested, the memory usage can become
+       For regular expressions whose quantifiers use only small numbers,  this
+       is  not  usually a problem. However, if the numbers are large, and par-
+       ticularly if such repetitions are nested, the memory usage  can  become
        an embarrassment. For example, the very simple pattern
 
          ((ab){1,1000}c){1,3}
 
-       uses 51K bytes when compiled using the 8-bit  library.  When  PCRE2  is
-       compiled  with its default internal pointer size of two bytes, the size
-       limit on a compiled pattern is 64K code units in the 8-bit  and  16-bit
-       libraries, and this is reached with the above pattern if the outer rep-
-       etition is increased from 3 to 4. PCRE2 can be compiled to  use  larger
-       internal  pointers  and thus handle larger compiled patterns, but it is
-       better to try to rewrite your pattern to use less memory if you can.
+       uses  over  50K bytes when compiled using the 8-bit library. When PCRE2
+       is compiled with its default internal pointer size of  two  bytes,  the
+       size  limit  on  a  compiled pattern is 64K code units in the 8-bit and
+       16-bit libraries, and this is reached with the  above  pattern  if  the
+       outer repetition is increased from 3 to 4. PCRE2 can be compiled to use
+       larger internal pointers and thus handle larger compiled patterns,  but
+       it  is  better to try to rewrite your pattern to use less memory if you
+       can.
 
        One way of reducing the memory usage for such patterns is to  make  use
        of PCRE2's "subroutine" facility. Re-writing the above pattern as
 
          ((ab)(?2){0,999}c)(?1){0,2}
 
-       reduces the memory requirements to 18K, and indeed it remains under 20K
-       even with the outer repetition increased to 100. However, this  pattern
-       is  not  exactly equivalent, because the "subroutine" calls are treated
-       as atomic groups into which there can be no backtracking if there is  a
-       subsequent  matching  failure.  Therefore, PCRE2 cannot do this kind of
-       rewriting automatically.  Furthermore, there is a  noticeable  loss  of
-       speed  when executing the modified pattern. Nevertheless, if the atomic
-       grouping is not a problem and the loss of  speed  is  acceptable,  this
-       kind  of rewriting will allow you to process patterns that PCRE2 cannot
-       otherwise handle.
+       reduces  the  memory  requirements to around 16K, and indeed it remains
+       under 20K even with the outer repetition  increased  to  100.  However,
+       this kind of pattern is not always exactly equivalent, because any cap-
+       tures within subroutine calls are lost when the  subroutine  completes.
+       If  this  is  not  a  problem, this kind of rewriting will allow you to
+       process patterns that PCRE2 cannot otherwise handle. The matching  per-
+       formance  of  the two different versions of the pattern are roughly the
+       same. (This applies from release 10.30 - things were different in  ear-
+       lier releases.)
 
 
-STACK USAGE AT RUN TIME
+STACK AND HEAP USAGE AT RUN TIME
 
-       When pcre2_match() is used for matching, certain kinds of  pattern  can
-       cause  it  to  use large amounts of the process stack. In some environ-
-       ments the default process stack is quite small, and if it runs out  the
-       result  is  often  SIGSEGV.  Rewriting your pattern can often help. The
-       pcre2stack documentation discusses this issue in detail.
+       From release 10.30, the interpretive (non-JIT) version of pcre2_match()
+       uses very little system stack at run time. In earlier  releases  recur-
+       sive  function  calls  could  use a great deal of stack, and this could
+       cause problems, but this usage has been eliminated. Backtracking  posi-
+       tions  are now explicitly remembered in memory frames controlled by the
+       code. An initial 20K vector of frames is allocated on the system  stack
+       (enough for about 100 frames for small patterns), but if this is insuf-
+       ficient, heap memory is used. The amount of heap memory can be limited;
+       if  the  limit  is  set to zero, only the initial stack vector is used.
+       Rewriting patterns to be time-efficient, as described below,  may  also
+       reduce the memory requirements.
+
+       In  contrast  to  pcre2_match(),  pcre2_dfa_match()  does use recursive
+       function calls, but  only  for  processing  atomic  groups,  lookaround
+       assertions, and recursion within the pattern. Too much nested recursion
+       may cause stack issues. The "match depth"  parameter  can  be  used  to
+       limit the depth of function recursion in pcre2_dfa_match().
 
 
 PROCESSING TIME
 
-       Certain items in regular expression patterns are processed  more  effi-
+       Certain  items  in regular expression patterns are processed more effi-
        ciently than others. It is more efficient to use a character class like
-       [aeiou]  than  a  set  of   single-character   alternatives   such   as
-       (a|e|i|o|u).  In  general,  the simplest construction that provides the
+       [aeiou]   than   a   set   of  single-character  alternatives  such  as
+       (a|e|i|o|u). In general, the simplest construction  that  provides  the
        required behaviour is usually the most efficient. Jeffrey Friedl's book
-       contains  a  lot  of useful general discussion about optimizing regular
-       expressions for efficient performance. This  document  contains  a  few
+       contains a lot of useful general discussion  about  optimizing  regular
+       expressions  for  efficient  performance.  This document contains a few
        observations about PCRE2.
 
-       Using  Unicode  character  properties  (the  \p, \P, and \X escapes) is
-       slow, because PCRE2 has to use a multi-stage table lookup  whenever  it
-       needs  a  character's  property. If you can find an alternative pattern
+       Using Unicode character properties (the \p,  \P,  and  \X  escapes)  is
+       slow,  because  PCRE2 has to use a multi-stage table lookup whenever it
+       needs a character's property. If you can find  an  alternative  pattern
        that does not use character properties, it will probably be faster.
 
-       By default, the escape sequences \b, \d, \s,  and  \w,  and  the  POSIX
-       character  classes  such  as  [:alpha:]  do not use Unicode properties,
+       By  default,  the  escape  sequences  \b, \d, \s, and \w, and the POSIX
+       character classes such as [:alpha:]  do  not  use  Unicode  properties,
        partly for backwards compatibility, and partly for performance reasons.
-       However,  you  can  set  the PCRE2_UCP option or start the pattern with
-       (*UCP) if you want Unicode character properties to be  used.  This  can
-       double  the  matching  time  for  items  such  as \d, when matched with
-       pcre2_match(); the performance loss is less with a DFA  matching  func-
+       However, you can set the PCRE2_UCP option or  start  the  pattern  with
+       (*UCP)  if  you  want Unicode character properties to be used. This can
+       double the matching time for  items  such  as  \d,  when  matched  with
+       pcre2_match();  the  performance loss is less with a DFA matching func-
        tion, and in both cases there is not much difference for \b.
 
-       When  a pattern begins with .* not in atomic parentheses, nor in paren-
-       theses that are the subject of a backreference,  and  the  PCRE2_DOTALL
-       option  is  set,  the pattern is implicitly anchored by PCRE2, since it
-       can match only at the start of a subject string.  If  the  pattern  has
+       When a pattern begins with .* not in atomic parentheses, nor in  paren-
+       theses  that  are  the subject of a backreference, and the PCRE2_DOTALL
+       option is set, the pattern is implicitly anchored by  PCRE2,  since  it
+       can  match  only  at  the start of a subject string. If the pattern has
        multiple top-level branches, they must all be anchorable. The optimiza-
-       tion can be disabled by  the  PCRE2_NO_DOTSTAR_ANCHOR  option,  and  is
+       tion  can  be  disabled  by  the PCRE2_NO_DOTSTAR_ANCHOR option, and is
        automatically disabled if the pattern contains (*PRUNE) or (*SKIP).
 
-       If  PCRE2_DOTALL  is  not  set,  PCRE2  cannot  make this optimization,
+       If PCRE2_DOTALL is  not  set,  PCRE2  cannot  make  this  optimization,
        because the dot metacharacter does not then match a newline, and if the
-       subject  string contains newlines, the pattern may match from the char-
+       subject string contains newlines, the pattern may match from the  char-
        acter immediately following one of them instead of from the very start.
        For example, the pattern
 
          .*second
 
-       matches  the subject "first\nand second" (where \n stands for a newline
-       character), with the match starting at the seventh character. In  order
-       to  do  this, PCRE2 has to retry the match starting after every newline
+       matches the subject "first\nand second" (where \n stands for a  newline
+       character),  with the match starting at the seventh character. In order
+       to do this, PCRE2 has to retry the match starting after  every  newline
        in the subject.
 
-       If you are using such a pattern with subject strings that do  not  con-
-       tain   newlines,   the   best   performance   is  obtained  by  setting
-       PCRE2_DOTALL, or starting the pattern with  ^.*  or  ^.*?  to  indicate
+       If  you  are using such a pattern with subject strings that do not con-
+       tain  newlines,  the  best   performance   is   obtained   by   setting
+       PCRE2_DOTALL,  or  starting  the  pattern  with ^.* or ^.*? to indicate
        explicit anchoring. That saves PCRE2 from having to scan along the sub-
        ject looking for a newline to restart at.
 
-       Beware of patterns that contain nested indefinite  repeats.  These  can
-       take  a  long time to run when applied to a string that does not match.
+       Beware  of  patterns  that contain nested indefinite repeats. These can
+       take a long time to run when applied to a string that does  not  match.
        Consider the pattern fragment
 
          ^(a+)*
 
-       This can match "aaaa" in 16 different ways, and this  number  increases
-       very  rapidly  as the string gets longer. (The * repeat can match 0, 1,
-       2, 3, or 4 times, and for each of those cases other than 0 or 4, the  +
-       repeats  can  match  different numbers of times.) When the remainder of
-       the pattern is such that the entire match is going to fail,  PCRE2  has
-       in  principle  to  try  every  possible variation, and this can take an
+       This  can  match "aaaa" in 16 different ways, and this number increases
+       very rapidly as the string gets longer. (The * repeat can match  0,  1,
+       2,  3, or 4 times, and for each of those cases other than 0 or 4, the +
+       repeats can match different numbers of times.) When  the  remainder  of
+       the  pattern  is such that the entire match is going to fail, PCRE2 has
+       in principle to try every possible variation,  and  this  can  take  an
        extremely long time, even for relatively short strings.
 
        An optimization catches some of the more simple cases such as
 
          (a+)*b
 
-       where a literal character follows. Before  embarking  on  the  standard
-       matching  procedure, PCRE2 checks that there is a "b" later in the sub-
-       ject string, and if there is not, it fails the match immediately.  How-
-       ever,  when  there  is no following literal this optimization cannot be
+       where  a  literal  character  follows. Before embarking on the standard
+       matching procedure, PCRE2 checks that there is a "b" later in the  sub-
+       ject  string, and if there is not, it fails the match immediately. How-
+       ever, when there is no following literal this  optimization  cannot  be
        used. You can see the difference by comparing the behaviour of
 
          (a+)*\d
 
-       with the pattern above. The former gives  a  failure  almost  instantly
-       when  applied  to  a  whole  line of "a" characters, whereas the latter
+       with  the  pattern  above.  The former gives a failure almost instantly
+       when applied to a whole line of  "a"  characters,  whereas  the  latter
        takes an appreciable time with strings longer than about 20 characters.
 
        In many cases, the solution to this kind of performance issue is to use
-       an atomic group or a possessive quantifier.
+       an atomic group or a possessive quantifier. This can often reduce  mem-
+       ory requirements as well. As another example, consider this pattern:
+
+         ([^<]|<(?!inet))+
+
+       It  matches  from wherever it starts until it encounters "<inet" or the
+       end of the data, and is the kind of pattern that  might  be  used  when
+       processing an XML file. Each iteration of the outer parentheses matches
+       either one character that is not "<" or a "<" that is not  followed  by
+       "inet".  However,  each time a parenthesis is processed, a backtracking
+       position is passed, so this formulation uses a memory  frame  for  each
+       matched character. For a long string, a lot of memory is required. Con-
+       sider now this  rewritten  pattern,  which  matches  exactly  the  same
+       strings:
+
+         ([^<]++|<(?!inet))+
+
+       This runs much faster, because sequences of characters that do not con-
+       tain "<" are "swallowed" in one item inside the parentheses, and a pos-
+       sessive  quantifier  is  used to stop any backtracking into the runs of
+       non-"<" characters. This version also uses a lot  less  memory  because
+       entry  to  a  new  set of parentheses happens only when a "<" character
+       that is not followed by "inet" is encountered (and we  assume  this  is
+       relatively rare).
+
+       This example shows that one way of optimizing performance when matching
+       long subject strings is to write repeated parenthesized subpatterns  to
+       match more than one character whenever possible.
+
+   SETTING RESOURCE LIMITS
+
+       You  can  set  limits on the amount of processing that takes place when
+       matching, and on the amount of heap memory that is  used.  The  default
+       values of the limits are very large, and unlikely ever to operate. They
+       can be changed when PCRE2 is built, and  they  can  also  be  set  when
+       pcre2_match()  or  pcre2_dfa_match()  is  called.  For details of these
+       interfaces, see the pcre2build documentation and the  section  entitled
+       "The match context" in the pcre2api documentation.
+
+       The  pcre2test  test program has a modifier called "find_limits" which,
+       if applied to a subject line, causes it to  find  the  smallest  limits
+       that allow a pattern to match. This is done by repeatedly matching with
+       different limits.
 
 
 AUTHOR
@@ -8540,8 +9105,8 @@
 
 REVISION
 
-       Last updated: 02 January 2015
-       Copyright (c) 1997-2015 University of Cambridge.
+       Last updated: 08 April 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -8593,32 +9158,34 @@
 
        There are also some options that are not defined by POSIX.  These  have
        been  added  at  the  request  of users who want to make use of certain
-       PCRE2-specific features via the POSIX calling interface.
+       PCRE2-specific features via the POSIX calling interface or to  add  BSD
+       or GNU functionality.
 
-       When PCRE2 is called via these functions, it is only the  API  that  is
-       POSIX-like  in  style.  The syntax and semantics of the regular expres-
-       sions themselves are still those of Perl, subject  to  the  setting  of
-       various  PCRE2 options, as described below. "POSIX-like in style" means
-       that the API approximates to the POSIX  definition;  it  is  not  fully
-       POSIX-compatible,  and  in  multi-unit  encoding domains it is probably
+       When  PCRE2  is  called via these functions, it is only the API that is
+       POSIX-like in style. The syntax and semantics of  the  regular  expres-
+       sions  themselves  are  still  those of Perl, subject to the setting of
+       various PCRE2 options, as described below. "POSIX-like in style"  means
+       that  the  API  approximates  to  the POSIX definition; it is not fully
+       POSIX-compatible, and in multi-unit encoding  domains  it  is  probably
        even less compatible.
 
        The header for these functions is supplied as pcre2posix.h to avoid any
-       potential  clash  with  other  POSIX  libraries.  It can, of course, be
+       potential clash with other POSIX  libraries.  It  can,  of  course,  be
        renamed or aliased as regex.h, which is the "correct" name. It provides
-       two  structure  types,  regex_t  for  compiled internal forms, and reg-
-       match_t for returning captured substrings. It also  defines  some  con-
-       stants  whose  names  start  with  "REG_";  these  are used for setting
+       two structure types, regex_t for  compiled  internal  forms,  and  reg-
+       match_t  for  returning  captured substrings. It also defines some con-
+       stants whose names start  with  "REG_";  these  are  used  for  setting
        options and identifying error codes.
 
 
 COMPILING A PATTERN
 
-       The function regcomp() is called to compile a pattern into an  internal
-       form.  The  pattern  is  a C string terminated by a binary zero, and is
-       passed in the argument pattern. The preg argument is  a  pointer  to  a
-       regex_t  structure that is used as a base for storing information about
-       the compiled regular expression.
+       The  function regcomp() is called to compile a pattern into an internal
+       form. By default, the pattern is a C string terminated by a binary zero
+       (but  see  REG_PEND below). The preg argument is a pointer to a regex_t
+       structure that is used as a base for storing information about the com-
+       piled  regular  expression. (It is also used for input when REG_PEND is
+       set.)
 
        The argument cflags is either zero, or contains one or more of the bits
        defined by the following macros:
@@ -8641,14 +9208,34 @@
        the defined POSIX behaviour for REG_NEWLINE  (see  the  following  sec-
        tion).
 
+         REG_NOSPEC
+
+       The  PCRE2_LITERAL  option is set when the regular expression is passed
+       for compilation to the native function. This disables all meta  charac-
+       ters  in the pattern, causing it to be treated as a literal string. The
+       only other options that are  allowed  with  REG_NOSPEC  are  REG_ICASE,
+       REG_NOSUB,  REG_PEND,  and REG_UTF. Note that REG_NOSPEC is not part of
+       the POSIX standard.
+
          REG_NOSUB
 
-       When  a  pattern that is compiled with this flag is passed to regexec()
-       for matching, the nmatch and pmatch arguments are ignored, and no  cap-
+       When a pattern that is compiled with this flag is passed  to  regexec()
+       for  matching, the nmatch and pmatch arguments are ignored, and no cap-
        tured strings are returned. Versions of the PCRE library prior to 10.22
-       used to set the  PCRE2_NO_AUTO_CAPTURE  compile  option,  but  this  no
+       used  to  set  the  PCRE2_NO_AUTO_CAPTURE  compile  option, but this no
        longer happens because it disables the use of back references.
 
+         REG_PEND
+
+       If this option is set, the reg_endp field in the preg structure  (which
+       has the type const char *) must be set to point to the character beyond
+       the end of the pattern before calling regcomp(). The pattern itself may
+       now  contain binary zeroes, which are treated as data characters. With-
+       out REG_PEND, a binary zero terminates  the  pattern  and  the  re_endp
+       field  is  ignored.  This  is a GNU extension to the POSIX standard and
+       should be used with caution in software  intended  to  be  portable  to
+       other systems.
+
          REG_UCP
 
        The  PCRE2_UCP  option is set when the regular expression is passed for
@@ -8678,11 +9265,12 @@
        ter (they are not) or by a negative class such as [^a] (they are).
 
        The  yield of regcomp() is zero on success, and non-zero otherwise. The
-       preg structure is filled in on success, and one member of the structure
-       is  public: re_nsub contains the number of capturing subpatterns in the
-       regular expression. Various error codes are defined in the header file.
+       preg structure is filled in on success, and one  other  member  of  the
+       structure  (as  well as re_endp) is public: re_nsub contains the number
+       of capturing subpatterns in the regular expression. Various error codes
+       are defined in the header file.
 
-       NOTE: If the yield of regcomp() is non-zero, you must  not  attempt  to
+       NOTE:  If  the  yield of regcomp() is non-zero, you must not attempt to
        use the contents of the preg structure. If, for example, you pass it to
        regexec(), the result is undefined and your program is likely to crash.
 
@@ -8690,9 +9278,9 @@
 MATCHING NEWLINE CHARACTERS
 
        This area is not simple, because POSIX and Perl take different views of
-       things.   It  is not possible to get PCRE2 to obey POSIX semantics, but
+       things.  It is not possible to get PCRE2 to obey POSIX  semantics,  but
        then PCRE2 was never intended to be a POSIX engine. The following table
-       lists  the  different  possibilities for matching newline characters in
+       lists the different possibilities for matching  newline  characters  in
        Perl and PCRE2:
 
                                  Default   Change with
@@ -8713,25 +9301,25 @@
          $ matches \n in middle     no     REG_NEWLINE
          ^ matches \n in middle     no     REG_NEWLINE
 
-       This behaviour is not what happens when PCRE2 is called via  its  POSIX
-       API.  By  default, PCRE2's behaviour is the same as Perl's, except that
-       there is no equivalent for PCRE2_DOLLAR_ENDONLY in Perl. In both  PCRE2
+       This  behaviour  is not what happens when PCRE2 is called via its POSIX
+       API. By default, PCRE2's behaviour is the same as Perl's,  except  that
+       there  is no equivalent for PCRE2_DOLLAR_ENDONLY in Perl. In both PCRE2
        and Perl, there is no way to stop newline from matching [^a].
 
-       Default  POSIX newline handling can be obtained by setting PCRE2_DOTALL
-       and PCRE2_DOLLAR_ENDONLY when  calling  pcre2_compile()  directly,  but
-       there  is  no  way  to make PCRE2 behave exactly as for the REG_NEWLINE
-       action. When using the POSIX API, passing REG_NEWLINE to  PCRE2's  reg-
+       Default POSIX newline handling can be obtained by setting  PCRE2_DOTALL
+       and  PCRE2_DOLLAR_ENDONLY  when  calling  pcre2_compile() directly, but
+       there is no way to make PCRE2 behave exactly  as  for  the  REG_NEWLINE
+       action.  When  using the POSIX API, passing REG_NEWLINE to PCRE2's reg-
        comp() function causes PCRE2_MULTILINE to be passed to pcre2_compile(),
-       and REG_DOTALL passes PCRE2_DOTALL. There is no way to pass  PCRE2_DOL-
+       and  REG_DOTALL passes PCRE2_DOTALL. There is no way to pass PCRE2_DOL-
        LAR_ENDONLY.
 
 
 MATCHING A PATTERN
 
-       The  function  regexec()  is  called  to  match a compiled pattern preg
-       against a given string, which is by default terminated by a  zero  byte
-       (but  see  REG_STARTEND below), subject to the options in eflags. These
+       The function regexec() is called  to  match  a  compiled  pattern  preg
+       against  a  given string, which is by default terminated by a zero byte
+       (but see REG_STARTEND below), subject to the options in  eflags.  These
        can be:
 
          REG_NOTBOL
@@ -8741,9 +9329,9 @@
 
          REG_NOTEMPTY
 
-       The  PCRE2_NOTEMPTY  option  is  set  when calling the underlying PCRE2
-       matching function. Note that REG_NOTEMPTY is  not  part  of  the  POSIX
-       standard.  However, setting this option can give more POSIX-like behav-
+       The PCRE2_NOTEMPTY option is set  when  calling  the  underlying  PCRE2
+       matching  function.  Note  that  REG_NOTEMPTY  is not part of the POSIX
+       standard. However, setting this option can give more POSIX-like  behav-
        iour in some situations.
 
          REG_NOTEOL
@@ -8753,15 +9341,24 @@
 
          REG_STARTEND
 
-       The  string  is  considered to start at string + pmatch[0].rm_so and to
-       have a terminating NUL located at string + pmatch[0].rm_eo (there  need
-       not  actually  be  a  NUL at that location), regardless of the value of
-       nmatch. This is a BSD extension, compatible with but not  specified  by
-       IEEE  Standard  1003.2  (POSIX.2),  and  should be used with caution in
-       software intended to be portable to other systems. Note that a non-zero
-       rm_so does not imply REG_NOTBOL; REG_STARTEND affects only the location
-       of the string, not how it is matched. Setting REG_STARTEND and  passing
-       pmatch  as  NULL  are  mutually  exclusive;  the  error  REG_INVARG  is
+       When this option is set, the subject  string  is  starts  at  string  +
+       pmatch[0].rm_so  and  ends  at  string  + pmatch[0].rm_eo, which should
+       point to the first character beyond the string.  There  may  be  binary
+       zeroes within the subject string, and indeed, using REG_STARTEND is the
+       only way to pass a subject string that contains a binary zero.
+
+       Whatever the value of  pmatch[0].rm_so,  the  offsets  of  the  matched
+       string  and  any  captured  substrings  are still given relative to the
+       start of string itself. (Before PCRE2 release 10.30  these  were  given
+       relative  to  string  +  pmatch[0].rm_so,  but  this differs from other
+       implementations.)
+
+       This is a BSD extension, compatible with  but  not  specified  by  IEEE
+       Standard  1003.2 (POSIX.2), and should be used with caution in software
+       intended to be portable to other systems. Note that  a  non-zero  rm_so
+       does  not  imply REG_NOTBOL; REG_STARTEND affects only the location and
+       length of the string, not how it is matched. Setting  REG_STARTEND  and
+       passing  pmatch as NULL are mutually exclusive; the error REG_INVARG is
        returned.
 
        If the pattern was compiled with the REG_NOSUB flag, no data about  any
@@ -8816,8 +9413,8 @@
 
 REVISION
 
-       Last updated: 31 January 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 15 June 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -8949,26 +9546,29 @@
        use within individual applications.  As  such,  the  data  supplied  to
        pcre2_serialize_decode()  is expected to be trusted data, not data from
        arbitrary external sources.  There  is  only  some  simple  consistency
-       checking, not complete validation of what is being re-loaded.
+       checking, not complete validation of what is being re-loaded. Corrupted
+       data may cause undefined results. For example, if the length field of a
+       pattern in the serialized data is corrupted, the deserializing code may
+       read beyond the end of the byte stream that is passed to it.
 
 
 SAVING COMPILED PATTERNS
 
        Before compiled patterns can be saved they must be serialized, that is,
-       converted to a stream of bytes. A single byte stream  may  contain  any
-       number  of  compiled patterns, but they must all use the same character
+       converted  to  a  stream of bytes. A single byte stream may contain any
+       number of compiled patterns, but they must all use the  same  character
        tables. A single copy of the tables is included in the byte stream (its
        size is 1088 bytes). For more details of character tables, see the sec-
        tion on locale support in the pcre2api documentation.
 
-       The function pcre2_serialize_encode() creates a serialized byte  stream
-       from  a  list of compiled patterns. Its first two arguments specify the
+       The  function pcre2_serialize_encode() creates a serialized byte stream
+       from a list of compiled patterns. Its first two arguments  specify  the
        list, being a pointer to a vector of pointers to compiled patterns, and
        the length of the vector. The third and fourth arguments point to vari-
        ables which are set to point to the created byte stream and its length,
-       respectively.  The  final  argument  is a pointer to a general context,
-       which can be used to specify custom memory  mangagement  functions.  If
-       this  argument  is NULL, malloc() is used to obtain memory for the byte
+       respectively. The final argument is a pointer  to  a  general  context,
+       which  can  be  used to specify custom memory mangagement functions. If
+       this argument is NULL, malloc() is used to obtain memory for  the  byte
        stream. The yield of the function is the number of serialized patterns,
        or one of the following negative error codes:
 
@@ -8978,12 +9578,12 @@
          PCRE2_ERROR_MIXEDTABLES  the patterns do not all use the same tables
          PCRE2_ERROR_NULL         the 1st, 3rd, or 4th argument is NULL
 
-       PCRE2_ERROR_BADMAGIC  means  either that a pattern's code has been cor-
-       rupted, or that a slot in the vector does not point to a compiled  pat-
+       PCRE2_ERROR_BADMAGIC means either that a pattern's code has  been  cor-
+       rupted,  or that a slot in the vector does not point to a compiled pat-
        tern.
 
        Once a set of patterns has been serialized you can save the data in any
-       appropriate manner. Here is sample code that compiles two patterns  and
+       appropriate  manner. Here is sample code that compiles two patterns and
        writes them to a file. It assumes that the variable fd refers to a file
        that is open for output. The error checking that should be present in a
        real application has been omitted for simplicity.
@@ -9001,13 +9601,13 @@
            &bytescount, NULL);
          errorcode = fwrite(bytes, 1, bytescount, fd);
 
-       Note  that  the  serialized data is binary data that may contain any of
-       the 256 possible byte  values.  On  systems  that  make  a  distinction
+       Note that the serialized data is binary data that may  contain  any  of
+       the  256  possible  byte  values.  On  systems  that make a distinction
        between binary and non-binary data, be sure that the file is opened for
        binary output.
 
-       Serializing a set of patterns leaves the original  data  untouched,  so
-       they  can  still  be used for matching. Their memory must eventually be
+       Serializing  a  set  of patterns leaves the original data untouched, so
+       they can still be used for matching. Their memory  must  eventually  be
        freed in the usual way by calling pcre2_code_free(). When you have fin-
        ished with the byte stream, it too must be freed by calling pcre2_seri-
        alize_free().
@@ -9015,11 +9615,11 @@
 
 RE-USING PRECOMPILED PATTERNS
 
-       In order to re-use a set of saved patterns  you  must  first  make  the
-       serialized  byte stream available in main memory (for example, by read-
-       ing from a file). The management of this memory  block  is  up  to  the
+       In  order  to  re-use  a  set of saved patterns you must first make the
+       serialized byte stream available in main memory (for example, by  read-
+       ing  from  a  file).  The  management of this memory block is up to the
        application.  You  can  use  the  pcre2_serialize_get_number_of_codes()
-       function to find out how many compiled patterns are in  the  serialized
+       function  to  find out how many compiled patterns are in the serialized
        data without actually decoding the patterns:
 
          uint8_t *bytes = <serialized data>;
@@ -9027,10 +9627,10 @@
 
        The pcre2_serialize_decode() function reads a byte stream and recreates
        the compiled patterns in new memory blocks, setting pointers to them in
-       a  vector.  The  first two arguments are a pointer to a suitable vector
-       and its length, and the third argument points to  a  byte  stream.  The
-       final  argument is a pointer to a general context, which can be used to
-       specify custom memory mangagement functions for the  decoded  patterns.
+       a vector. The first two arguments are a pointer to  a  suitable  vector
+       and  its  length,  and  the third argument points to a byte stream. The
+       final argument is a pointer to a general context, which can be used  to
+       specify  custom  memory mangagement functions for the decoded patterns.
        If this argument is NULL, malloc() and free() are used. After deserial-
        ization, the byte stream is no longer needed and can be discarded.
 
@@ -9040,9 +9640,9 @@
          int32_t number_of_codes =
            pcre2_serialize_decode(list_of_codes, 2, bytes, NULL);
 
-       If the vector is not large enough for all  the  patterns  in  the  byte
-       stream,  it  is  filled  with  those  that  fit,  and the remainder are
-       ignored. The yield of the function is the number of  decoded  patterns,
+       If  the  vector  is  not  large enough for all the patterns in the byte
+       stream, it is filled  with  those  that  fit,  and  the  remainder  are
+       ignored.  The  yield of the function is the number of decoded patterns,
        or one of the following negative error codes:
 
          PCRE2_ERROR_BADDATA    second argument is zero or less
@@ -9052,24 +9652,24 @@
          PCRE2_ERROR_MEMORY     memory allocation failed
          PCRE2_ERROR_NULL       first or third argument is NULL
 
-       PCRE2_ERROR_BADMAGIC  may mean that the data is corrupt, or that it was
+       PCRE2_ERROR_BADMAGIC may mean that the data is corrupt, or that it  was
        compiled on a system with different endianness.
 
        Decoded patterns can be used for matching in the usual way, and must be
-       freed  by  calling pcre2_code_free(). However, be aware that there is a
-       potential race issue if you  are  using  multiple  patterns  that  were
-       decoded  from  a  single  byte stream in a multithreaded application. A
+       freed by calling pcre2_code_free(). However, be aware that there  is  a
+       potential  race  issue  if  you  are  using multiple patterns that were
+       decoded from a single byte stream in  a  multithreaded  application.  A
        single copy of the character tables is used by all the decoded patterns
        and a reference count is used to arrange for its memory to be automati-
-       cally freed when the last pattern is freed, but there is no locking  on
-       this  reference count. Therefore, if you want to call pcre2_code_free()
-       for these patterns in different threads,  you  must  arrange  your  own
-       locking,  and  ensure  that  pcre2_code_free()  cannot be called by two
+       cally  freed when the last pattern is freed, but there is no locking on
+       this reference count. Therefore, if you want to call  pcre2_code_free()
+       for  these  patterns  in  different  threads, you must arrange your own
+       locking, and ensure that pcre2_code_free()  cannot  be  called  by  two
        threads at the same time.
 
-       If a pattern was processed by pcre2_jit_compile() before being  serial-
-       ized,  the  JIT data is discarded and so is no longer available after a
-       save/restore cycle. You can, however, process a restored  pattern  with
+       If  a pattern was processed by pcre2_jit_compile() before being serial-
+       ized, the JIT data is discarded and so is no longer available  after  a
+       save/restore  cycle.  You can, however, process a restored pattern with
        pcre2_jit_compile() if you wish.
 
 
@@ -9082,174 +9682,8 @@
 
 REVISION
 
-       Last updated: 24 May 2016
-       Copyright (c) 1997-2016 University of Cambridge.
-------------------------------------------------------------------------------
-
-
-PCRE2STACK(3)              Library Functions Manual              PCRE2STACK(3)
-
-
-
-NAME
-       PCRE2 - Perl-compatible regular expressions (revised API)
-
-PCRE2 DISCUSSION OF STACK USAGE
-
-       When  you  call  pcre2_match(),  it  makes  use of an internal function
-       called match(). This calls itself recursively at branch points  in  the
-       pattern,  in  order  to  remember the state of the match so that it can
-       back up and try a different alternative after a  failure.  As  matching
-       proceeds  deeper  and deeper into the tree of possibilities, the recur-
-       sion depth increases. The match() function is also called in other cir-
-       cumstances,  for  example,  whenever  a  parenthesized  sub-pattern  is
-       entered, and in certain cases of repetition.
-
-       Not all calls of match() increase the recursion depth; for an item such
-       as  a* it may be called several times at the same level, after matching
-       different numbers of a's. Furthermore, in a number of cases  where  the
-       result  of  the  recursive call would immediately be passed back as the
-       result of the current call (a "tail recursion"), the function  is  just
-       restarted instead.
-
-       Each  time the internal match() function is called recursively, it uses
-       memory from the process stack. For certain kinds of pattern  and  data,
-       very  large  amounts of stack may be needed, despite the recognition of
-       "tail recursion". Note that if  PCRE2  is  compiled  with  the  -fsani-
-       tize=address  option  of  the  GCC compiler, the stack requirements are
-       greatly increased.
-
-       The above comments apply when pcre2_match() is run in its normal inter-
-       pretive manner. If the compiled pattern was processed by pcre2_jit_com-
-       pile(), and just-in-time compiling  was  successful,  and  the  options
-       passed  to  pcre2_match()  were  not incompatible, the matching process
-       uses the JIT-compiled code instead of the  match()  function.  In  this
-       case, the memory requirements are handled entirely differently. See the
-       pcre2jit documentation for details.
-
-       The  pcre2_dfa_match()  function  operates  in  a  different   way   to
-       pcre2_match(),  and uses recursion only when there is a regular expres-
-       sion recursion or subroutine call in the  pattern.  This  includes  the
-       processing  of assertion and "once-only" subpatterns, which are handled
-       like subroutine calls.  Normally, these are never very  deep,  and  the
-       limit  on  the  complexity  of  pcre2_dfa_match()  is controlled by the
-       amount of workspace it is given.  However, it is possible to write pat-
-       terns  with  runaway  infinite  recursions;  such  patterns  will cause
-       pcre2_dfa_match() to run out of stack. At present, there is no  protec-
-       tion against this.
-
-       The  comments  that  follow do NOT apply to pcre2_dfa_match(); they are
-       relevant only for pcre2_match() without the JIT optimization.
-
-   Reducing pcre2_match()'s stack usage
-
-       You can often reduce the amount of recursion, and therefore the  amount
-       of  stack  used,  by  modifying the pattern that is being matched. Con-
-       sider, for example, this pattern:
-
-         ([^<]|<(?!inet))+
-
-       It matches from wherever it starts until it encounters "<inet"  or  the
-       end  of  the  data,  and is the kind of pattern that might be used when
-       processing an XML file. Each iteration of the outer parentheses matches
-       either  one  character that is not "<" or a "<" that is not followed by
-       "inet". However, each time a  parenthesis  is  processed,  a  recursion
-       occurs, so this formulation uses a stack frame for each matched charac-
-       ter. For a long string, a lot of stack is required. Consider  now  this
-       rewritten pattern, which matches exactly the same strings:
-
-         ([^<]++|<(?!inet))+
-
-       This  uses very much less stack, because runs of characters that do not
-       contain "<" are "swallowed" in one item inside the parentheses.  Recur-
-       sion  happens  only when a "<" character that is not followed by "inet"
-       is encountered (and we assume this is relatively  rare).  A  possessive
-       quantifier  is  used  to stop any backtracking into the runs of non-"<"
-       characters, but that is not related to stack usage.
-
-       This example shows that one way of avoiding stack problems when  match-
-       ing long subject strings is to write repeated parenthesized subpatterns
-       to match more than one character whenever possible.
-
-   Compiling PCRE2 to use heap instead of stack for pcre2_match()
-
-       In environments where stack memory is constrained, you  might  want  to
-       compile PCRE2 to use heap memory instead of stack for remembering back-
-       up points when pcre2_match() is running. This makes it run more slowly,
-       however. Details of how to do this are given in the pcre2build documen-
-       tation. When built in this way, instead of using the stack, PCRE2  gets
-       memory  for  remembering  backup  points from the heap. By default, the
-       memory is obtained by calling the system malloc() function, but you can
-       arrange to supply your own memory management function. For details, see
-       the section entitled "The match context" in the pcre2api documentation.
-       Since the block sizes are always the same, it may be possible to imple-
-       ment customized a memory handler that is more efficient than the  stan-
-       dard function. The memory blocks obtained for this purpose are retained
-       and re-used if possible while pcre2_match() is running.  They  are  all
-       freed just before it exits.
-
-   Limiting pcre2_match()'s stack usage
-
-       You can set limits on the number of times the internal match() function
-       is called, both in total and  recursively.  If  a  limit  is  exceeded,
-       pcre2_match()  returns  an  error  code. Setting suitable limits should
-       prevent it from running out of stack. The default values of the  limits
-       are  very large, and unlikely ever to operate. They can be changed when
-       PCRE2 is built, and they can also be set when pcre2_match() is  called.
-       For  details  of these interfaces, see the pcre2build documentation and
-       the section entitled "The match context" in the pcre2api documentation.
-
-       As a very rough rule of thumb, you should reckon on about 500 bytes per
-       recursion.  Thus,  if  you  want  to limit your stack usage to 8Mb, you
-       should set the limit at 16000 recursions. A 64Mb stack,  on  the  other
-       hand, can support around 128000 recursions.
-
-       The  pcre2test  test program has a modifier called "find_limits" which,
-       if applied to a subject line, causes it to  find  the  smallest  limits
-       that  allow a a pattern to match. This is done by calling pcre2_match()
-       repeatedly with different limits.
-
-   Changing stack size in Unix-like systems
-
-       In Unix-like environments, there is not often a problem with the  stack
-       unless  very  long  strings  are  involved, though the default limit on
-       stack size varies from system to system. Values from 8Mb  to  64Mb  are
-       common. You can find your default limit by running the command:
-
-         ulimit -s
-
-       Unfortunately,  the  effect  of  running out of stack is often SIGSEGV,
-       though sometimes a more explicit error message is given. You  can  nor-
-       mally increase the limit on stack size by code such as this:
-
-         struct rlimit rlim;
-         getrlimit(RLIMIT_STACK, &rlim);
-         rlim.rlim_cur = 100*1024*1024;
-         setrlimit(RLIMIT_STACK, &rlim);
-
-       This  reads  the current limits (soft and hard) using getrlimit(), then
-       attempts to increase the soft limit to  100Mb  using  setrlimit().  You
-       must do this before calling pcre2_match().
-
-   Changing stack size in Mac OS X
-
-       Using setrlimit(), as described above, should also work on Mac OS X. It
-       is also possible to set a stack size when linking a program. There is a
-       discussion   about   stack  sizes  in  Mac  OS  X  at  this  web  site:
-       http://developer.apple.com/qa/qa2005/qa1419.html.
-
-
-AUTHOR
-
-       Philip Hazel
-       University Computing Service
-       Cambridge, England.
-
-
-REVISION
-
-       Last updated: 21 November 2014
-       Copyright (c) 1997-2014 University of Cambridge.
+       Last updated: 21 March 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -9526,18 +9960,21 @@
          (?i)            caseless
          (?J)            allow duplicate names
          (?m)            multiline
+         (?n)            no auto capture
          (?s)            single line (dotall)
          (?U)            default ungreedy (lazy)
-         (?x)            extended (ignore white space)
+         (?x)            extended: ignore white space except in classes
+         (?xx)           as (?x) but also ignore space and tab in classes
          (?-...)         unset option(s)
 
        The following are recognized only at the very start  of  a  pattern  or
        after  one  of the newline or \R options with similar syntax. More than
-       one of them may appear.
+       one of them may appear. For the first three, d is a decimal number.
 
-         (*LIMIT_MATCH=d) set the match limit to d (decimal number)
-         (*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
-         (*NOTEMPTY)     set PCRE2_NOTEMPTY when matching
+         (*LIMIT_DEPTH=d) set the backtracking limit to d
+         (*LIMIT_HEAP=d)  set the heap size limit to d kilobytes
+         (*LIMIT_MATCH=d) set the match limit to d
+         (*NOTEMPTY)      set PCRE2_NOTEMPTY when matching
          (*NOTEMPTY_ATSTART) set PCRE2_NOTEMPTY_ATSTART when matching
          (*NO_AUTO_POSSESS) no auto-possessification (PCRE2_NO_AUTO_POSSESS)
          (*NO_DOTSTAR_ANCHOR) no .* anchoring (PCRE2_NO_DOTSTAR_ANCHOR)
@@ -9546,16 +9983,17 @@
          (*UTF)          set appropriate UTF mode for the library in use
          (*UCP)          set PCRE2_UCP (use Unicode properties for \d etc)
 
-       Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value  of
-       the  limits  set by the caller of pcre2_match(), not increase them. The
-       application can lock out the use of (*UTF) and (*UCP)  by  setting  the
-       PCRE2_NEVER_UTF  or  PCRE2_NEVER_UCP  options, respectively, at compile
-       time.
+       Note that LIMIT_DEPTH, LIMIT_HEAP, and LIMIT_MATCH can only reduce  the
+       value   of   the   limits   set  by  the  caller  of  pcre2_match()  or
+       pcre2_dfa_match(), not increase them. LIMIT_RECURSION  is  an  obsolete
+       synonym for LIMIT_DEPTH. The application can lock out the use of (*UTF)
+       and (*UCP) by setting the PCRE2_NEVER_UTF or  PCRE2_NEVER_UCP  options,
+       respectively, at compile time.
 
 
 NEWLINE CONVENTION
 
-       These are recognized only at the very start of  the  pattern  or  after
+       These  are  recognized  only  at the very start of the pattern or after
        option settings with a similar syntax.
 
          (*CR)           carriage return only
@@ -9563,11 +10001,12 @@
          (*CRLF)         carriage return followed by linefeed
          (*ANYCRLF)      all three of the above
          (*ANY)          any Unicode newline sequence
+         (*NUL)          the NUL character (binary zero)
 
 
 WHAT \R MATCHES
 
-       These  are  recognized  only  at the very start of the pattern or after
+       These are recognized only at the very start of  the  pattern  or  after
        option setting with a similar syntax.
 
          (*BSR_ANYCRLF)  CR, LF, or CRLF
@@ -9589,6 +10028,9 @@
          \n              reference by number (can be ambiguous)
          \gn             reference by number
          \g{n}           reference by number
+         \g+n            relative reference by number (PCRE2 extension)
+         \g-n            relative reference by number
+         \g{+n}          relative reference by number (PCRE2 extension)
          \g{-n}          relative reference by number
          \k<name>        reference by name (Perl)
          \k'name'        reference by name (Perl)
@@ -9625,14 +10067,18 @@
          (?(-n)              relative reference condition
          (?(<name>)          named reference condition (Perl)
          (?('name')          named reference condition (Perl)
-         (?(name)            named reference condition (PCRE2)
+         (?(name)            named reference condition (PCRE2, deprecated)
          (?(R)               overall recursion condition
-         (?(Rn)              specific group recursion condition
-         (?(R&name)          specific recursion condition
+         (?(Rn)              specific numbered group recursion condition
+         (?(R&name)          specific named group recursion condition
          (?(DEFINE)          define subpattern for reference
          (?(VERSION[>]=n.m)  test PCRE2 version
          (?(assert)          assertion condition
 
+       Note  the  ambiguity of (?(R) and (?(Rn) which might be named reference
+       conditions or recursion tests. Such a condition  is  interpreted  as  a
+       reference condition if the relevant named group exists.
+
 
 BACKTRACKING CONTROL
 
@@ -9642,7 +10088,7 @@
          (*FAIL)         force backtrack; synonym (*F)
          (*MARK:NAME)    set name to be passed back; synonym (*:NAME)
 
-       The following act only when a subsequent match failure causes  a  back-
+       The  following  act only when a subsequent match failure causes a back-
        track to reach them. They all force a match failure, but they differ in
        what happens afterwards. Those that advance the start-of-match point do
        so only if the pattern is not anchored.
@@ -9664,14 +10110,14 @@
          (?C"text")      callout with string data
 
        The allowed string delimiters are ` ' " ^ % # $ (which are the same for
-       the start and the end), and the starting delimiter { matched  with  the
-       ending  delimiter  }. To encode the ending delimiter within the string,
+       the  start  and the end), and the starting delimiter { matched with the
+       ending delimiter }. To encode the ending delimiter within  the  string,
        double it.
 
 
 SEE ALSO
 
-       pcre2pattern(3),   pcre2api(3),   pcre2callout(3),    pcre2matching(3),
+       pcre2pattern(3),    pcre2api(3),   pcre2callout(3),   pcre2matching(3),
        pcre2(3).
 
 
@@ -9684,8 +10130,8 @@
 
 REVISION
 
-       Last updated: 16 October 2015
-       Copyright (c) 1997-2015 University of Cambridge.
+       Last updated: 17 June 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
@@ -9724,7 +10170,7 @@
        names  for  properties are supported. For example, \p{L} matches a let-
        ter. Its Perl synonym, \p{Letter}, is not supported.   Furthermore,  in
        Perl,  many properties may optionally be prefixed by "Is", for compati-
-       bility with Perl 5.6. PCRE does not support this.
+       bility with Perl 5.6. PCRE2 does not support this.
 
 
 WIDE CHARACTERS AND UTF MODES
@@ -9775,64 +10221,78 @@
        escapes (\h, \H, \v, and \V) do match all the appropriate Unicode char-
        acters, whether or not PCRE2_UCP is set.
 
-       Case-insensitive matching in UTF mode makes use of Unicode  properties.
-       A  few  Unicode characters such as Greek sigma have more than two code-
-       points that are case-equivalent, and these are treated as such.
+
+CASE-EQUIVALENCE IN UTF MODES
+
+       Case-insensitive matching in a UTF mode makes use of Unicode properties
+       except for characters whose code points are less than 128 and that have
+       at most two case-equivalent values. For these, a direct table lookup is
+       used  for speed. A few Unicode characters such as Greek sigma have more
+       than two codepoints that are case-equivalent, and these are treated  as
+       such.
 
 
 VALIDITY OF UTF STRINGS
 
-       When the PCRE2_UTF option is set, the strings passed  as  patterns  and
+       When  the  PCRE2_UTF  option is set, the strings passed as patterns and
        subjects are (by default) checked for validity on entry to the relevant
-       functions.  If an invalid UTF string is passed, an negative error  code
-       is  returned.  The  code  unit offset to the offending character can be
-       extracted from the match data block by  calling  pcre2_get_startchar(),
+       functions.   If an invalid UTF string is passed, an negative error code
+       is returned. The code unit offset to the  offending  character  can  be
+       extracted  from  the match data block by calling pcre2_get_startchar(),
        which is used for this purpose after a UTF error.
 
        UTF-16 and UTF-32 strings can indicate their endianness by special code
-       knows as a byte-order mark (BOM). The PCRE2  functions  do  not  handle
+       knows  as  a  byte-order  mark (BOM). The PCRE2 functions do not handle
        this, expecting strings to be in host byte order.
 
        A UTF string is checked before any other processing takes place. In the
-       case of pcre2_match()  and  pcre2_dfa_match()  calls  with  a  non-zero
-       starting  offset, the check is applied only to that part of the subject
-       that could be inspected during matching, and there is a check that  the
-       starting  offset points to the first code unit of a character or to the
-       end of the subject. If there are no lookbehind assertions in  the  pat-
-       tern,  the check starts at the starting offset. Otherwise, it starts at
-       the length of the longest lookbehind before the starting offset, or  at
-       the  start  of the subject if there are not that many characters before
-       the starting offset. Note that the sequences \b and \B are  one-charac-
+       case  of  pcre2_match()  and  pcre2_dfa_match()  calls  with a non-zero
+       starting offset, the check is applied only to that part of the  subject
+       that  could be inspected during matching, and there is a check that the
+       starting offset points to the first code unit of a character or to  the
+       end  of  the subject. If there are no lookbehind assertions in the pat-
+       tern, the check starts at the starting offset. Otherwise, it starts  at
+       the  length of the longest lookbehind before the starting offset, or at
+       the start of the subject if there are not that many  characters  before
+       the  starting offset. Note that the sequences \b and \B are one-charac-
        ter lookbehinds.
 
-       In  addition  to checking the format of the string, there is a check to
+       In addition to checking the format of the string, there is a  check  to
        ensure that all code points lie in the range U+0 to U+10FFFF, excluding
-       the  surrogate  area. The so-called "non-character" code points are not
+       the surrogate area. The so-called "non-character" code points  are  not
        excluded because Unicode corrigendum #9 makes it clear that they should
        not be.
 
-       Characters  in  the "Surrogate Area" of Unicode are reserved for use by
-       UTF-16, where they are used in pairs to encode code points with  values
-       greater  than  0xFFFF. The code points that are encoded by UTF-16 pairs
-       are available independently in the  UTF-8  and  UTF-32  encodings.  (In
-       other  words,  the  whole  surrogate  thing is a fudge for UTF-16 which
+       Characters in the "Surrogate Area" of Unicode are reserved for  use  by
+       UTF-16,  where they are used in pairs to encode code points with values
+       greater than 0xFFFF. The code points that are encoded by  UTF-16  pairs
+       are  available  independently  in  the  UTF-8 and UTF-32 encodings. (In
+       other words, the whole surrogate thing is  a  fudge  for  UTF-16  which
        unfortunately messes up UTF-8 and UTF-32.)
 
-       In some situations, you may already know that your strings  are  valid,
-       and  therefore  want  to  skip these checks in order to improve perfor-
-       mance, for example in the case of a long subject string that  is  being
-       scanned  repeatedly.   If you set the PCRE2_NO_UTF_CHECK option at com-
-       pile time or at match time, PCRE2 assumes that the pattern  or  subject
+       In  some  situations, you may already know that your strings are valid,
+       and therefore want to skip these checks in  order  to  improve  perfor-
+       mance,  for  example in the case of a long subject string that is being
+       scanned repeatedly.  If you set the PCRE2_NO_UTF_CHECK option  at  com-
+       pile  time  or at match time, PCRE2 assumes that the pattern or subject
        it is given (respectively) contains only valid UTF code unit sequences.
 
-       Passing  PCRE2_NO_UTF_CHECK  to pcre2_compile() just disables the check
+       Passing PCRE2_NO_UTF_CHECK to pcre2_compile() just disables  the  check
        for the pattern; it does not also apply to subject strings. If you want
-       to  disable the check for a subject string you must pass this option to
+       to disable the check for a subject string you must pass this option  to
        pcre2_match() or pcre2_dfa_match().
 
-       If you pass an invalid UTF string when PCRE2_NO_UTF_CHECK is  set,  the
+       If  you  pass an invalid UTF string when PCRE2_NO_UTF_CHECK is set, the
        result is undefined and your program may crash or loop indefinitely.
 
+       Note that setting PCRE2_NO_UTF_CHECK at compile time does  not  disable
+       the  error  that  is given if an escape sequence for an invalid Unicode
+       code point is encountered in the pattern. If you want to  allow  escape
+       sequences  such  as  \x{d800}  (a surrogate code point) you can set the
+       PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES extra option. However, this is pos-
+       sible only in UTF-8 and UTF-32 modes, because these values are not rep-
+       resentable in UTF-16.
+
    Errors in UTF-8 strings
 
        The following negative error codes are given for invalid UTF-8 strings:
@@ -9843,10 +10303,10 @@
          PCRE2_ERROR_UTF8_ERR4
          PCRE2_ERROR_UTF8_ERR5
 
-       The  string  ends  with a truncated UTF-8 character; the code specifies
-       how many bytes are missing (1 to 5). Although RFC 3629 restricts  UTF-8
-       characters  to  be  no longer than 4 bytes, the encoding scheme (origi-
-       nally defined by RFC 2279) allows for  up  to  6  bytes,  and  this  is
+       The string ends with a truncated UTF-8 character;  the  code  specifies
+       how  many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8
+       characters to be no longer than 4 bytes, the  encoding  scheme  (origi-
+       nally  defined  by  RFC  2279)  allows  for  up to 6 bytes, and this is
        checked first; hence the possibility of 4 or 5 missing bytes.
 
          PCRE2_ERROR_UTF8_ERR6
@@ -9856,24 +10316,24 @@
          PCRE2_ERROR_UTF8_ERR10
 
        The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of
-       the character do not have the binary value 0b10 (that  is,  either  the
+       the  character  do  not have the binary value 0b10 (that is, either the
        most significant bit is 0, or the next bit is 1).
 
          PCRE2_ERROR_UTF8_ERR11
          PCRE2_ERROR_UTF8_ERR12
 
-       A  character that is valid by the RFC 2279 rules is either 5 or 6 bytes
+       A character that is valid by the RFC 2279 rules is either 5 or 6  bytes
        long; these code points are excluded by RFC 3629.
 
          PCRE2_ERROR_UTF8_ERR13
 
-       A 4-byte character has a value greater than 0x10fff; these code  points
+       A  4-byte character has a value greater than 0x10fff; these code points
        are excluded by RFC 3629.
 
          PCRE2_ERROR_UTF8_ERR14
 
-       A  3-byte  character  has  a  value in the range 0xd800 to 0xdfff; this
-       range of code points are reserved by RFC 3629 for use with UTF-16,  and
+       A 3-byte character has a value in the  range  0xd800  to  0xdfff;  this
+       range  of code points are reserved by RFC 3629 for use with UTF-16, and
        so are excluded from UTF-8.
 
          PCRE2_ERROR_UTF8_ERR15
@@ -9882,26 +10342,26 @@
          PCRE2_ERROR_UTF8_ERR18
          PCRE2_ERROR_UTF8_ERR19
 
-       A  2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes
-       for a value that can be represented by fewer bytes, which  is  invalid.
-       For  example,  the two bytes 0xc0, 0xae give the value 0x2e, whose cor-
+       A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it  codes
+       for  a  value that can be represented by fewer bytes, which is invalid.
+       For example, the two bytes 0xc0, 0xae give the value 0x2e,  whose  cor-
        rect coding uses just one byte.
 
          PCRE2_ERROR_UTF8_ERR20
 
        The two most significant bits of the first byte of a character have the
-       binary  value 0b10 (that is, the most significant bit is 1 and the sec-
-       ond is 0). Such a byte can only validly occur as the second  or  subse-
+       binary value 0b10 (that is, the most significant bit is 1 and the  sec-
+       ond  is  0). Such a byte can only validly occur as the second or subse-
        quent byte of a multi-byte character.
 
          PCRE2_ERROR_UTF8_ERR21
 
-       The  first byte of a character has the value 0xfe or 0xff. These values
+       The first byte of a character has the value 0xfe or 0xff. These  values
        can never occur in a valid UTF-8 string.
 
    Errors in UTF-16 strings
 
-       The following  negative  error  codes  are  given  for  invalid  UTF-16
+       The  following  negative  error  codes  are  given  for  invalid UTF-16
        strings:
 
          PCRE2_ERROR_UTF16_ERR1  Missing low surrogate at end of string
@@ -9911,7 +10371,7 @@
 
    Errors in UTF-32 strings
 
-       The  following  negative  error  codes  are  given  for  invalid UTF-32
+       The following  negative  error  codes  are  given  for  invalid  UTF-32
        strings:
 
          PCRE2_ERROR_UTF32_ERR1  Surrogate character (0xd800 to 0xdfff)
@@ -9927,8 +10387,8 @@
 
 REVISION
 
-       Last updated: 03 July 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 17 May 2017
+       Copyright (c) 1997-2017 University of Cambridge.
 ------------------------------------------------------------------------------
 
 
diff --git a/dist2/doc/pcre2_callout_enumerate.3 b/dist2/doc/pcre2_callout_enumerate.3
index 4573bb4..109c9be 100644
--- a/dist2/doc/pcre2_callout_enumerate.3
+++ b/dist2/doc/pcre2_callout_enumerate.3
@@ -1,4 +1,4 @@
-.TH PCRE2_COMPILE 3 "23 March 2015" "PCRE2 10.20"
+.TH PCRE2_COMPILE 3 "23 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -24,20 +24,21 @@
   \fIcallout_data\fP   User data that is passed to the callback
 .sp
 The \fIcallback()\fP function is passed a pointer to a data block containing
-the following fields:
+the following fields (not necessarily in this order):
 .sp
-  \fIversion\fP                Block version number
-  \fIpattern_position\fP       Offset to next item in pattern
-  \fInext_item_length\fP       Length of next item in pattern
-  \fIcallout_number\fP         Number for numbered callouts
-  \fIcallout_string_offset\fP  Offset to string within pattern
-  \fIcallout_string_length\fP  Length of callout string
-  \fIcallout_string\fP         Points to callout string or is NULL
+  uint32_t   \fIversion\fP                Block version number
+  uint32_t   \fIcallout_number\fP         Number for numbered callouts
+  PCRE2_SIZE \fIpattern_position\fP       Offset to next item in pattern
+  PCRE2_SIZE \fInext_item_length\fP       Length of next item in pattern
+  PCRE2_SIZE \fIcallout_string_offset\fP  Offset to string within pattern
+  PCRE2_SIZE \fIcallout_string_length\fP  Length of callout string
+  PCRE2_SPTR \fIcallout_string\fP         Points to callout string or is NULL
 .sp
-The second argument is the callout data that was passed to
-\fBpcre2_callout_enumerate()\fP. The \fBcallback()\fP function must return zero
-for success. Any other value causes the pattern scan to stop, with the value
-being passed back as the result of \fBpcre2_callout_enumerate()\fP.
+The second argument passed to the \fBcallback()\fP function is the callout data
+that was passed to \fBpcre2_callout_enumerate()\fP. The \fBcallback()\fP
+function must return zero for success. Any other value causes the pattern scan
+to stop, with the value being passed back as the result of
+\fBpcre2_callout_enumerate()\fP.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_code_copy.3 b/dist2/doc/pcre2_code_copy.3
index 270b3a6..09b4705 100644
--- a/dist2/doc/pcre2_code_copy.3
+++ b/dist2/doc/pcre2_code_copy.3
@@ -1,4 +1,4 @@
-.TH PCRE2_CODE_COPY 3 "26 February 2016" "PCRE2 10.22"
+.TH PCRE2_CODE_COPY 3 "22 November 2016" "PCRE2 10.23"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -16,8 +16,9 @@
 This function makes a copy of the memory used for a compiled pattern, excluding
 any memory used by the JIT compiler. Without a subsequent call to
 \fBpcre2_jit_compile()\fP, the copy can be used only for non-JIT matching. The
-yield of the function is NULL if \fIcode\fP is NULL or if sufficient memory
-cannot be obtained.
+pointer to the character tables is copied, not the tables themselves (see
+\fBpcre2_code_copy_with_tables()\fP). The yield of the function is NULL if
+\fIcode\fP is NULL or if sufficient memory cannot be obtained.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_code_copy_with_tables.3 b/dist2/doc/pcre2_code_copy_with_tables.3
new file mode 100644
index 0000000..cfbddb3
--- /dev/null
+++ b/dist2/doc/pcre2_code_copy_with_tables.3
@@ -0,0 +1,32 @@
+.TH PCRE2_CODE_COPY 3 "22 November 2016" "PCRE2 10.23"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *\fIcode\fP);
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function makes a copy of the memory used for a compiled pattern, excluding
+any memory used by the JIT compiler. Without a subsequent call to
+\fBpcre2_jit_compile()\fP, the copy can be used only for non-JIT matching.
+Unlike \fBpcre2_code_copy()\fP, a separate copy of the character tables is also
+made, with the new code pointing to it. This memory will be automatically freed
+when \fBpcre2_code_free()\fP is called. The yield of the function is NULL if
+\fIcode\fP is NULL or if sufficient memory cannot be obtained.
+.P
+There is a complete description of the PCRE2 native API in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcre2posix\fP
+.\"
+page.
diff --git a/dist2/doc/pcre2_code_free.3 b/dist2/doc/pcre2_code_free.3
index 5127081..7376869 100644
--- a/dist2/doc/pcre2_code_free.3
+++ b/dist2/doc/pcre2_code_free.3
@@ -1,4 +1,4 @@
-.TH PCRE2_CODE_FREE 3 "29 July 2015" "PCRE2 10.21"
+.TH PCRE2_CODE_FREE 3 "23 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -14,7 +14,9 @@
 .rs
 .sp
 This function frees the memory used for a compiled pattern, including any
-memory used by the JIT compiler.
+memory used by the JIT compiler. If the compiled pattern was created by a call
+to \fBpcre2_code_copy_with_tables()\fP, the memory for the character tables is
+also freed.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_compile.3 b/dist2/doc/pcre2_compile.3
index 1e0dca5..19f35c3 100644
--- a/dist2/doc/pcre2_compile.3
+++ b/dist2/doc/pcre2_compile.3
@@ -1,4 +1,4 @@
-.TH PCRE2_COMPILE 3 "22 April 2015" "PCRE2 10.20"
+.TH PCRE2_COMPILE 3 "16 June 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -25,26 +25,34 @@
   \fIerroffset\fP     Where to put an error offset
   \fIccontext\fP      Pointer to a compile context or NULL
 .sp
-The length of the string and any error offset that is returned are in code
-units, not characters. A compile context is needed only if you want to change
+The length of the pattern and any error offset that is returned are in code
+units, not characters. A compile context is needed only if you want to provide
+custom memory allocation functions, or to provide an external function for
+system stack size checking, or to change one or more of these parameters:
 .sp
-  What \eR matches (Unicode newlines or CR, LF, CRLF only)
-  PCRE2's character tables
-  The newline character sequence
-  The compile time nested parentheses limit
+  What \eR matches (Unicode newlines, or CR, LF, CRLF only);
+  PCRE2's character tables;
+  The newline character sequence;
+  The compile time nested parentheses limit;
+  The maximum pattern length (in code units) that is allowed.
+  The additional options bits (see pcre2_set_compile_extra_options())
 .sp
-or provide an external function for stack size checking. The option bits are:
+The option bits are:
 .sp
   PCRE2_ANCHORED           Force pattern anchoring
+  PCRE2_ALLOW_EMPTY_CLASS  Allow empty classes
   PCRE2_ALT_BSUX           Alternative handling of \eu, \eU, and \ex
   PCRE2_ALT_CIRCUMFLEX     Alternative handling of ^ in multiline mode
+  PCRE2_ALT_VERBNAMES      Process backslashes in verb names
   PCRE2_AUTO_CALLOUT       Compile automatic callouts
   PCRE2_CASELESS           Do caseless matching
   PCRE2_DOLLAR_ENDONLY     $ not to match newline at end
   PCRE2_DOTALL             . matches anything including NL
   PCRE2_DUPNAMES           Allow duplicate names for subpatterns
+  PCRE2_ENDANCHORED        Pattern can match only at end of subject
   PCRE2_EXTENDED           Ignore white space and # comments
   PCRE2_FIRSTLINE          Force matching to be before newline
+  PCRE2_LITERAL            Pattern characters are all literal
   PCRE2_MATCH_UNSET_BACKREF  Match unset back references
   PCRE2_MULTILINE          ^ and $ match newlines within data
   PCRE2_NEVER_BACKSLASH_C  Lock out the use of \eC in patterns
@@ -59,19 +67,21 @@
                              (only relevant if PCRE2_UTF is set)
   PCRE2_UCP                Use Unicode properties for \ed, \ew, etc.
   PCRE2_UNGREEDY           Invert greediness of quantifiers
+  PCRE2_USE_OFFSET_LIMIT   Enable offset limit for unanchored matching
   PCRE2_UTF                Treat pattern and subjects as UTF strings
 .sp
-PCRE2 must be built with Unicode support in order to use PCRE2_UTF, PCRE2_UCP
-and related options.
+PCRE2 must be built with Unicode support (the default) in order to use
+PCRE2_UTF, PCRE2_UCP and related options.
 .P
 The yield of the function is a pointer to a private data structure that
 contains the compiled pattern, or NULL if an error was detected.
 .P
-There is a complete description of the PCRE2 native API in the
+There is a complete description of the PCRE2 native API, with more detail on
+each option, in the
 .\" HREF
 \fBpcre2api\fP
 .\"
-page and a description of the POSIX API in the
+page, and a description of the POSIX API in the
 .\" HREF
 \fBpcre2posix\fP
 .\"
diff --git a/dist2/doc/pcre2_config.3 b/dist2/doc/pcre2_config.3
index 0c29ce6..ab9623d 100644
--- a/dist2/doc/pcre2_config.3
+++ b/dist2/doc/pcre2_config.3
@@ -1,4 +1,4 @@
-.TH PCRE2_CONFIG 3 "20 April 2014" "PCRE2 10.0"
+.TH PCRE2_CONFIG 3 "16 September 2017" "PCRE2 10.31"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -31,22 +31,29 @@
   PCRE2_CONFIG_BSR             Indicates what \eR matches by default:
                                  PCRE2_BSR_UNICODE
                                  PCRE2_BSR_ANYCRLF
+  PCRE2_CONFIG_COMPILED_WIDTHS Which of 8/16/32 support was compiled
+  PCRE2_CONFIG_DEPTHLIMIT      Default backtracking depth limit
+  PCRE2_CONFIG_HEAPLIMIT       Default heap memory limit
+.\" JOIN
   PCRE2_CONFIG_JIT             Availability of just-in-time compiler
                                 support (1=yes 0=no)
-  PCRE2_CONFIG_JITTARGET       Information about the target archi-
-                                 tecture for the JIT compiler
+.\" JOIN
+  PCRE2_CONFIG_JITTARGET       Information (a string) about the target
+                                 architecture for the JIT compiler
   PCRE2_CONFIG_LINKSIZE        Configured internal link size (2, 3, 4)
   PCRE2_CONFIG_MATCHLIMIT      Default internal resource limit
+  PCRE2_CONFIG_NEVER_BACKSLASH_C  Whether or not \eC is disabled
   PCRE2_CONFIG_NEWLINE         Code for the default newline sequence:
                                  PCRE2_NEWLINE_CR
                                  PCRE2_NEWLINE_LF
                                  PCRE2_NEWLINE_CRLF
                                  PCRE2_NEWLINE_ANY
                                  PCRE2_NEWLINE_ANYCRLF
+                                 PCRE2_NEWLINE_NUL
   PCRE2_CONFIG_PARENSLIMIT     Default parentheses nesting limit
-  PCRE2_CONFIG_RECURSIONLIMIT  Internal recursion depth limit
-  PCRE2_CONFIG_STACKRECURSE    Recursion implementation (1=stack
-                                 0=heap)
+  PCRE2_CONFIG_RECURSIONLIMIT  Obsolete: use PCRE2_CONFIG_DEPTHLIMIT
+  PCRE2_CONFIG_STACKRECURSE    Obsolete: always returns 0
+.\" JOIN
   PCRE2_CONFIG_UNICODE         Availability of Unicode support (1=yes
                                  0=no)
   PCRE2_CONFIG_UNICODE_VERSION The Unicode version (a string)
diff --git a/dist2/doc/pcre2_convert_context_copy.3 b/dist2/doc/pcre2_convert_context_copy.3
new file mode 100644
index 0000000..827c3e9
--- /dev/null
+++ b/dist2/doc/pcre2_convert_context_copy.3
@@ -0,0 +1,26 @@
+.TH PCRE2_CONVERT_CONTEXT_COPY 3 "10 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B pcre2_convert_context *pcre2_convert_context_copy(
+.B "  pcre2_convert_context *\fIcvcontext\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is part of an experimental set of pattern conversion functions.
+It makes a new copy of a convert context, using the memory allocation function
+that was used for the original context. The result is NULL if the memory cannot
+be obtained.
+.P
+The pattern conversion functions are described in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
diff --git a/dist2/doc/pcre2_convert_context_create.3 b/dist2/doc/pcre2_convert_context_create.3
new file mode 100644
index 0000000..91c17fb
--- /dev/null
+++ b/dist2/doc/pcre2_convert_context_create.3
@@ -0,0 +1,27 @@
+.TH PCRE2_CONVERT_CONTEXT_CREATE 3 "10 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B pcre2_convert_context *pcre2_convert_context_create(
+.B "  pcre2_general_context *\fIgcontext\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is part of an experimental set of pattern conversion functions.
+It creates and initializes a new convert context. If its argument is
+NULL, \fBmalloc()\fP is used to get the necessary memory; otherwise the memory
+allocation function within the general context is used. The result is NULL if
+the memory could not be obtained.
+.P
+The pattern conversion functions are described in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
diff --git a/dist2/doc/pcre2_convert_context_free.3 b/dist2/doc/pcre2_convert_context_free.3
new file mode 100644
index 0000000..fd5b13c
--- /dev/null
+++ b/dist2/doc/pcre2_convert_context_free.3
@@ -0,0 +1,25 @@
+.TH PCRE2_CONVERT_CONTEXT_FREE 3 "10 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B void pcre2_convert_context_free(pcre2_convert_context *\fIcvcontext\fP);
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is part of an experimental set of pattern conversion functions.
+It frees the memory occupied by a convert context, using the memory
+freeing function from the general context with which it was created, or
+\fBfree()\fP if that was not set.
+.P
+The pattern conversion functions are described in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
diff --git a/dist2/doc/pcre2_converted_pattern_free.3 b/dist2/doc/pcre2_converted_pattern_free.3
new file mode 100644
index 0000000..687e078
--- /dev/null
+++ b/dist2/doc/pcre2_converted_pattern_free.3
@@ -0,0 +1,25 @@
+.TH PCRE2_CONVERTED_PATTERN_FREE 3 "11 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B void pcre2_converted_pattern_free(PCRE2_UCHAR *\fIconverted_pattern\fP);
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is part of an experimental set of pattern conversion functions.
+It frees the memory occupied by a converted pattern that was obtained by
+calling \fBpcre2_pattern_convert()\fP with arguments that caused it to place
+the converted pattern into newly obtained heap memory.
+.P
+The pattern conversion functions are described in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
diff --git a/dist2/doc/pcre2_dfa_match.3 b/dist2/doc/pcre2_dfa_match.3
index f45da0d..7839145 100644
--- a/dist2/doc/pcre2_dfa_match.3
+++ b/dist2/doc/pcre2_dfa_match.3
@@ -1,4 +1,4 @@
-.TH PCRE2_DFA_MATCH 3 "12 May 2013" "PCRE2 10.00"
+.TH PCRE2_DFA_MATCH 3 "30 May 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -19,8 +19,9 @@
 .sp
 This function matches a compiled regular expression against a given subject
 string, using an alternative matching algorithm that scans the subject string
-just once (\fInot\fP Perl-compatible). (The Perl-compatible matching function
-is \fBpcre2_match()\fP.) The arguments for this function are:
+just once (except when processing lookaround assertions). This function is
+\fInot\fP Perl-compatible (the Perl-compatible matching function is
+\fBpcre2_match()\fP). The arguments for this function are:
 .sp
   \fIcode\fP         Points to the compiled pattern
   \fIsubject\fP      Points to the subject string
@@ -33,22 +34,28 @@
   \fIwscount\fP      Number of elements in the vector
 .sp
 For \fBpcre2_dfa_match()\fP, a match context is needed only if you want to set
-up a callout function. The \fIlength\fP and \fIstartoffset\fP values are code
-units, not characters. The options are:
+up a callout function or specify the match and/or the recursion depth limits.
+The \fIlength\fP and \fIstartoffset\fP values are code units, not characters.
+The options are:
 .sp
   PCRE2_ANCHORED          Match only at the first position
+  PCRE2_ENDANCHORED       Pattern can match only at end of subject
   PCRE2_NOTBOL            Subject is not the beginning of a line
   PCRE2_NOTEOL            Subject is not the end of a line
   PCRE2_NOTEMPTY          An empty string is not a valid match
+.\" JOIN
   PCRE2_NOTEMPTY_ATSTART  An empty string at the start of the subject
                            is not a valid match
+.\" JOIN
   PCRE2_NO_UTF_CHECK      Do not check the subject for UTF
                            validity (only relevant if PCRE2_UTF
                            was set at compile time)
+.\" JOIN
+  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial
+                           match even if there is a full match
+.\" JOIN
   PCRE2_PARTIAL_SOFT      Return PCRE2_ERROR_PARTIAL for a partial
-                            match if no full matches are found
-  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial match
-                           even if there is a full match as well
+                           match if no full matches are found
   PCRE2_DFA_RESTART       Restart after a partial match
   PCRE2_DFA_SHORTEST      Return only the shortest match
 .sp
diff --git a/dist2/doc/pcre2_get_error_message.3 b/dist2/doc/pcre2_get_error_message.3
index 9378b18..3d3e0de 100644
--- a/dist2/doc/pcre2_get_error_message.3
+++ b/dist2/doc/pcre2_get_error_message.3
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_ERROR_MESSAGE 3 "17 June 2016" "PCRE2 10.22"
+.TH PCRE2_GET_ERROR_MESSAGE 3 "24 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -22,11 +22,11 @@
   \fIbuffer\fP      where to put the message
   \fIbufflen\fP     the length of the buffer (code units)
 .sp
-The function returns the length of the message, excluding the trailing zero, or
-the negative error code PCRE2_ERROR_NOMEMORY if the buffer is too small. In
-this case, the returned message is truncated (but still with a trailing zero).
-If \fIerrorcode\fP does not contain a recognized error code number, the
-negative value PCRE2_ERROR_BADDATA is returned.
+The function returns the length of the message in code units, excluding the
+trailing zero, or the negative error code PCRE2_ERROR_NOMEMORY if the buffer is
+too small. In this case, the returned message is truncated (but still with a
+trailing zero). If \fIerrorcode\fP does not contain a recognized error code
+number, the negative value PCRE2_ERROR_BADDATA is returned.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_get_mark.3 b/dist2/doc/pcre2_get_mark.3
index e741dfe..dce377d 100644
--- a/dist2/doc/pcre2_get_mark.3
+++ b/dist2/doc/pcre2_get_mark.3
@@ -1,4 +1,4 @@
-.TH PCRE2_GET_MARK 3 "24 October 2014" "PCRE2 10.00"
+.TH PCRE2_GET_MARK 3 "13 October 2017" "PCRE2 10.31"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -14,11 +14,14 @@
 .rs
 .sp
 After a call of \fBpcre2_match()\fP that was passed the match block that is
-this function's argument, this function returns a pointer to the last (*MARK)
-name that was encountered. The name is zero-terminated, and is within the
-compiled pattern. If no (*MARK) name is available, NULL is returned. A (*MARK)
-name may be available after a failed match or a partial match, as well as after
-a successful one.
+this function's argument, this function returns a pointer to the last (*MARK),
+(*PRUNE), or (*THEN) name that was encountered during the matching process. The
+name is zero-terminated, and is within the compiled pattern. The length of the
+name is in the preceding code unit. If no name is available, NULL is returned.
+.P
+After a successful match, the name that is returned is the last one on the
+matching path. After a failed match or a partial match, the last encountered
+name is returned.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_jit_stack_create.3 b/dist2/doc/pcre2_jit_stack_create.3
index d530d50..61ccf79 100644
--- a/dist2/doc/pcre2_jit_stack_create.3
+++ b/dist2/doc/pcre2_jit_stack_create.3
@@ -1,4 +1,4 @@
-.TH PCRE2_JIT_STACK_CREATE 3 "03 November 2014" "PCRE2 10.00"
+.TH PCRE2_JIT_STACK_CREATE 3 "24 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -20,10 +20,9 @@
 context, for memory allocation functions, or NULL for standard memory
 allocation. The result can be passed to the JIT run-time code by calling
 \fBpcre2_jit_stack_assign()\fP to associate the stack with a compiled pattern,
-which can then be processed by \fBpcre2_match()\fP. If the "fast path" JIT
-matcher, \fBpcre2_jit_match()\fP is used, the stack can be passed directly as
-an argument. A maximum stack size of 512K to 1M should be more than enough for
-any pattern. For more details, see the
+which can then be processed by \fBpcre2_match()\fP or \fBpcre2_jit_match()\fP.
+A maximum stack size of 512K to 1M should be more than enough for any pattern.
+For more details, see the
 .\" HREF
 \fBpcre2jit\fP
 .\"
diff --git a/dist2/doc/pcre2_maketables.3 b/dist2/doc/pcre2_maketables.3
index 322dba7..740954b 100644
--- a/dist2/doc/pcre2_maketables.3
+++ b/dist2/doc/pcre2_maketables.3
@@ -1,4 +1,4 @@
-.TH PCRE2_MAKETABLES 3 "21 October 2014" "PCRE2 10.00"
+.TH PCRE2_MAKETABLES 3 "17 April 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -7,15 +7,15 @@
 .B #include <pcre2.h>
 .PP
 .SM
-.B const unsigned char *pcre2_maketables(pcre22_general_context *\fIgcontext\fP);
+.B const unsigned char *pcre2_maketables(pcre2_general_context *\fIgcontext\fP);
 .
 .SH DESCRIPTION
 .rs
 .sp
-This function builds a set of character tables for character values less than
-256. These can be passed to \fBpcre2_compile()\fP in a compile context in order
-to override the internal, built-in tables (which were either defaulted or made
-by \fBpcre2_maketables()\fP when PCRE2 was compiled). See the
+This function builds a set of character tables for character code points that
+are less than 256. These can be passed to \fBpcre2_compile()\fP in a compile
+context in order to override the internal, built-in tables (which were either
+defaulted or made by \fBpcre2_maketables()\fP when PCRE2 was compiled). See the
 .\" HREF
 \fBpcre2_set_character_tables()\fP
 .\"
diff --git a/dist2/doc/pcre2_match.3 b/dist2/doc/pcre2_match.3
index f25cace..6f7aefb 100644
--- a/dist2/doc/pcre2_match.3
+++ b/dist2/doc/pcre2_match.3
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH 3 "21 October 2014" "PCRE2 10.00"
+.TH PCRE2_MATCH 3 "14 November 2017" "PCRE2 10.31"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -18,7 +18,13 @@
 .sp
 This function matches a compiled regular expression against a given subject
 string, using a matching algorithm that is similar to Perl's. It returns
-offsets to captured substrings. Its arguments are:
+offsets to what it has matched and to captured substrings via the
+\fBmatch_data\fP block, which can be processed by functions with names that
+start with \fBpcre2_get_ovector_...()\fP or \fBpcre2_substring_...()\fP. The
+return from \fBpcre2_match()\fP is one more than the highest numbered capturing
+pair that has been set (for example, 1 if there are no captures), zero if the
+vector of offsets is too small, or a negative error code for no match and other
+errors. The function arguments are:
 .sp
   \fIcode\fP         Points to the compiled pattern
   \fIsubject\fP      Points to the subject string
@@ -31,26 +37,35 @@
 A match context is needed only if you want to:
 .sp
   Set up a callout function
-  Change the limit for calling the internal function \fImatch()\fP
-  Change the limit for calling \fImatch()\fP recursively
-  Set custom memory management when the heap is used for recursion
+  Set a matching offset limit
+  Change the heap memory limit
+  Change the backtracking match limit
+  Change the backtracking depth limit
+  Set custom memory management specifically for the match
 .sp
 The \fIlength\fP and \fIstartoffset\fP values are code
-units, not characters. The options are:
+units, not characters. The length may be given as PCRE2_ZERO_TERMINATE for a
+subject that is terminated by a binary zero code unit. The options are:
 .sp
   PCRE2_ANCHORED          Match only at the first position
+  PCRE2_ENDANCHORED       Pattern can match only at end of subject
   PCRE2_NOTBOL            Subject string is not the beginning of a line
   PCRE2_NOTEOL            Subject string is not the end of a line
   PCRE2_NOTEMPTY          An empty string is not a valid match
+.\" JOIN
   PCRE2_NOTEMPTY_ATSTART  An empty string at the start of the subject
                            is not a valid match
+  PCRE2_NO_JIT            Do not use JIT matching
+.\" JOIN
   PCRE2_NO_UTF_CHECK      Do not check the subject for UTF
                            validity (only relevant if PCRE2_UTF
                            was set at compile time)
+.\" JOIN
+  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial
+                           match even if there is a full match
+.\" JOIN
   PCRE2_PARTIAL_SOFT      Return PCRE2_ERROR_PARTIAL for a partial
                             match if no full matches are found
-  PCRE2_PARTIAL_HARD      Return PCRE2_ERROR_PARTIAL for a partial match
-                           if that is found before a full match
 .sp
 For details of partial matching, see the
 .\" HREF
diff --git a/dist2/doc/pcre2_match_data_free.3 b/dist2/doc/pcre2_match_data_free.3
index 5e4bc62..e22074b 100644
--- a/dist2/doc/pcre2_match_data_free.3
+++ b/dist2/doc/pcre2_match_data_free.3
@@ -1,4 +1,4 @@
-.TH PCRE2_MATCH_DATA_FREE 3 "24 October 2014" "PCRE2 10.00"
+.TH PCRE2_MATCH_DATA_FREE 3 "25 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -14,8 +14,8 @@
 .rs
 .sp
 This function frees the memory occupied by a match data block, using the memory
-freeing function from the general context with which it was created, or
-\fBfree()\fP if that was not set.
+freeing function from the general context or compiled pattern with which it was
+created, or \fBfree()\fP if that was not set.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_pattern_convert.3 b/dist2/doc/pcre2_pattern_convert.3
new file mode 100644
index 0000000..b72acb7
--- /dev/null
+++ b/dist2/doc/pcre2_pattern_convert.3
@@ -0,0 +1,55 @@
+.TH PCRE2_PATTERN_CONVERT 3 "11 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_pattern_convert(PCRE2_SPTR \fIpattern\fP, PCRE2_SIZE \fIlength\fP,
+.B "  uint32_t \fIoptions\fP, PCRE2_UCHAR **\fIbuffer\fP,"
+.B "  PCRE2_SIZE *\fIblength\fP, pcre2_convert_context *\fIcvcontext\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is part of an experimental set of pattern conversion functions.
+It converts a foreign pattern (for example, a glob) into a PCRE2 regular
+expression pattern. Its arguments are:
+.sp
+  \fIpattern\fP     The foreign pattern
+  \fIlength\fP      The length of the input pattern or PCRE2_ZERO_TERMINATED
+  \fIoptions\fP     Option bits
+  \fIbuffer\fP      Pointer to pointer to output buffer, or NULL
+  \fIblength\fP     Pointer to output length field
+  \fIcvcontext\fP   Pointer to a convert context or NULL
+.sp
+The length of the converted pattern (excluding the terminating zero) is
+returned via \fIblength\fP. If \fIbuffer\fP is NULL, the function just returns
+the output length. If \fIbuffer\fP points to a NULL pointer, heap memory is
+obtained for the converted pattern, using the allocator in the context if
+present (or else \fBmalloc()\fP), and the field pointed to by \fIbuffer\fP is
+updated. If \fIbuffer\fP points to a non-NULL field, that must point to a
+buffer whose size is in the variable pointed to by \fIblength\fP. This value is
+updated.
+.P
+The option bits are:
+.sp
+  PCRE2_CONVERT_UTF                     Input is UTF
+  PCRE2_CONVERT_NO_UTF_CHECK            Do not check UTF validity
+  PCRE2_CONVERT_POSIX_BASIC             Convert POSIX basic pattern
+  PCRE2_CONVERT_POSIX_EXTENDED          Convert POSIX extended pattern
+  PCRE2_CONVERT_GLOB                    ) Convert
+  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR  )   various types
+  PCRE2_CONVERT_GLOB_NO_STARSTAR        )     of glob
+.sp
+The return value from \fBpcre2_pattern_convert()\fP is zero on success or a
+non-zero PCRE2 error code.
+.P
+The pattern conversion functions are described in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
diff --git a/dist2/doc/pcre2_pattern_info.3 b/dist2/doc/pcre2_pattern_info.3
index 575840b..64bfc45 100644
--- a/dist2/doc/pcre2_pattern_info.3
+++ b/dist2/doc/pcre2_pattern_info.3
@@ -1,4 +1,4 @@
-.TH PCRE2_PATTERN_INFO 3 "21 November 2015" "PCRE2 10.21"
+.TH PCRE2_PATTERN_INFO 3 "16 December 2017" "PCRE2 10.31"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -15,7 +15,7 @@
 .sp
 This function returns information about a compiled pattern. Its arguments are:
 .sp
-  \fIcode\fP     Pointer to a compiled regular expression
+  \fIcode\fP     Pointer to a compiled regular expression pattern
   \fIwhat\fP     What information is required
   \fIwhere\fP    Where to put the information
 .sp
@@ -29,25 +29,38 @@
                                PCRE2_BSR_UNICODE: Unicode line endings
                                PCRE2_BSR_ANYCRLF: CR, LF, or CRLF only
   PCRE2_INFO_CAPTURECOUNT    Number of capturing subpatterns
+.\" JOIN
+  PCRE2_INFO_DEPTHLIMIT      Backtracking depth limit if set,
+                               otherwise PCRE2_ERROR_UNSET
+  PCRE2_INFO_EXTRAOPTIONS    Extra options that were passed in the
+                               compile context
   PCRE2_INFO_FIRSTBITMAP     Bitmap of first code units, or NULL
   PCRE2_INFO_FIRSTCODETYPE   Type of start-of-match information
                                0 nothing set
                                1 first code unit is set
                                2 start of string or after newline
   PCRE2_INFO_FIRSTCODEUNIT   First code unit when type is 1
+  PCRE2_INFO_FRAMESIZE       Size of backtracking frame
   PCRE2_INFO_HASBACKSLASHC   Return 1 if pattern contains \eC
+.\" JOIN
   PCRE2_INFO_HASCRORLF       Return 1 if explicit CR or LF matches
                                exist in the pattern
+.\" JOIN
+  PCRE2_INFO_HEAPLIMIT       Heap memory limit if set,
+                               otherwise PCRE2_ERROR_UNSET
   PCRE2_INFO_JCHANGED        Return 1 if (?J) or (?-J) was used
   PCRE2_INFO_JITSIZE         Size of JIT compiled code, or 0
   PCRE2_INFO_LASTCODETYPE    Type of must-be-present information
                                0 nothing set
                                1 code unit is set
   PCRE2_INFO_LASTCODEUNIT    Last code unit when type is 1
+.\" JOIN
   PCRE2_INFO_MATCHEMPTY      1 if the pattern can match an
                                empty string, 0 otherwise
+.\" JOIN
   PCRE2_INFO_MATCHLIMIT      Match limit if set,
                                otherwise PCRE2_ERROR_UNSET
+.\" JOIN
   PCRE2_INFO_MAXLOOKBEHIND   Length (in characters) of the longest
                                lookbehind assertion
   PCRE2_INFO_MINLENGTH       Lower bound length of matching strings
@@ -60,8 +73,8 @@
                                PCRE2_NEWLINE_CRLF
                                PCRE2_NEWLINE_ANY
                                PCRE2_NEWLINE_ANYCRLF
-  PCRE2_INFO_RECURSIONLIMIT  Recursion limit if set,
-                               otherwise PCRE2_ERROR_UNSET
+                               PCRE2_NEWLINE_NUL
+  PCRE2_INFO_RECURSIONLIMIT  Obsolete synonym for PCRE2_INFO_DEPTHLIMIT
   PCRE2_INFO_SIZE            Size of compiled pattern
 .sp
 If \fIwhere\fP is NULL, the function returns the amount of memory needed for
diff --git a/dist2/doc/pcre2_set_callout.3 b/dist2/doc/pcre2_set_callout.3
index 2f86f69..cb48e14 100644
--- a/dist2/doc/pcre2_set_callout.3
+++ b/dist2/doc/pcre2_set_callout.3
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_CALLOUT 3 "24 October 2014" "PCRE2 10.00"
+.TH PCRE2_SET_CALLOUT 3 "21 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -17,7 +17,7 @@
 .sp
 This function sets the callout fields in a match context (the first argument).
 The second argument specifies a callout function, and the third argument is an
-opaque data time that is passed to it. The result of this function is always
+opaque data item that is passed to it. The result of this function is always
 zero.
 .P
 There is a complete description of the PCRE2 native API in the
diff --git a/dist2/doc/pcre2_set_compile_extra_options.3 b/dist2/doc/pcre2_set_compile_extra_options.3
new file mode 100644
index 0000000..1d73a8f
--- /dev/null
+++ b/dist2/doc/pcre2_set_compile_extra_options.3
@@ -0,0 +1,38 @@
+.TH PCRE2_SET_MAX_PATTERN_LENGTH 3 "16 June 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_set_compile_extra_options(pcre2_compile_context *\fIccontext\fP,
+.B "  PCRE2_SIZE \fIextra_options\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function sets additional option bits for \fBpcre2_compile()\fP that are
+housed in a compile context. It completely replaces all the bits. The extra
+options are:
+.sp
+.\" JOIN
+  PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES  Allow \ex{df800} to \ex{dfff}
+                                         in UTF-8 and UTF-32 modes
+.\" JOIN
+  PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL    Treat all invalid escapes as
+                                         a literal following character
+  PCRE2_EXTRA_MATCH_LINE               Pattern matches whole lines
+  PCRE2_EXTRA_MATCH_WORD               Pattern matches "words"
+.sp
+There is a complete description of the PCRE2 native API in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcre2posix\fP
+.\"
+page.
diff --git a/dist2/doc/pcre2_set_depth_limit.3 b/dist2/doc/pcre2_set_depth_limit.3
new file mode 100644
index 0000000..62bc7fe
--- /dev/null
+++ b/dist2/doc/pcre2_set_depth_limit.3
@@ -0,0 +1,28 @@
+.TH PCRE2_SET_DEPTH_LIMIT 3 "25 March 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_set_depth_limit(pcre2_match_context *\fImcontext\fP,
+.B "  uint32_t \fIvalue\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function sets the backtracking depth limit field in a match context. The
+result is always zero.
+.P
+There is a complete description of the PCRE2 native API in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcre2posix\fP
+.\"
+page.
diff --git a/dist2/doc/pcre2_set_glob_escape.3 b/dist2/doc/pcre2_set_glob_escape.3
new file mode 100644
index 0000000..d5637af
--- /dev/null
+++ b/dist2/doc/pcre2_set_glob_escape.3
@@ -0,0 +1,29 @@
+.TH PCRE2_SET_GLOB_ESCAPE 3 "11 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_set_glob_escape(pcre2_convert_context *\fIcvcontext\fP,
+.B "  uint32_t \fIescape_char\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is part of an experimental set of pattern conversion functions.
+It sets the escape character that is used when converting globs. The second
+argument must either be zero (meaning there is no escape character) or a
+punctuation character whose code point is less than 256. The default is grave
+accent if running under Windows, otherwise backslash. The result of the
+function is zero for success or PCRE2_ERROR_BADDATA if the second argument is
+invalid.
+.P
+The pattern conversion functions are described in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
diff --git a/dist2/doc/pcre2_set_glob_separator.3 b/dist2/doc/pcre2_set_glob_separator.3
new file mode 100644
index 0000000..273b515
--- /dev/null
+++ b/dist2/doc/pcre2_set_glob_separator.3
@@ -0,0 +1,28 @@
+.TH PCRE2_SET_GLOB_SEPARATOR 3 "11 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_set_glob_separator(pcre2_convert_context *\fIcvcontext\fP,
+.B "  uint32_t \fIseparator_char\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is part of an experimental set of pattern conversion functions.
+It sets the component separator character that is used when converting globs.
+The second argument must one of the characters forward slash, backslash, or
+dot. The default is backslash when running under Windows, otherwise forward
+slash. The result of the function is zero for success or PCRE2_ERROR_BADDATA if
+the second argument is invalid.
+.P
+The pattern conversion functions are described in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
diff --git a/dist2/doc/pcre2_set_heap_limit.3 b/dist2/doc/pcre2_set_heap_limit.3
new file mode 100644
index 0000000..a99b4ab
--- /dev/null
+++ b/dist2/doc/pcre2_set_heap_limit.3
@@ -0,0 +1,28 @@
+.TH PCRE2_SET_DEPTH_LIMIT 3 "11 April 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_set_heap_limit(pcre2_match_context *\fImcontext\fP,
+.B "  uint32_t \fIvalue\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function sets the backtracking heap limit field in a match context. The
+result is always zero.
+.P
+There is a complete description of the PCRE2 native API in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcre2posix\fP
+.\"
+page.
diff --git a/dist2/doc/pcre2_set_max_pattern_length.3 b/dist2/doc/pcre2_set_max_pattern_length.3
new file mode 100644
index 0000000..7aa01c7
--- /dev/null
+++ b/dist2/doc/pcre2_set_max_pattern_length.3
@@ -0,0 +1,31 @@
+.TH PCRE2_SET_MAX_PATTERN_LENGTH 3 "05 October 2016" "PCRE2 10.23"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_set_max_pattern_length(pcre2_compile_context *\fIccontext\fP,
+.B "  PCRE2_SIZE \fIvalue\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function sets, in a compile context, the maximum text length (in code
+units) of the pattern that can be compiled. The result is always zero. If a
+longer pattern is passed to \fBpcre2_compile()\fP there is an immediate error
+return. The default is effectively unlimited, being the largest value a
+PCRE2_SIZE variable can hold.
+.P
+There is a complete description of the PCRE2 native API in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcre2posix\fP
+.\"
+page.
diff --git a/dist2/doc/pcre2_set_newline.3 b/dist2/doc/pcre2_set_newline.3
index 8237500..0bccfc7 100644
--- a/dist2/doc/pcre2_set_newline.3
+++ b/dist2/doc/pcre2_set_newline.3
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_NEWLINE 3 "22 October 2014" "PCRE2 10.00"
+.TH PCRE2_SET_NEWLINE 3 "26 May 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -23,6 +23,7 @@
   PCRE2_NEWLINE_CRLF      CR followed by LF only
   PCRE2_NEWLINE_ANYCRLF   Any of the above
   PCRE2_NEWLINE_ANY       Any Unicode newline sequence
+  PCRE2_NEWLINE_NUL       The NUL character (binary zero)
 .sp
 The result is zero for success or PCRE2_ERROR_BADDATA if the second argument is
 invalid.
diff --git a/dist2/doc/pcre2_set_recursion_limit.3 b/dist2/doc/pcre2_set_recursion_limit.3
index ab1f3cd..26f4257 100644
--- a/dist2/doc/pcre2_set_recursion_limit.3
+++ b/dist2/doc/pcre2_set_recursion_limit.3
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_RECURSION_LIMIT 3 "24 October 2014" "PCRE2 10.00"
+.TH PCRE2_SET_RECURSION_LIMIT 3 "25 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -14,8 +14,8 @@
 .SH DESCRIPTION
 .rs
 .sp
-This function sets the recursion limit field in a match context. The result is
-always zero.
+This function is obsolete and should not be used in new code. Use
+\fBpcre2_set_depth_limit()\fP instead.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_set_recursion_memory_management.3 b/dist2/doc/pcre2_set_recursion_memory_management.3
index 9b5887a..12f175d 100644
--- a/dist2/doc/pcre2_set_recursion_memory_management.3
+++ b/dist2/doc/pcre2_set_recursion_memory_management.3
@@ -1,4 +1,4 @@
-.TH PCRE2_SET_RECURSION_MEMORY_MANAGEMENT 3 "24 October 2014" "PCRE2 10.00"
+.TH PCRE2_SET_RECURSION_MEMORY_MANAGEMENT 3 "25 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -16,13 +16,8 @@
 .SH DESCRIPTION
 .rs
 .sp
-This function sets the match context fields for custom memory management when
-PCRE2 is compiled to use the heap instead of the system stack for recursive
-function calls while matching. When PCRE2 is compiled to use the stack (the
-default) this function does nothing. The first argument is a match context, the
-second and third specify the memory allocation and freeing functions, and the
-final argument is an opaque value that is passed to them whenever they are
-called. The result of this function is always zero.
+From release 10.30 onwards, this function is obsolete and does nothing. The
+result is always zero.
 .P
 There is a complete description of the PCRE2 native API in the
 .\" HREF
diff --git a/dist2/doc/pcre2_substitute.3 b/dist2/doc/pcre2_substitute.3
index e69e0cc..7da668c 100644
--- a/dist2/doc/pcre2_substitute.3
+++ b/dist2/doc/pcre2_substitute.3
@@ -1,4 +1,4 @@
-.TH PCRE2_SUBSTITUTE 3 "12 December 2015" "PCRE2 10.21"
+.TH PCRE2_SUBSTITUTE 3 "04 April 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -35,24 +35,32 @@
   \fIoutputbuffer\fP  Points to the output buffer
   \fIoutlengthptr\fP  Points to the length of the output buffer
 .sp
-A match context is needed only if you want to:
+A match data block is needed only if you want to inspect the data from the
+match that is returned in that block. A match context is needed only if you
+want to:
 .sp
   Set up a callout function
-  Change the limit for calling the internal function \fImatch()\fP
-  Change the limit for calling \fImatch()\fP recursively
-  Set custom memory management when the heap is used for recursion
+  Set a matching offset limit
+  Change the backtracking match limit
+  Change the backtracking depth limit
+  Set custom memory management in the match context
 .sp
 The \fIlength\fP, \fIstartoffset\fP and \fIrlength\fP values are code
 units, not characters, as is the contents of the variable pointed at by
 \fIoutlengthptr\fP, which is updated to the actual length of the new string.
-The options are:
+The subject and replacement lengths can be given as PCRE2_ZERO_TERMINATED for
+zero-terminated strings. The options are:
 .sp
   PCRE2_ANCHORED             Match only at the first position
+  PCRE2_ENDANCHORED          Pattern can match only at end of subject
   PCRE2_NOTBOL               Subject is not the beginning of a line
   PCRE2_NOTEOL               Subject is not the end of a line
   PCRE2_NOTEMPTY             An empty string is not a valid match
+.\" JOIN
   PCRE2_NOTEMPTY_ATSTART     An empty string at the start of the
                               subject is not a valid match
+  PCRE2_NO_JIT               Do not use JIT matching
+.\" JOIN
   PCRE2_NO_UTF_CHECK         Do not check the subject or replacement
                               for UTF validity (only relevant if
                               PCRE2_UTF was set at compile time)
diff --git a/dist2/doc/pcre2api.3 b/dist2/doc/pcre2api.3
index db61ea0..786b314 100644
--- a/dist2/doc/pcre2api.3
+++ b/dist2/doc/pcre2api.3
@@ -1,11 +1,11 @@
-.TH PCRE2API 3 "17 June 2016" "PCRE2 10.22"
+.TH PCRE2API 3 "31 December 2017" "PCRE2 10.31"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .sp
 .B #include <pcre2.h>
 .sp
-PCRE2 is a new API for PCRE. This document contains a description of all its
-functions. See the
+PCRE2 is a new API for PCRE, starting at release 10.0. This document contains a
+description of all its native functions. See the
 .\" HREF
 \fBpcre2\fP
 .\"
@@ -90,6 +90,9 @@
 .B int pcre2_set_character_tables(pcre2_compile_context *\fIccontext\fP,
 .B "  const unsigned char *\fItables\fP);"
 .sp
+.B int pcre2_set_compile_extra_options(pcre2_compile_context *\fIccontext\fP,
+.B "  uint32_t \fIextra_options\fP);"
+.sp
 .B int pcre2_set_max_pattern_length(pcre2_compile_context *\fIccontext\fP,
 .B "  PCRE2_SIZE \fIvalue\fP);"
 .sp
@@ -120,19 +123,17 @@
 .B "  int (*\fIcallout_function\fP)(pcre2_callout_block *, void *),"
 .B "  void *\fIcallout_data\fP);"
 .sp
-.B int pcre2_set_match_limit(pcre2_match_context *\fImcontext\fP,
-.B "  uint32_t \fIvalue\fP);"
-.sp
 .B int pcre2_set_offset_limit(pcre2_match_context *\fImcontext\fP,
 .B "  PCRE2_SIZE \fIvalue\fP);"
 .sp
-.B int pcre2_set_recursion_limit(pcre2_match_context *\fImcontext\fP,
+.B int pcre2_set_heap_limit(pcre2_match_context *\fImcontext\fP,
 .B "  uint32_t \fIvalue\fP);"
 .sp
-.B int pcre2_set_recursion_memory_management(
-.B "  pcre2_match_context *\fImcontext\fP,"
-.B "  void *(*\fIprivate_malloc\fP)(PCRE2_SIZE, void *),"
-.B "  void (*\fIprivate_free\fP)(void *, void *), void *\fImemory_data\fP);"
+.B int pcre2_set_match_limit(pcre2_match_context *\fImcontext\fP,
+.B "  uint32_t \fIvalue\fP);"
+.sp
+.B int pcre2_set_depth_limit(pcre2_match_context *\fImcontext\fP,
+.B "  uint32_t \fIvalue\fP);"
 .fi
 .
 .
@@ -235,6 +236,8 @@
 .nf
 .B pcre2_code *pcre2_code_copy(const pcre2_code *\fIcode\fP);
 .sp
+.B pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *\fIcode\fP);
+.sp
 .B int pcre2_get_error_message(int \fIerrorcode\fP, PCRE2_UCHAR *\fIbuffer\fP,
 .B "  PCRE2_SIZE \fIbufflen\fP);"
 .sp
@@ -250,6 +253,60 @@
 .fi
 .
 .
+.SH "PCRE2 NATIVE API OBSOLETE FUNCTIONS"
+.rs
+.sp
+.nf
+.B int pcre2_set_recursion_limit(pcre2_match_context *\fImcontext\fP,
+.B "  uint32_t \fIvalue\fP);"
+.sp
+.B int pcre2_set_recursion_memory_management(
+.B "  pcre2_match_context *\fImcontext\fP,"
+.B "  void *(*\fIprivate_malloc\fP)(PCRE2_SIZE, void *),"
+.B "  void (*\fIprivate_free\fP)(void *, void *), void *\fImemory_data\fP);"
+.fi
+.sp
+These functions became obsolete at release 10.30 and are retained only for
+backward compatibility. They should not be used in new code. The first is
+replaced by \fBpcre2_set_depth_limit()\fP; the second is no longer needed and
+has no effect (it always returns zero).
+.
+.
+.SH "PCRE2 EXPERIMENTAL PATTERN CONVERSION FUNCTIONS"
+.rs
+.sp
+.nf
+.B pcre2_convert_context *pcre2_convert_context_create(
+.B "  pcre2_general_context *\fIgcontext\fP);"
+.sp
+.B pcre2_convert_context *pcre2_convert_context_copy(
+.B "  pcre2_convert_context *\fIcvcontext\fP);"
+.sp
+.B void pcre2_convert_context_free(pcre2_convert_context *\fIcvcontext\fP);
+.sp
+.B int pcre2_set_glob_escape(pcre2_convert_context *\fIcvcontext\fP,
+.B "  uint32_t \fIescape_char\fP);"
+.sp
+.B int pcre2_set_glob_separator(pcre2_convert_context *\fIcvcontext\fP,
+.B "  uint32_t \fIseparator_char\fP);"
+.sp
+.B int pcre2_pattern_convert(PCRE2_SPTR \fIpattern\fP, PCRE2_SIZE \fIlength\fP,
+.B "  uint32_t \fIoptions\fP, PCRE2_UCHAR **\fIbuffer\fP,"
+.B "  PCRE2_SIZE *\fIblength\fP, pcre2_convert_context *\fIcvcontext\fP);"
+.sp
+.B void pcre2_converted_pattern_free(PCRE2_UCHAR *\fIconverted_pattern\fP);
+.fi
+.sp
+These functions provide a way of converting non-PCRE2 patterns into
+patterns that can be processed by \fBpcre2_compile()\fP. This facility is
+experimental and may be changed in future releases. At present, "globs" and
+POSIX basic and extended patterns can be converted. Details are given in the
+.\" HREF
+\fBpcre2convert\fP
+.\"
+documentation.
+.
+.
 .SH "PCRE2 8-BIT, 16-BIT, AND 32-BIT LIBRARIES"
 .rs
 .sp
@@ -300,11 +357,11 @@
 processing any particular pattern to use only functions from a single library.
 For example, if you want to run a match using a pattern that was compiled with
 \fBpcre2_compile_16()\fP, you must do so with \fBpcre2_match_16()\fP, not
-\fBpcre2_match_8()\fP.
+\fBpcre2_match_8()\fP or \fBpcre2_match_32()\fP.
 .P
 In the function summaries above, and in the rest of this document and other
 PCRE2 documents, functions and data types are described using their generic
-names, without the 8, 16, or 32 suffix.
+names, without the _8, _16, or _32 suffix.
 .
 .
 .SH "PCRE2 API OVERVIEW"
@@ -313,23 +370,23 @@
 PCRE2 has its own native API, which is described in this document. There are
 also some wrapper functions for the 8-bit library that correspond to the
 POSIX regular expression API, but they do not give access to all the
-functionality. They are described in the
+functionality of PCRE2. They are described in the
 .\" HREF
 \fBpcre2posix\fP
 .\"
 documentation. Both these APIs define a set of C function calls.
 .P
 The native API C data types, function prototypes, option values, and error
-codes are defined in the header file \fBpcre2.h\fP, which contains definitions
-of PCRE2_MAJOR and PCRE2_MINOR, the major and minor release numbers for the
-library. Applications can use these to include support for different releases
-of PCRE2.
+codes are defined in the header file \fBpcre2.h\fP, which also contains
+definitions of PCRE2_MAJOR and PCRE2_MINOR, the major and minor release numbers
+for the library. Applications can use these to include support for different
+releases of PCRE2.
 .P
 In a Windows environment, if you want to statically link an application program
 against a non-dll PCRE2 library, you must define PCRE2_STATIC before including
 \fBpcre2.h\fP.
 .P
-The functions \fBpcre2_compile()\fP, and \fBpcre2_match()\fP are used for
+The functions \fBpcre2_compile()\fP and \fBpcre2_match()\fP are used for
 compiling and matching regular expressions in a Perl-compatible manner. A
 sample program that demonstrates the simplest way of using them is provided in
 the file called \fIpcre2demo.c\fP in the PCRE2 source distribution. A listing
@@ -343,10 +400,16 @@
 .\"
 documentation describes how to compile and run it.
 .P
-Just-in-time compiler support is an optional feature of PCRE2 that can be built
-in appropriate hardware environments. It greatly speeds up the matching
+The compiling and matching functions recognize various options that are passed
+as bits in an options argument. There are also some more complicated parameters
+such as custom memory management functions and resource limits that are passed
+in "contexts" (which are just memory blocks, described below). Simple
+applications do not need to make use of contexts.
+.P
+Just-in-time (JIT) compiler support is an optional feature of PCRE2 that can be
+built in appropriate hardware environments. It greatly speeds up the matching
 performance of many patterns. Programs can request that it be used if
-available, by calling \fBpcre2_jit_compile()\fP after a pattern has been
+available by calling \fBpcre2_jit_compile()\fP after a pattern has been
 successfully compiled by \fBpcre2_compile()\fP. This does nothing if JIT
 support is not available.
 .P
@@ -356,8 +419,8 @@
 .P
 JIT matching is automatically used by \fBpcre2_match()\fP if it is available,
 unless the PCRE2_NO_JIT option is set. There is also a direct interface for JIT
-matching, which gives improved performance. The JIT-specific functions are
-discussed in the
+matching, which gives improved performance at the expense of less sanity
+checking. The JIT-specific functions are discussed in the
 .\" HREF
 \fBpcre2jit\fP
 .\"
@@ -367,7 +430,7 @@
 Perl-compatible, is also provided. This uses a different algorithm for the
 matching. The alternative algorithm finds all possible matches (at a given
 point in the subject), and scans the subject just once (unless there are
-lookbehind assertions). However, this algorithm does not return captured
+lookaround assertions). However, this algorithm does not return captured
 substrings. A description of the two matching algorithms and their advantages
 and disadvantages is given in the
 .\" HREF
@@ -390,7 +453,7 @@
   \fBpcre2_substring_number_from_name()\fP
 .sp
 \fBpcre2_substring_free()\fP and \fBpcre2_substring_list_free()\fP are also
-provided, to free the memory used for extracted strings.
+provided, to free memory used for extracted strings.
 .P
 The function \fBpcre2_substitute()\fP can be called to match a pattern and
 return a copy of the subject string with substitutions for parts that were
@@ -482,8 +545,8 @@
 that is, the same compiled pattern can be used by more than one thread
 simultaneously. For example, an application can compile all its patterns at the
 start, before forking off multiple threads that use them. However, if the
-just-in-time optimization feature is being used, it needs separate memory stack
-areas for each thread. See the
+just-in-time (JIT) optimization feature is being used, it needs separate memory
+stack areas for each thread. See the
 .\" HREF
 \fBpcre2jit\fP
 .\"
@@ -509,8 +572,9 @@
 (perhaps waiting to see if the pattern is used often enough) similar logic is
 required. JIT compilation updates a pointer within the compiled code block, so
 a thread must gain unique write access to the pointer before calling
-\fBpcre2_jit_compile()\fP. Alternatively, \fBpcre2_code_copy()\fP can be used
-to obtain a private copy of the compiled code.
+\fBpcre2_jit_compile()\fP. Alternatively, \fBpcre2_code_copy()\fP or
+\fBpcre2_code_copy_with_tables()\fP can be used to obtain a private copy of the
+compiled code before calling the JIT compiler.
 .
 .
 .SS "Context blocks"
@@ -533,10 +597,10 @@
 .SS "Match blocks"
 .rs
 .sp
-The matching functions need a block of memory for working space and for storing
-the results of a match. This includes details of what was matched, as well as
-additional information such as the name of a (*MARK) setting. Each thread must
-provide its own copy of this memory.
+The matching functions need a block of memory for storing the results of a
+match. This includes details of what was matched, as well as additional
+information such as the name of a (*MARK) setting. Each thread must provide its
+own copy of this memory.
 .
 .
 .SH "PCRE2 CONTEXTS"
@@ -608,15 +672,16 @@
 .SS "The compile context"
 .rs
 .sp
-A compile context is required if you want to change the default values of any
-of the following compile-time parameters:
+A compile context is required if you want to provide an external function for
+stack checking during compilation or to change the default values of any of the
+following compile-time parameters:
 .sp
   What \eR matches (Unicode newlines or CR, LF, CRLF only)
   PCRE2's character tables
   The newline character sequence
   The compile time nested parentheses limit
   The maximum length of the pattern string
-  An external function for stack checking
+  The extra options bits (none set by default)
 .sp
 A compile context is also required if you are using custom memory management.
 If none of these apply, just pass NULL as the context argument of
@@ -659,15 +724,32 @@
 in the current locale.
 .sp
 .nf
+.B int pcre2_set_compile_extra_options(pcre2_compile_context *\fIccontext\fP,
+.B "  uint32_t \fIextra_options\fP);"
+.fi
+.sp
+As PCRE2 has developed, almost all the 32 option bits that are available in
+the \fIoptions\fP argument of \fBpcre2_compile()\fP have been used up. To avoid
+running out, the compile context contains a set of extra option bits which are
+used for some newer, assumed rarer, options. This function sets those bits. It
+always sets all the bits (either on or off). It does not modify any existing
+setting. The available options are defined in the section entitled "Extra
+compile options"
+.\" HTML <a href="#extracompileoptions">
+.\" </a>
+below.
+.\"
+.sp
+.nf
 .B int pcre2_set_max_pattern_length(pcre2_compile_context *\fIccontext\fP,
 .B "  PCRE2_SIZE \fIvalue\fP);"
 .fi
 .sp
-This sets a maximum length, in code units, for the pattern string that is to be
-compiled. If the pattern is longer, an error is generated. This facility is
-provided so that applications that accept patterns from external sources can
-limit their size. The default is the largest number that a PCRE2_SIZE variable
-can hold, which is effectively unlimited.
+This sets a maximum length, in code units, for any pattern string that is
+compiled with this context. If the pattern is longer, an error is generated.
+This facility is provided so that applications that accept patterns from
+external sources can limit their size. The default is the largest number that a
+PCRE2_SIZE variable can hold, which is effectively unlimited.
 .sp
 .nf
 .B int pcre2_set_newline(pcre2_compile_context *\fIccontext\fP,
@@ -677,14 +759,22 @@
 This specifies which characters or character sequences are to be recognized as
 newlines. The value must be one of PCRE2_NEWLINE_CR (carriage return only),
 PCRE2_NEWLINE_LF (linefeed only), PCRE2_NEWLINE_CRLF (the two-character
-sequence CR followed by LF), PCRE2_NEWLINE_ANYCRLF (any of the above), or
-PCRE2_NEWLINE_ANY (any Unicode newline sequence).
+sequence CR followed by LF), PCRE2_NEWLINE_ANYCRLF (any of the above),
+PCRE2_NEWLINE_ANY (any Unicode newline sequence), or PCRE2_NEWLINE_NUL (the
+NUL character, that is a binary zero).
 .P
-When a pattern is compiled with the PCRE2_EXTENDED option, the value of this
-parameter affects the recognition of white space and the end of internal
-comments starting with #. The value is saved with the compiled pattern for
-subsequent use by the JIT compiler and by the two interpreted matching
-functions, \fIpcre2_match()\fP and \fIpcre2_dfa_match()\fP.
+A pattern can override the value set in the compile context by starting with a
+sequence such as (*CRLF). See the
+.\" HREF
+\fBpcre2pattern\fP
+.\"
+page for details.
+.P
+When a pattern is compiled with the PCRE2_EXTENDED or PCRE2_EXTENDED_MORE
+option, the newline convention affects the recognition of white space and the
+end of internal comments starting with #. The value is saved with the compiled
+pattern for subsequent use by the JIT compiler and by the two interpreted
+matching functions, \fIpcre2_match()\fP and \fIpcre2_dfa_match()\fP.
 .sp
 .nf
 .B int pcre2_set_parens_nest_limit(pcre2_compile_context *\fIccontext\fP,
@@ -693,7 +783,8 @@
 .sp
 This parameter ajusts the limit, set when PCRE2 is built (default 250), on the
 depth of parenthesis nesting in a pattern. This limit stops rogue patterns
-using up too much system stack when being compiled.
+using up too much system stack when being compiled. The limit applies to
+parentheses of all kinds, not just capturing parentheses.
 .sp
 .nf
 .B int pcre2_set_compile_recursion_guard(pcre2_compile_context *\fIccontext\fP,
@@ -703,10 +794,10 @@
 There is at least one application that runs PCRE2 in threads with very limited
 system stack, where running out of stack is to be avoided at all costs. The
 parenthesis limit above cannot take account of how much stack is actually
-available. For a finer control, you can supply a function that is called
-whenever \fBpcre2_compile()\fP starts to compile a parenthesized part of a
-pattern. This function can check the actual stack size (or anything else that
-it wants to, of course).
+available during compilation. For a finer control, you can supply a function
+that is called whenever \fBpcre2_compile()\fP starts to compile a parenthesized
+part of a pattern. This function can check the actual stack size (or anything
+else that it wants to, of course).
 .P
 The first argument to the callout function gives the current depth of
 nesting, and the second is user data that is set up by the last argument of
@@ -718,15 +809,15 @@
 .SS "The match context"
 .rs
 .sp
-A match context is required if you want to change the default values of any
-of the following match-time parameters:
+A match context is required if you want to:
 .sp
-  A callout function
-  The offset limit for matching an unanchored pattern
-  The limit for calling \fBmatch()\fP (see below)
-  The limit for calling \fBmatch()\fP recursively
+  Set up a callout function
+  Set an offset limit for matching an unanchored pattern
+  Change the limit on the amount of heap used when matching
+  Change the backtracking match limit
+  Change the backtracking depth limit
+  Set custom memory management specifically for the match
 .sp
-A match context is also required if you are using custom memory management.
 If none of these apply, just pass NULL as the context argument of
 \fBpcre2_match()\fP, \fBpcre2_dfa_match()\fP, or \fBpcre2_jit_match()\fP.
 .P
@@ -752,7 +843,7 @@
 .B "  void *\fIcallout_data\fP);"
 .fi
 .sp
-This sets up a "callout" function, which PCRE2 will call at specified points
+This sets up a "callout" function for PCRE2 to call at specified points
 during a matching operation. Details are given in the
 .\" HREF
 \fBpcre2callout\fP
@@ -768,22 +859,61 @@
 advance in the subject string. The default value is PCRE2_UNSET. The
 \fBpcre2_match()\fP and \fBpcre2_dfa_match()\fP functions return
 PCRE2_ERROR_NOMATCH if a match with a starting point before or at the given
-offset is not found. For example, if the pattern /abc/ is matched against
-"123abc" with an offset limit less than 3, the result is PCRE2_ERROR_NO_MATCH.
-A match can never be found if the \fIstartoffset\fP argument of
-\fBpcre2_match()\fP or \fBpcre2_dfa_match()\fP is greater than the offset
-limit.
+offset is not found. The \fBpcre2_substitute()\fP function makes no more
+substitutions.
 .P
-When using this facility, you must set PCRE2_USE_OFFSET_LIMIT when calling
-\fBpcre2_compile()\fP so that when JIT is in use, different code can be
+For example, if the pattern /abc/ is matched against "123abc" with an offset
+limit less than 3, the result is PCRE2_ERROR_NO_MATCH. A match can never be
+found if the \fIstartoffset\fP argument of \fBpcre2_match()\fP,
+\fBpcre2_dfa_match()\fP, or \fBpcre2_substitute()\fP is greater than the offset
+limit set in the match context.
+.P
+When using this facility, you must set the PCRE2_USE_OFFSET_LIMIT option when
+calling \fBpcre2_compile()\fP so that when JIT is in use, different code can be
 compiled. If a match is started with a non-default match limit when
 PCRE2_USE_OFFSET_LIMIT is not set, an error is generated.
 .P
 The offset limit facility can be used to track progress when searching large
-subject strings. See also the PCRE2_FIRSTLINE option, which requires a match to
-start within the first line of the subject. If this is set with an offset
-limit, a match must occur in the first line and also within the offset limit.
-In other words, whichever limit comes first is used.
+subject strings or to limit the extent of global substitutions. See also the
+PCRE2_FIRSTLINE option, which requires a match to start before or at the first
+newline that follows the start of matching in the subject. If this is set with
+an offset limit, a match must occur in the first line and also within the
+offset limit. In other words, whichever limit comes first is used.
+.sp
+.nf
+.B int pcre2_set_heap_limit(pcre2_match_context *\fImcontext\fP,
+.B "  uint32_t \fIvalue\fP);"
+.fi
+.sp
+The \fIheap_limit\fP parameter specifies, in units of kilobytes, the maximum
+amount of heap memory that \fBpcre2_match()\fP may use to hold backtracking
+information when running an interpretive match. This limit does not apply to
+matching with the JIT optimization, which has its own memory control
+arrangements (see the
+.\" HREF
+\fBpcre2jit\fP
+.\"
+documentation for more details), nor does it apply to \fBpcre2_dfa_match()\fP.
+If the limit is reached, the negative error code PCRE2_ERROR_HEAPLIMIT is
+returned. The default limit is set when PCRE2 is built; the default default is
+very large and is essentially "unlimited".
+.P
+A value for the heap limit may also be supplied by an item at the start of a
+pattern of the form
+.sp
+  (*LIMIT_HEAP=ddd)
+.sp
+where ddd is a decimal number. However, such a setting is ignored unless ddd is
+less than the limit set by the caller of \fBpcre2_match()\fP or, if no such
+limit is set, less than the default.
+.P
+The \fBpcre2_match()\fP function starts out using a 20K vector on the system
+stack for recording backtracking points. The more nested backtracking points
+there are (that is, the deeper the search tree), the more memory is needed.
+Heap memory is used only if the initial vector is too small. If the heap limit
+is set to a value less than 21 (in particular, zero) no heap memory will be
+used. In this case, only patterns that do not have a lot of nested backtracking
+can be successfully processed.
 .sp
 .nf
 .B int pcre2_set_match_limit(pcre2_match_context *\fImcontext\fP,
@@ -791,17 +921,17 @@
 .fi
 .sp
 The \fImatch_limit\fP parameter provides a means of preventing PCRE2 from using
-up too many resources when processing patterns that are not going to match, but
-which have a very large number of possibilities in their search trees. The
-classic example is a pattern that uses nested unlimited repeats.
+up too many computing resources when processing patterns that are not going to
+match, but which have a very large number of possibilities in their search
+trees. The classic example is a pattern that uses nested unlimited repeats.
 .P
-Internally, \fBpcre2_match()\fP uses a function called \fBmatch()\fP, which it
-calls repeatedly (sometimes recursively). The limit set by \fImatch_limit\fP is
-imposed on the number of times this function is called during a match, which
-has the effect of limiting the amount of backtracking that can take place. For
+There is an internal counter in \fBpcre2_match()\fP that is incremented each
+time round its main matching loop. If this value reaches the match limit,
+\fBpcre2_match()\fP returns the negative value PCRE2_ERROR_MATCHLIMIT. This has
+the effect of limiting the amount of backtracking that can take place. For
 patterns that are not anchored, the count restarts from zero for each position
-in the subject string. This limit is not relevant to \fBpcre2_dfa_match()\fP,
-which ignores it.
+in the subject string. This limit also applies to \fBpcre2_dfa_match()\fP,
+though the counting is done in a different way.
 .P
 When \fBpcre2_match()\fP is called with a pattern that was successfully
 processed by \fBpcre2_jit_compile()\fP, the way in which matching is executed
@@ -811,75 +941,49 @@
 matching can continue.
 .P
 The default value for the limit can be set when PCRE2 is built; the default
-default is 10 million, which handles all but the most extreme cases. If the
-limit is exceeded, \fBpcre2_match()\fP returns PCRE2_ERROR_MATCHLIMIT. A value
+default is 10 million, which handles all but the most extreme cases. A value
 for the match limit may also be supplied by an item at the start of a pattern
 of the form
 .sp
   (*LIMIT_MATCH=ddd)
 .sp
 where ddd is a decimal number. However, such a setting is ignored unless ddd is
-less than the limit set by the caller of \fBpcre2_match()\fP or, if no such
-limit is set, less than the default.
+less than the limit set by the caller of \fBpcre2_match()\fP or
+\fBpcre2_dfa_match()\fP or, if no such limit is set, less than the default.
 .sp
 .nf
-.B int pcre2_set_recursion_limit(pcre2_match_context *\fImcontext\fP,
+.B int pcre2_set_depth_limit(pcre2_match_context *\fImcontext\fP,
 .B "  uint32_t \fIvalue\fP);"
 .fi
 .sp
-The \fIrecursion_limit\fP parameter is similar to \fImatch_limit\fP, but
-instead of limiting the total number of times that \fBmatch()\fP is called, it
-limits the depth of recursion. The recursion depth is a smaller number than the
-total number of calls, because not all calls to \fBmatch()\fP are recursive.
-This limit is of use only if it is set smaller than \fImatch_limit\fP.
+This parameter limits the depth of nested backtracking in \fBpcre2_match()\fP.
+Each time a nested backtracking point is passed, a new memory "frame" is used
+to remember the state of matching at that point. Thus, this parameter
+indirectly limits the amount of memory that is used in a match. However,
+because the size of each memory "frame" depends on the number of capturing
+parentheses, the actual memory limit varies from pattern to pattern. This limit
+was more useful in versions before 10.30, where function recursion was used for
+backtracking.
 .P
-Limiting the recursion depth limits the amount of system stack that can be
-used, or, when PCRE2 has been compiled to use memory on the heap instead of the
-stack, the amount of heap memory that can be used. This limit is not relevant,
-and is ignored, when matching is done using JIT compiled code or by the
-\fBpcre2_dfa_match()\fP function.
+The depth limit is not relevant, and is ignored, when matching is done using
+JIT compiled code. However, it is supported by \fBpcre2_dfa_match()\fP, which
+uses it to limit the depth of internal recursive function calls that implement
+atomic groups, lookaround assertions, and pattern recursions. This is,
+therefore, an indirect limit on the amount of system stack that is used. A
+recursive pattern such as /(.)(?1)/, when matched to a very long string using
+\fBpcre2_dfa_match()\fP, can use a great deal of stack.
 .P
-The default value for \fIrecursion_limit\fP can be set when PCRE2 is built; the
-default default is the same value as the default for \fImatch_limit\fP. If the
-limit is exceeded, \fBpcre2_match()\fP returns PCRE2_ERROR_RECURSIONLIMIT. A
-value for the recursion limit may also be supplied by an item at the start of a
-pattern of the form
+The default value for the depth limit can be set when PCRE2 is built; the
+default default is the same value as the default for the match limit. If the
+limit is exceeded, \fBpcre2_match()\fP or \fBpcre2_dfa_match()\fP returns
+PCRE2_ERROR_DEPTHLIMIT. A value for the depth limit may also be supplied by an
+item at the start of a pattern of the form
 .sp
-  (*LIMIT_RECURSION=ddd)
+  (*LIMIT_DEPTH=ddd)
 .sp
 where ddd is a decimal number. However, such a setting is ignored unless ddd is
-less than the limit set by the caller of \fBpcre2_match()\fP or, if no such
-limit is set, less than the default.
-.sp
-.nf
-.B int pcre2_set_recursion_memory_management(
-.B "  pcre2_match_context *\fImcontext\fP,"
-.B "  void *(*\fIprivate_malloc\fP)(PCRE2_SIZE, void *),"
-.B "  void (*\fIprivate_free\fP)(void *, void *), void *\fImemory_data\fP);"
-.fi
-.sp
-This function sets up two additional custom memory management functions for use
-by \fBpcre2_match()\fP when PCRE2 is compiled to use the heap for remembering
-backtracking data, instead of recursive function calls that use the system
-stack. There is a discussion about PCRE2's stack usage in the
-.\" HREF
-\fBpcre2stack\fP
-.\"
-documentation. See the
-.\" HREF
-\fBpcre2build\fP
-.\"
-documentation for details of how to build PCRE2.
-.P
-Using the heap for recursion is a non-standard way of building PCRE2, for use
-in environments that have limited stacks. Because of the greater use of memory
-management, \fBpcre2_match()\fP runs more slowly. Functions that are different
-to the general custom memory functions are provided so that special-purpose
-external code can be used for this case, because the memory blocks are all the
-same size. The blocks are retained by \fBpcre2_match()\fP until it is about to
-exit so that they can be re-used when possible during the match. In the absence
-of these functions, the normal custom memory management functions are used, if
-supplied, otherwise the system functions.
+less than the limit set by the caller of \fBpcre2_match()\fP or
+\fBpcre2_dfa_match()\fP or, if no such limit is set, less than the default.
 .
 .
 .SH "CHECKING BUILD-TIME OPTIONS"
@@ -915,6 +1019,25 @@
 value of PCRE2_BSR_ANYCRLF means that \eR matches only CR, LF, or CRLF. The
 default can be overridden when a pattern is compiled.
 .sp
+  PCRE2_CONFIG_COMPILED_WIDTHS
+.sp
+The output is a uint32_t integer whose lower bits indicate which code unit
+widths were selected when PCRE2 was built. The 1-bit indicates 8-bit support,
+and the 2-bit and 4-bit indicate 16-bit and 32-bit support, respectively.
+.sp
+  PCRE2_CONFIG_DEPTHLIMIT
+.sp
+The output is a uint32_t integer that gives the default limit for the depth of
+nested backtracking in \fBpcre2_match()\fP or the depth of nested recursions
+and lookarounds in \fBpcre2_dfa_match()\fP. Further details are given with
+\fBpcre2_set_depth_limit()\fP above.
+.sp
+  PCRE2_CONFIG_HEAPLIMIT
+.sp
+The output is a uint32_t integer that gives, in kilobytes, the default limit
+for the amount of heap memory used by \fBpcre2_match()\fP. Further details are
+given with \fBpcre2_set_heap_limit()\fP above.
+.sp
   PCRE2_CONFIG_JIT
 .sp
 The output is a uint32_t integer that is set to one if support for just-in-time
@@ -948,9 +1071,9 @@
 .sp
   PCRE2_CONFIG_MATCHLIMIT
 .sp
-The output is a uint32_t integer that gives the default limit for the number of
-internal matching function calls in a \fBpcre2_match()\fP execution. Further
-details are given with \fBpcre2_match()\fP below.
+The output is a uint32_t integer that gives the default match limit for
+\fBpcre2_match()\fP. Further details are given with
+\fBpcre2_set_match_limit()\fP above.
 .sp
   PCRE2_CONFIG_NEWLINE
 .sp
@@ -962,10 +1085,16 @@
   PCRE2_NEWLINE_CRLF     Carriage return, linefeed (CRLF)
   PCRE2_NEWLINE_ANY      Any Unicode line ending
   PCRE2_NEWLINE_ANYCRLF  Any of CR, LF, or CRLF
+  PCRE2_NEWLINE_NUL      The NUL character (binary zero)
 .sp
 The default should normally correspond to the standard sequence for your
 operating system.
 .sp
+  PCRE2_CONFIG_NEVER_BACKSLASH_C
+.sp
+The output is a uint32_t integer that is set to one if the use of \eC was
+permanently disabled when PCRE2 was built; otherwise it is set to zero.
+.sp
   PCRE2_CONFIG_PARENSLIMIT
 .sp
 The output is a uint32_t integer that gives the maximum depth of nesting
@@ -975,19 +1104,10 @@
 stack that may already be used by the calling application. For finer control
 over compilation stack usage, see \fBpcre2_set_compile_recursion_guard()\fP.
 .sp
-  PCRE2_CONFIG_RECURSIONLIMIT
-.sp
-The output is a uint32_t integer that gives the default limit for the depth of
-recursion when calling the internal matching function in a \fBpcre2_match()\fP
-execution. Further details are given with \fBpcre2_match()\fP below.
-.sp
   PCRE2_CONFIG_STACKRECURSE
 .sp
-The output is a uint32_t integer that is set to one if internal recursion when
-running \fBpcre2_match()\fP is implemented by recursive function calls that use
-the system stack to remember their state. This is the usual way that PCRE2 is
-compiled. The output is zero if PCRE2 was compiled to use blocks of data on the
-heap instead of recursive function calls.
+This parameter is obsolete and should not be used in new code. The output is a
+uint32_t integer that is always set to zero.
 .sp
   PCRE2_CONFIG_UNICODE_VERSION
 .sp
@@ -1006,7 +1126,7 @@
 .sp
   PCRE2_CONFIG_VERSION
 .sp
-The \fIwhere\fP argument should point to a buffer that is at least 12 code
+The \fIwhere\fP argument should point to a buffer that is at least 24 code
 units long. (The exact length required can be found by calling
 \fBpcre2_config()\fP with \fBwhere\fP set to NULL.) The buffer is filled with
 the PCRE2 version string, zero-terminated. The number of code units used is
@@ -1026,11 +1146,13 @@
 .B void pcre2_code_free(pcre2_code *\fIcode\fP);
 .sp
 .B pcre2_code *pcre2_code_copy(const pcre2_code *\fIcode\fP);
+.sp
+.B pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *\fIcode\fP);
 .fi
 .P
 The \fBpcre2_compile()\fP function compiles a pattern into an internal form.
-The pattern is defined by a pointer to a string of code units and a length. If
-the pattern is zero-terminated, the length can be specified as
+The pattern is defined by a pointer to a string of code units and a length (in
+code units). If the pattern is zero-terminated, the length can be specified as
 PCRE2_ZERO_TERMINATED. The function returns a pointer to a block of memory that
 contains the compiled pattern and related data, or NULL if an error occurred.
 .P
@@ -1048,9 +1170,24 @@
 .\"
 the JIT information cannot be copied (because it is position-dependent).
 The new copy can initially be used only for non-JIT matching, though it can be
-passed to \fBpcre2_jit_compile()\fP if required. The \fBpcre2_code_copy()\fP
-function provides a way for individual threads in a multithreaded application
-to acquire a private copy of shared compiled code.
+passed to \fBpcre2_jit_compile()\fP if required.
+.P
+The \fBpcre2_code_copy()\fP function provides a way for individual threads in a
+multithreaded application to acquire a private copy of shared compiled code.
+However, it does not make a copy of the character tables used by the compiled
+pattern; the new pattern code points to the same tables as the original code.
+(See
+.\" HTML <a href="#jitcompiling">
+.\" </a>
+"Locale Support"
+.\"
+below for details of these character tables.) In many applications the same
+tables are used throughout, so this behaviour is appropriate. Nevertheless,
+there are occasions when a copy of a compiled pattern and the relevant tables
+are needed. The \fBpcre2_code_copy_with_tables()\fP provides this facility.
+Copies of both the code and the tables are made, with the new code pointing to
+the new tables. The memory for the new tables is automatically freed when
+\fBpcre2_code_free()\fP is called for the new copy of the compiled code.
 .P
 NOTE: When one of the matching functions is called, pointers to the compiled
 pattern and the subject string are set in the match data block so that they can
@@ -1076,8 +1213,8 @@
 .P
 For those options that can be different in different parts of the pattern, the
 contents of the \fIoptions\fP argument specifies their settings at the start of
-compilation. The PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK options can be set at
-the time of matching as well as at compile time.
+compilation. The PCRE2_ANCHORED, PCRE2_ENDANCHORED, and PCRE2_NO_UTF_CHECK
+options can be set at the time of matching as well as at compile time.
 .P
 Other, less frequently required compile-time parameters (for example, the
 newline setting) can be provided in a compile context (as described
@@ -1093,16 +1230,30 @@
 error has occurred. The values are not defined when compilation is successful
 and \fBpcre2_compile()\fP returns a non-NULL value.
 .P
-The \fBpcre2_get_error_message()\fP function (see "Obtaining a textual error
+There are nearly 100 positive error codes that \fBpcre2_compile()\fP may return
+if it finds an error in the pattern. There are also some negative error codes
+that are used for invalid UTF strings. These are the same as given by
+\fBpcre2_match()\fP and \fBpcre2_dfa_match()\fP, and are described in the
+.\" HREF
+\fBpcre2unicode\fP
+.\"
+page. There is no separate documentation for the positive error codes, because
+the textual error messages that are obtained by calling the
+\fBpcre2_get_error_message()\fP function (see "Obtaining a textual error
 message"
 .\" HTML <a href="#geterrormessage">
 .\" </a>
 below)
 .\"
-provides a textual message for each error code. Compilation errors have
-positive error codes; UTF formatting error codes are negative. For an invalid
-UTF-8 or UTF-16 string, the offset is that of the first code unit of the
-failing character.
+should be self-explanatory. Macro names starting with PCRE2_ERROR_ are defined
+for both positive and negative error codes in \fBpcre2.h\fP.
+.P
+The value returned in \fIerroroffset\fP is an indication of where in the
+pattern the error occurred. It is not necessarily the furthest point in the
+pattern that was read. For example, after the error "lookbehind assertion is
+not fixed length", the error offset points to the start of the failing
+assertion. For an invalid UTF-8 or UTF-16 string, the offset is that of the
+first code unit of the failing character.
 .P
 Some errors are not detected until the whole pattern has been scanned; in these
 cases, the offset passed back is the length of the pattern. Note that the
@@ -1178,13 +1329,15 @@
 option is set, normal backslash processing is applied to verb names and only an
 unescaped closing parenthesis terminates the name. A closing parenthesis can be
 included in a name either as \e) or between \eQ and \eE. If the PCRE2_EXTENDED
-option is set, unescaped whitespace in verb names is skipped and #-comments are
-recognized, exactly as in the rest of the pattern.
+or PCRE2_EXTENDED_MORE option is set, unescaped whitespace in verb names is
+skipped and #-comments are recognized in this mode, exactly as in the rest of
+the pattern.
 .sp
   PCRE2_AUTO_CALLOUT
 .sp
 If this bit is set, \fBpcre2_compile()\fP automatically inserts callout items,
-all with number 255, before each pattern item. For discussion of the callout
+all with number 255, before each pattern item, except immediately before or
+after an explicit callout in the pattern. For discussion of the callout
 facility, see the
 .\" HREF
 \fBpcre2callout\fP
@@ -1195,7 +1348,13 @@
 .sp
 If this bit is set, letters in the pattern match both upper and lower case
 letters in the subject. It is equivalent to Perl's /i option, and it can be
-changed within a pattern by a (?i) option setting.
+changed within a pattern by a (?i) option setting. If PCRE2_UTF is set, Unicode
+properties are used for all characters with more than one other case, and for
+all characters whose code points are greater than U+007f. For lower valued
+characters with only one other case, a lookup table is used for speed. When
+PCRE2_UTF is not set, a lookup table is used for all code points less than 256,
+and higher code points (available only in 16-bit or 32-bit mode) are treated as
+not having another case.
 .sp
   PCRE2_DOLLAR_ENDONLY
 .sp
@@ -1227,6 +1386,29 @@
 .\"
 documentation.
 .sp
+  PCRE2_ENDANCHORED
+.sp
+If this bit is set, the end of any pattern match must be right at the end of
+the string being searched (the "subject string"). If the pattern match
+succeeds by reaching (*ACCEPT), but does not reach the end of the subject, the
+match fails at the current starting point. For unanchored patterns, a new match
+is then tried at the next starting point. However, if the match succeeds by
+reaching the end of the pattern, but not the end of the subject, backtracking
+occurs and an alternative match may be found. Consider these two patterns:
+.sp
+  .(*ACCEPT)|..
+  .|..
+.sp
+If matched against "abc" with PCRE2_ENDANCHORED set, the first matches "c"
+whereas the second matches "bc". The effect of PCRE2_ENDANCHORED can also be
+achieved by appropriate constructs in the pattern itself, which is the only way
+to do it in Perl.
+.P
+For DFA matching with \fBpcre2_dfa_match()\fP, PCRE2_ENDANCHORED applies only
+to the first (that is, the longest) matched string. Other parallel matches,
+which are necessarily substrings of the first one, must obviously end before
+the end of the subject.
+.sp
   PCRE2_EXTENDED
 .sp
 If this bit is set, most white space characters in the pattern are totally
@@ -1254,14 +1436,39 @@
 in the \fBpcre2pattern\fP documentation. A default is defined when PCRE2 is
 built.
 .sp
+  PCRE2_EXTENDED_MORE
+.sp
+This option has the effect of PCRE2_EXTENDED, but, in addition, unescaped space
+and horizontal tab characters are ignored inside a character class.
+PCRE2_EXTENDED_MORE is equivalent to Perl's 5.26 /xx option, and it can be
+changed within a pattern by a (?xx) option setting.
+.sp
   PCRE2_FIRSTLINE
 .sp
-If this option is set, an unanchored pattern is required to match before or at
-the first newline in the subject string, though the matched text may continue
-over the newline. See also PCRE2_USE_OFFSET_LIMIT, which provides a more
-general limiting facility. If PCRE2_FIRSTLINE is set with an offset limit, a
-match must occur in the first line and also within the offset limit. In other
-words, whichever limit comes first is used.
+If this option is set, the start of an unanchored pattern match must be before
+or at the first newline in the subject string following the start of matching,
+though the matched text may continue over the newline. If \fIstartoffset\fP is
+non-zero, the limiting newline is not necessarily the first newline in the
+subject. For example, if the subject string is "abc\enxyz" (where \en
+represents a single-character newline) a pattern match for "yz" succeeds with
+PCRE2_FIRSTLINE if \fIstartoffset\fP is greater than 3. See also
+PCRE2_USE_OFFSET_LIMIT, which provides a more general limiting facility. If
+PCRE2_FIRSTLINE is set with an offset limit, a match must occur in the first
+line and also within the offset limit. In other words, whichever limit comes
+first is used.
+.sp
+  PCRE2_LITERAL
+.sp
+If this option is set, all meta-characters in the pattern are disabled, and it
+is treated as a literal string. Matching literal strings with a regular
+expression engine is not the most efficient way of doing it. If you are doing a
+lot of literal matching and are worried about efficiency, you should consider
+using other approaches. The only other main options that are allowed with
+PCRE2_LITERAL are: PCRE2_ANCHORED, PCRE2_ENDANCHORED, PCRE2_AUTO_CALLOUT,
+PCRE2_CASELESS, PCRE2_FIRSTLINE, PCRE2_NO_START_OPTIMIZE, PCRE2_NO_UTF_CHECK,
+PCRE2_UTF, and PCRE2_USE_OFFSET_LIMIT. The extra options PCRE2_EXTRA_MATCH_LINE
+and PCRE2_EXTRA_MATCH_WORD are also supported. Any other options cause an
+error.
 .sp
   PCRE2_MATCH_UNSET_BACKREF
 .sp
@@ -1325,8 +1532,8 @@
 If this option is set, it disables the use of numbered capturing parentheses in
 the pattern. Any opening parenthesis that is not followed by ? behaves as if it
 were followed by ?: but named parentheses can still be used for capturing (and
-they acquire numbers in the usual way). There is no equivalent of this option
-in Perl. Note that, if this option is set, references to capturing groups (back
+they acquire numbers in the usual way). This is the same as Perl's /n option.
+Note that, when this option is set, references to capturing groups (back
 references or recursion/subroutine calls) may only refer to named groups,
 though the reference can be by name or by number.
 .sp
@@ -1361,8 +1568,8 @@
 .P
 There are a number of optimizations that may occur at the start of a match, in
 order to speed up the process. For example, if it is known that an unanchored
-match must start with a specific character, the matching code searches the
-subject for that character, and fails immediately if it cannot find it, without
+match must start with a specific code unit value, the matching code searches
+the subject for that value, and fails immediately if it cannot find it, without
 actually running the main matching function. This means that a special item
 such as (*COMMIT) at the start of a pattern is not considered until after a
 suitable starting point for the match has been found. Also, when callouts or
@@ -1389,9 +1596,10 @@
 match is run with PCRE2_NO_START_OPTIMIZE set, the initial scan along the
 subject string does not happen. The first match attempt is run starting from
 "D" and when this fails, (*COMMIT) prevents any further matches being tried, so
-the overall result is "no match". There are also other start-up optimizations.
-For example, a minimum length for the subject may be recorded. Consider the
-pattern
+the overall result is "no match".
+.P
+There are also other start-up optimizations. For example, a minimum length for
+the subject may be recorded. Consider the pattern
 .sp
   (*MARK:A)(X|Y)
 .sp
@@ -1423,16 +1631,30 @@
 .\" HREF
 \fBpcre2unicode\fP
 .\"
-document.
-If an invalid UTF sequence is found, \fBpcre2_compile()\fP returns a negative
-error code.
+document. If an invalid UTF sequence is found, \fBpcre2_compile()\fP returns a
+negative error code.
 .P
-If you know that your pattern is valid, and you want to skip this check for
-performance reasons, you can set the PCRE2_NO_UTF_CHECK option. When it is set,
-the effect of passing an invalid UTF string as a pattern is undefined. It may
-cause your program to crash or loop. Note that this option can also be passed
-to \fBpcre2_match()\fP and \fBpcre_dfa_match()\fP, to suppress validity
-checking of the subject string.
+If you know that your pattern is a valid UTF string, and you want to skip this
+check for performance reasons, you can set the PCRE2_NO_UTF_CHECK option. When
+it is set, the effect of passing an invalid UTF string as a pattern is
+undefined. It may cause your program to crash or loop.
+.P
+Note that this option can also be passed to \fBpcre2_match()\fP and
+\fBpcre_dfa_match()\fP, to suppress UTF validity checking of the subject
+string.
+.P
+Note also that setting PCRE2_NO_UTF_CHECK at compile time does not disable the
+error that is given if an escape sequence for an invalid Unicode code point is
+encountered in the pattern. In particular, the so-called "surrogate" code
+points (0xd800 to 0xdfff) are invalid. If you want to allow escape sequences
+such as \ex{d800} you can set the PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES extra
+option, as described in the section entitled "Extra compile options"
+.\" HTML <a href="#extracompileoptions">
+.\" </a>
+below.
+.\"
+However, this is possible only in UTF-8 and UTF-32 modes, because these values
+are not representable in UTF-16.
 .sp
   PCRE2_UCP
 .sp
@@ -1450,7 +1672,7 @@
 .\"
 page. If you set PCRE2_UCP, matching one of the items it affects takes much
 longer. The option is available only if PCRE2 has been compiled with Unicode
-support.
+support (which is the default).
 .sp
   PCRE2_UNGREEDY
 .sp
@@ -1478,32 +1700,78 @@
 that are subsequently processed as strings of UTF characters instead of
 single-code-unit strings. It is available when PCRE2 is built to include
 Unicode support (which is the default). If Unicode support is not available,
-the use of this option provokes an error. Details of how this option changes
-the behaviour of PCRE2 are given in the
+the use of this option provokes an error. Details of how PCRE2_UTF changes the
+behaviour of PCRE2 are given in the
 .\" HREF
 \fBpcre2unicode\fP
 .\"
 page.
 .
 .
-.SH "COMPILATION ERROR CODES"
+.\" HTML <a name="extracompileoptions"></a>
+.SS "Extra compile options"
 .rs
 .sp
-There are over 80 positive error codes that \fBpcre2_compile()\fP may return
-(via \fIerrorcode\fP) if it finds an error in the pattern. There are also some
-negative error codes that are used for invalid UTF strings. These are the same
-as given by \fBpcre2_match()\fP and \fBpcre2_dfa_match()\fP, and are described
-in the
-.\" HREF
-\fBpcre2unicode\fP
-.\"
-page. The \fBpcre2_get_error_message()\fP function (see "Obtaining a textual
-error message"
-.\" HTML <a href="#geterrormessage">
-.\" </a>
-below)
-.\"
-can be called to obtain a textual error message from any error code.
+Unlike the main compile-time options, the extra options are not saved with the
+compiled pattern. The option bits that can be set in a compile context by
+calling the \fBpcre2_set_compile_extra_options()\fP function are as follows:
+.sp
+  PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES
+.sp
+This option applies when compiling a pattern in UTF-8 or UTF-32 mode. It is
+forbidden in UTF-16 mode, and ignored in non-UTF modes. Unicode "surrogate"
+code points in the range 0xd800 to 0xdfff are used in pairs in UTF-16 to encode
+code points with values in the range 0x10000 to 0x10ffff. The surrogates cannot
+therefore be represented in UTF-16. They can be represented in UTF-8 and
+UTF-32, but are defined as invalid code points, and cause errors if encountered
+in a UTF-8 or UTF-32 string that is being checked for validity by PCRE2.
+.P
+These values also cause errors if encountered in escape sequences such as
+\ex{d912} within a pattern. However, it seems that some applications, when
+using PCRE2 to check for unwanted characters in UTF-8 strings, explicitly test
+for the surrogates using escape sequences. The PCRE2_NO_UTF_CHECK option does
+not disable the error that occurs, because it applies only to the testing of
+input strings for UTF validity.
+.P
+If the extra option PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is set, surrogate code
+point values in UTF-8 and UTF-32 patterns no longer provoke errors and are
+incorporated in the compiled pattern. However, they can only match subject
+characters if the matching function is called with PCRE2_NO_UTF_CHECK set.
+.sp
+  PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
+.sp
+This is a dangerous option. Use with care. By default, an unrecognized escape
+such as \ej or a malformed one such as \ex{2z} causes a compile-time error when
+detected by \fBpcre2_compile()\fP. Perl is somewhat inconsistent in handling
+such items: for example, \ej is treated as a literal "j", and non-hexadecimal
+digits in \ex{} are just ignored, though warnings are given in both cases if
+Perl's warning switch is enabled. However, a malformed octal number after \eo{
+always causes an error in Perl.
+.P
+If the PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL extra option is passed to
+\fBpcre2_compile()\fP, all unrecognized or erroneous escape sequences are
+treated as single-character escapes. For example, \ej is a literal "j" and
+\ex{2z} is treated as the literal string "x{2z}". Setting this option means
+that typos in patterns may go undetected and have unexpected results. This is a
+dangerous option. Use with care.
+.sp
+  PCRE2_EXTRA_MATCH_LINE
+.sp
+This option is provided for use by the \fB-x\fP option of \fBpcre2grep\fP. It
+causes the pattern only to match complete lines. This is achieved by
+automatically inserting the code for "^(?:" at the start of the compiled
+pattern and ")$" at the end. Thus, when PCRE2_MULTILINE is set, the matched
+line may be in the middle of the subject string. This option can be used with
+PCRE2_LITERAL.
+.sp
+  PCRE2_EXTRA_MATCH_WORD
+.sp
+This option is provided for use by the \fB-w\fP option of \fBpcre2grep\fP. It
+causes the pattern only to match strings that have a word boundary at the start
+and the end. This is achieved by automatically inserting the code for "\eb(?:"
+at the start of the compiled pattern and ")\eb" at the end. The option may be
+used with PCRE2_LITERAL. However, it is ignored if PCRE2_EXTRA_MATCH_LINE is
+also set.
 .
 .
 .\" HTML <a name="jitcompiling"></a>
@@ -1541,7 +1809,7 @@
 JIT compilation is a heavyweight optimization. It can take some time for
 patterns to be analyzed, and for one-off matches and simple patterns the
 benefit of faster execution might be offset by a much slower compilation time.
-Most, but not all patterns can be optimized by the JIT compiler.
+Most (but not all) patterns can be optimized by the JIT compiler.
 .
 .
 .\" HTML <a name="localesupport"></a>
@@ -1552,10 +1820,10 @@
 digits, or whatever, by reference to a set of tables, indexed by character code
 point. This applies only to characters whose code points are less than 256. By
 default, higher-valued code points never match escapes such as \ew or \ed.
-However, if PCRE2 is built with UTF support, all characters can be tested with
-\ep and \eP, or, alternatively, the PCRE2_UCP option can be set when a pattern
-is compiled; this causes \ew and friends to use Unicode property support
-instead of the built-in tables.
+However, if PCRE2 is built with Unicode support, all characters can be tested
+with \ep and \eP, or, alternatively, the PCRE2_UCP option can be set when a
+pattern is compiled; this causes \ew and friends to use Unicode property
+support instead of the built-in tables.
 .P
 The use of locales with Unicode is discouraged. If you are handling characters
 with code points greater than 128, you should either use Unicode support, or
@@ -1594,7 +1862,7 @@
 The pointer that is passed (via the compile context) to \fBpcre2_compile()\fP
 is saved with the compiled pattern, and the same tables are used by
 \fBpcre2_match()\fP and \fBpcre_dfa_match()\fP. Thus, for any single pattern,
-compilation, and matching all happen in the same locale, but different patterns
+compilation and matching both happen in the same locale, but different patterns
 can be processed in different locales.
 .
 .
@@ -1617,7 +1885,7 @@
 and the third argument is a pointer to a variable to receive the data. If the
 third argument is NULL, the first argument is ignored, and the function returns
 the size in bytes of the variable that is required for the information
-requested. Otherwise, The yield of the function is zero for success, or one of
+requested. Otherwise, the yield of the function is zero for success, or one of
 the following negative numbers:
 .sp
   PCRE2_ERROR_NULL           the argument \fIcode\fP was NULL
@@ -1641,12 +1909,15 @@
 .sp
   PCRE2_INFO_ALLOPTIONS
   PCRE2_INFO_ARGOPTIONS
+  PCRE2_INFO_EXTRAOPTIONS
 .sp
-Return a copy of the pattern's options. The third argument should point to a
+Return copies of the pattern's options. The third argument should point to a
 \fBuint32_t\fP variable. PCRE2_INFO_ARGOPTIONS returns exactly the options that
 were passed to \fBpcre2_compile()\fP, whereas PCRE2_INFO_ALLOPTIONS returns
 the compile options as modified by any top-level (*XXX) option settings such as
-(*UTF) at the start of the pattern itself.
+(*UTF) at the start of the pattern itself. PCRE2_INFO_EXTRAOPTIONS returns the
+extra options that were set in the compile context by calling the
+pcre2_set_compile_extra_options() function.
 .P
 For example, if the pattern /(*UTF)abc/ is compiled with the PCRE2_EXTENDED
 option, the result for PCRE2_INFO_ALLOPTIONS is PCRE2_EXTENDED and PCRE2_UTF.
@@ -1670,8 +1941,8 @@
   .* is not in a capturing group that is the subject
        of a back reference
   PCRE2_DOTALL is in force for .*
-  Neither (*PRUNE) nor (*SKIP) appears in the pattern.
-  PCRE2_NO_DOTSTAR_ANCHOR is not set.
+  Neither (*PRUNE) nor (*SKIP) appears in the pattern
+  PCRE2_NO_DOTSTAR_ANCHOR is not set
 .sp
 For patterns that are auto-anchored, the PCRE2_ANCHORED bit is set in the
 options returned for PCRE2_INFO_ALLOPTIONS.
@@ -1699,6 +1970,15 @@
 where (?| is not used, this is also the total number of capturing subpatterns.
 The third argument should point to an \fBuint32_t\fP variable.
 .sp
+  PCRE2_INFO_DEPTHLIMIT
+.sp
+If the pattern set a backtracking depth limit by including an item of the form
+(*LIMIT_DEPTH=nnnn) at the start, the value is returned. The third argument
+should point to an unsigned 32-bit integer. If no such value has been set, the
+call to \fBpcre2_pattern_info()\fP returns the error PCRE2_ERROR_UNSET. Note
+that this limit will only be used during matching if it is less than the limit
+set or defaulted by the caller of the match function.
+.sp
   PCRE2_INFO_FIRSTBITMAP
 .sp
 In the absence of a single first code unit for a non-anchored pattern,
@@ -1715,21 +1995,29 @@
 Return information about the first code unit of any matched string, for a
 non-anchored pattern. The third argument should point to an \fBuint32_t\fP
 variable. If there is a fixed first value, for example, the letter "c" from a
-pattern such as (cat|cow|coyote), 1 is returned, and the character value can be
-retrieved using PCRE2_INFO_FIRSTCODEUNIT. If there is no fixed first value, but
-it is known that a match can occur only at the start of the subject or
-following a newline in the subject, 2 is returned. Otherwise, and for anchored
-patterns, 0 is returned.
+pattern such as (cat|cow|coyote), 1 is returned, and the value can be retrieved
+using PCRE2_INFO_FIRSTCODEUNIT. If there is no fixed first value, but it is
+known that a match can occur only at the start of the subject or following a
+newline in the subject, 2 is returned. Otherwise, and for anchored patterns, 0
+is returned.
 .sp
   PCRE2_INFO_FIRSTCODEUNIT
 .sp
-Return the value of the first code unit of any matched string in the situation
+Return the value of the first code unit of any matched string for a pattern
 where PCRE2_INFO_FIRSTCODETYPE returns 1; otherwise return 0. The third
 argument should point to an \fBuint32_t\fP variable. In the 8-bit library, the
 value is always less than 256. In the 16-bit library the value can be up to
 0xffff. In the 32-bit library in UTF-32 mode the value can be up to 0x10ffff,
 and up to 0xffffffff when not using UTF-32 mode.
 .sp
+  PCRE2_INFO_FRAMESIZE
+.sp
+Return the size (in bytes) of the data frames that are used to remember
+backtracking positions when the pattern is processed by \fBpcre2_match()\fP
+without the use of JIT. The third argument should point to an \fBsize_t\fP
+variable. The frame size depends on the number of capturing parentheses in the
+pattern. Each additional capturing group adds two PCRE2_SIZE variables.
+.sp
   PCRE2_INFO_HASBACKSLASHC
 .sp
 Return 1 if the pattern contains any instances of \eC, otherwise 0. The third
@@ -1739,7 +2027,17 @@
 .sp
 Return 1 if the pattern contains any explicit matches for CR or LF characters,
 otherwise 0. The third argument should point to an \fBuint32_t\fP variable. An
-explicit match is either a literal CR or LF character, or \er or \en.
+explicit match is either a literal CR or LF character, or \er or \en or one of
+the equivalent hexadecimal or octal escape sequences.
+.sp
+  PCRE2_INFO_HEAPLIMIT
+.sp
+If the pattern set a heap memory limit by including an item of the form
+(*LIMIT_HEAP=nnnn) at the start, the value is returned. The third argument
+should point to an unsigned 32-bit integer. If no such value has been set, the
+call to \fBpcre2_pattern_info()\fP returns the error PCRE2_ERROR_UNSET. Note
+that this limit will only be used during matching if it is less than the limit
+set or defaulted by the caller of the match function.
 .sp
   PCRE2_INFO_JCHANGED
 .sp
@@ -1766,10 +2064,10 @@
 .sp
   PCRE2_INFO_LASTCODEUNIT
 .sp
-Return the value of the rightmost literal data unit that must exist in any
-matched string, other than at its start, if such a value has been recorded. The
-third argument should point to an \fBuint32_t\fP variable. If there is no such
-value, 0 is returned.
+Return the value of the rightmost literal code unit that must exist in any
+matched string, other than at its start, for a pattern where
+PCRE2_INFO_LASTCODETYPE returns 1. Otherwise, return 0. The third argument
+should point to an \fBuint32_t\fP variable.
 .sp
   PCRE2_INFO_MATCHEMPTY
 .sp
@@ -1784,7 +2082,9 @@
 If the pattern set a match limit by including an item of the form
 (*LIMIT_MATCH=nnnn) at the start, the value is returned. The third argument
 should point to an unsigned 32-bit integer. If no such value has been set, the
-call to \fBpcre2_pattern_info()\fP returns the error PCRE2_ERROR_UNSET.
+call to \fBpcre2_pattern_info()\fP returns the error PCRE2_ERROR_UNSET. Note
+that this limit will only be used during matching if it is less than the limit
+set or defaulted by the caller of the match function.
 .sp
   PCRE2_INFO_MAXLOOKBEHIND
 .sp
@@ -1796,7 +2096,8 @@
 lookbehind, though it does not actually inspect the previous character. This is
 to ensure that at least one character from the old segment is retained when a
 new segment is processed. Otherwise, if there are no lookbehinds in the
-pattern, \eA might match incorrectly at the start of a new segment.
+pattern, \eA might match incorrectly at the start of a second or subsequent
+segment.
 .sp
   PCRE2_INFO_MINLENGTH
 .sp
@@ -1878,23 +2179,17 @@
 .sp
   PCRE2_INFO_NEWLINE
 .sp
-The output is a \fBuint32_t\fP with one of the following values:
+The output is one of the following \fBuint32_t\fP values:
 .sp
   PCRE2_NEWLINE_CR       Carriage return (CR)
   PCRE2_NEWLINE_LF       Linefeed (LF)
   PCRE2_NEWLINE_CRLF     Carriage return, linefeed (CRLF)
   PCRE2_NEWLINE_ANY      Any Unicode line ending
   PCRE2_NEWLINE_ANYCRLF  Any of CR, LF, or CRLF
+  PCRE2_NEWLINE_NUL      The NUL character (binary zero)
 .sp
-This specifies the default character sequence that will be recognized as
-meaning "newline" while matching.
-.sp
-  PCRE2_INFO_RECURSIONLIMIT
-.sp
-If the pattern set a recursion limit by including an item of the form
-(*LIMIT_RECURSION=nnnn) at the start, the value is returned. The third
-argument should point to an unsigned 32-bit integer. If no such value has been
-set, the call to \fBpcre2_pattern_info()\fP returns the error PCRE2_ERROR_UNSET.
+This identifies the character sequence that will be recognized as meaning
+"newline" while matching.
 .sp
   PCRE2_INFO_SIZE
 .sp
@@ -1964,16 +2259,16 @@
 data block, which is an opaque structure that is accessed by function calls. In
 particular, the match data block contains a vector of offsets into the subject
 string that define the matched part of the subject and any substrings that were
-captured. This is know as the \fIovector\fP.
+captured. This is known as the \fIovector\fP.
 .P
 Before calling \fBpcre2_match()\fP, \fBpcre2_dfa_match()\fP, or
 \fBpcre2_jit_match()\fP you must create a match data block by calling one of
 the creation functions above. For \fBpcre2_match_data_create()\fP, the first
 argument is the number of pairs of offsets in the \fIovector\fP. One pair of
 offsets is required to identify the string that matched the whole pattern, with
-another pair for each captured substring. For example, a value of 4 creates
-enough space to record the matched portion of the subject plus three captured
-substrings. A minimum of at least 1 pair is imposed by
+an additional pair for each captured substring. For example, a value of 4
+creates enough space to record the matched portion of the subject plus three
+captured substrings. A minimum of at least 1 pair is imposed by
 \fBpcre2_match_data_create()\fP, so it is always possible to return the overall
 matched string.
 .P
@@ -2052,7 +2347,7 @@
     11,             /* the length of the subject string */
     0,              /* start at offset 0 in the subject */
     0,              /* default options */
-    match_data,     /* the match data block */
+    md,             /* the match data block */
     NULL);          /* a match context; NULL means use defaults */
 .sp
 If the subject string is zero-terminated, the length can be given as
@@ -2116,9 +2411,11 @@
 character is CR followed by LF, advance the starting offset by two characters
 instead of one.
 .P
-If a non-zero starting offset is passed when the pattern is anchored, one
+If a non-zero starting offset is passed when the pattern is anchored, a single
 attempt to match at the given offset is made. This can only succeed if the
-pattern does not require the match to be at the start of the subject.
+pattern does not require the match to be at the start of the subject. In other
+words, the anchoring must be the result of setting the PCRE2_ANCHORED option or
+the use of .* with PCRE2_DOTALL, not by starting the pattern with ^ or \eA.
 .
 .
 .\" HTML <a name="matchoptions"></a>
@@ -2126,15 +2423,15 @@
 .rs
 .sp
 The unused bits of the \fIoptions\fP argument for \fBpcre2_match()\fP must be
-zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_NOTBOL,
-PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART, PCRE2_NO_JIT,
-PCRE2_NO_UTF_CHECK, PCRE2_PARTIAL_HARD, and PCRE2_PARTIAL_SOFT. Their action is
-described below.
+zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_ENDANCHORED,
+PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART,
+PCRE2_NO_JIT, PCRE2_NO_UTF_CHECK, PCRE2_PARTIAL_HARD, and PCRE2_PARTIAL_SOFT.
+Their action is described below.
 .P
-Setting PCRE2_ANCHORED at match time is not supported by the just-in-time (JIT)
-compiler. If it is set, JIT matching is disabled and the normal interpretive
-code in \fBpcre2_match()\fP is run. Apart from PCRE2_NO_JIT (obviously), the
-remaining options are supported for JIT matching.
+Setting PCRE2_ANCHORED or PCRE2_ENDANCHORED at match time is not supported by
+the just-in-time (JIT) compiler. If it is set, JIT matching is disabled and the
+interpretive code in \fBpcre2_match()\fP is run. Apart from PCRE2_NO_JIT
+(obviously), the remaining options are supported for JIT matching.
 .sp
   PCRE2_ANCHORED
 .sp
@@ -2144,6 +2441,12 @@
 matching time. Note that setting the option at match time disables JIT
 matching.
 .sp
+  PCRE2_ENDANCHORED
+.sp
+If the PCRE2_ENDANCHORED option is set, any string that \fBpcre2_match()\fP
+matches must be right at the end of the subject string. Note that setting the
+option at match time disables JIT matching.
+.sp
   PCRE2_NOTBOL
 .sp
 This option specifies that first character of the subject string is not the
@@ -2228,12 +2531,12 @@
 If you know that your subject is valid, and you want to skip these checks for
 performance reasons, you can set the PCRE2_NO_UTF_CHECK option when calling
 \fBpcre2_match()\fP. You might want to do this for the second and subsequent
-calls to \fBpcre2_match()\fP if you are making repeated calls to find all the
-matches in a single subject string.
+calls to \fBpcre2_match()\fP if you are making repeated calls to find other
+matches in the same subject string.
 .P
-NOTE: When PCRE2_NO_UTF_CHECK is set, the effect of passing an invalid string
-as a subject, or an invalid value of \fIstartoffset\fP, is undefined. Your
-program may crash or loop indefinitely.
+WARNING: When PCRE2_NO_UTF_CHECK is set, the effect of passing an invalid
+string as a subject, or an invalid value of \fIstartoffset\fP, is undefined.
+Your program may crash or loop indefinitely.
 .sp
   PCRE2_PARTIAL_HARD
   PCRE2_PARTIAL_SOFT
@@ -2300,9 +2603,9 @@
 reference, and so advances only by one character after the first failure.
 .P
 An explicit match for CR of LF is either a literal appearance of one of those
-characters in the pattern, or one of the \er or \en escape sequences. Implicit
-matches such as [^X] do not count, nor does \es, even though it includes CR and
-LF in the characters that it matches.
+characters in the pattern, or one of the \er or \en or equivalent octal or
+hexadecimal escape sequences. Implicit matches such as [^X] do not count, nor
+does \es, even though it includes CR and LF in the characters that it matches.
 .P
 Notwithstanding the above, anomalous effects may still occur when CRLF is a
 valid newline sequence and explicit \er or \en escapes appear in the pattern.
@@ -2366,12 +2669,12 @@
 .\"
 documentation for details of partial matching.
 .P
-After a successful match, the first pair of offsets identifies the portion of
-the subject string that was matched by the entire pattern. The next pair is
-used for the first capturing subpattern, and so on. The value returned by
+After a fully successful match, the first pair of offsets identifies the
+portion of the subject string that was matched by the entire pattern. The next
+pair is used for the first captured substring, and so on. The value returned by
 \fBpcre2_match()\fP is one more than the highest numbered pair that has been
 set. For example, if two substrings have been captured, the returned value is
-3. If there are no capturing subpatterns, the return value from a successful
+3. If there are no captured substrings, the return value from a successful
 match is 1, indicating that just the first pair of offsets has been set.
 .P
 If a pattern uses the \eK escape sequence within a positive assertion, the
@@ -2386,11 +2689,7 @@
 If the ovector is too small to hold all the captured substring offsets, as much
 as possible is filled in, and the function returns a value of zero. If captured
 substrings are not of interest, \fBpcre2_match()\fP may be called with a match
-data block whose ovector is of minimum length (that is, one pair). However, if
-the pattern contains back references and the \fIovector\fP is not big enough to
-remember the related substrings, PCRE2 has to get additional memory for use
-during matching. Thus it is usually advisable to set up a match data block
-containing an ovector of reasonable size.
+data block whose ovector is of minimum length (that is, one pair).
 .P
 It is possible for capturing subpattern number \fIn+1\fP to match some part of
 the subject when subpattern \fIn\fP has not been used at all. For example, if
@@ -2430,24 +2729,27 @@
 undefined.
 .P
 After a successful match, a partial match (PCRE2_ERROR_PARTIAL), or a failure
-to match (PCRE2_ERROR_NOMATCH), a (*MARK) name may be available, and
-\fBpcre2_get_mark()\fP can be called. It returns a pointer to the
-zero-terminated name, which is within the compiled pattern. Otherwise NULL is
-returned. The length of the (*MARK) name (excluding the terminating zero) is
-stored in the code unit that preceeds the name. You should use this instead of
-relying on the terminating zero if the (*MARK) name might contain a binary
-zero.
+to match (PCRE2_ERROR_NOMATCH), a (*MARK), (*PRUNE), or (*THEN) name may be
+available. The function \fBpcre2_get_mark()\fP can be called to access this
+name. The same function applies to all three verbs. It returns a pointer to the
+zero-terminated name, which is within the compiled pattern. If no name is
+available, NULL is returned. The length of the name (excluding the terminating
+zero) is stored in the code unit that precedes the name. You should use this
+length instead of relying on the terminating zero if the name might contain a
+binary zero.
 .P
-After a successful match, the (*MARK) name that is returned is the
-last one encountered on the matching path through the pattern. After a "no
-match" or a partial match, the last encountered (*MARK) name is returned. For
-example, consider this pattern:
+After a successful match, the name that is returned is the last (*MARK),
+(*PRUNE), or (*THEN) name encountered on the matching path through the pattern.
+Instances of (*PRUNE) and (*THEN) without names are ignored. Thus, for example,
+if the matching path contains (*MARK:A)(*PRUNE), the name "A" is returned.
+After a "no match" or a partial match, the last encountered name is returned.
+For example, consider this pattern:
 .sp
   ^(*MARK:A)((*MARK:B)a|b)c
 .sp
-When it matches "bc", the returned mark is A. The B mark is "seen" in the first
+When it matches "bc", the returned name is A. The B mark is "seen" in the first
 branch of the group, but it is not on the matching path. On the other hand,
-when this pattern fails to match "bx", the returned mark is B.
+when this pattern fails to match "bx", the returned name is B.
 .P
 After a successful match, a partial match, or one of the invalid UTF errors
 (for example, PCRE2_ERROR_UTF8_ERR5), \fBpcre2_get_startchar()\fP can be
@@ -2506,8 +2808,9 @@
 .sp
   PCRE2_ERROR_BADMODE
 .sp
-This error is given when a pattern that was compiled by the 8-bit library is
-passed to a 16-bit or 32-bit library function, or vice versa.
+This error is given when a compiled pattern is passed to a function in a
+library of a different code unit width, for example, a pattern compiled by
+the 8-bit library is passed to a 16-bit or 32-bit library function.
 .sp
   PCRE2_ERROR_BADOFFSET
 .sp
@@ -2534,22 +2837,19 @@
 .\"
 documentation for details.
 .sp
+  PCRE2_ERROR_DEPTHLIMIT
+.sp
+The nested backtracking depth limit was reached.
+.sp
+  PCRE2_ERROR_HEAPLIMIT
+.sp
+The heap limit was reached.
+.sp
   PCRE2_ERROR_INTERNAL
 .sp
 An unexpected internal error has occurred. This error could be caused by a bug
 in PCRE2 or by overwriting of the compiled pattern.
 .sp
-  PCRE2_ERROR_JIT_BADOPTION
-.sp
-This error is returned when a pattern that was successfully studied using JIT
-is being matched, but the matching mode (partial or complete match) does not
-correspond to any JIT compilation mode. When the JIT fast path function is
-used, this error may be also given for invalid options. See the
-.\" HREF
-\fBpcre2jit\fP
-.\"
-documentation for more details.
-.sp
   PCRE2_ERROR_JIT_STACKLIMIT
 .sp
 This error is returned when a pattern that was successfully studied using JIT
@@ -2562,15 +2862,14 @@
 .sp
   PCRE2_ERROR_MATCHLIMIT
 .sp
-The backtracking limit was reached.
+The backtracking match limit was reached.
 .sp
   PCRE2_ERROR_NOMEMORY
 .sp
-If a pattern contains back references, but the ovector is not big enough to
-remember the referenced substrings, PCRE2 gets a block of memory at the start
-of matching to use for this purpose. There are some other special cases where
-extra memory is needed during matching. This error is given when memory cannot
-be obtained.
+If a pattern contains many nested backtracking points, heap memory is used to
+remember them. This error is given when the memory allocation function (default
+or custom) fails. Note that a different error, PCRE2_ERROR_HEAPLIMIT, is given
+if the amount of memory needed exceeds the heap limit.
 .sp
   PCRE2_ERROR_NULL
 .sp
@@ -2586,10 +2885,6 @@
 faulted at compile time, but more complicated cases, in particular mutual
 recursions between two different subpatterns, cannot be detected until matching
 is attempted.
-.sp
-  PCRE2_ERROR_RECURSIONLIMIT
-.sp
-The internal recursion limit was reached.
 .
 .
 .\" HTML <a name="geterrormessage"></a>
@@ -2604,8 +2899,8 @@
 A text message for an error code from any PCRE2 function (compile, match, or
 auxiliary) can be obtained by calling \fBpcre2_get_error_message()\fP. The code
 is passed as the first argument, with the remaining two arguments specifying a
-code unit buffer and its length, into which the text message is placed. Note
-that the message is returned in code units of the appropriate width for the
+code unit buffer and its length in code units, into which the text message is
+placed. The message is returned in code units of the appropriate width for the
 library that is being used.
 .P
 The returned message is terminated with a trailing zero, and the function
@@ -2779,8 +3074,8 @@
 compiled pattern, and the second is the name. The yield of the function is the
 subpattern number, PCRE2_ERROR_NOSUBSTRING if there is no subpattern of that
 name, or PCRE2_ERROR_NOUNIQUESUBSTRING if there is more than one subpattern of
-that name. Given the number, you can extract the substring directly, or use one
-of the functions described above.
+that name. Given the number, you can extract the substring directly from the
+ovector, or use one of the "bynumber" functions described above.
 .P
 For convenience, there are also "byname" functions that correspond to the
 "bynumber" functions, the only difference being that the second argument is a
@@ -2855,12 +3150,12 @@
 In the replacement string, which is interpreted as a UTF string in UTF mode,
 and is checked for UTF validity unless the PCRE2_NO_UTF_CHECK option is set, a
 dollar character is an escape character that can specify the insertion of
-characters from capturing groups or (*MARK) items in the pattern. The following
-forms are always recognized:
+characters from capturing groups or (*MARK), (*PRUNE), or (*THEN) items in the
+pattern. The following forms are always recognized:
 .sp
   $$                  insert a dollar character
   $<n> or ${<n>}      insert the contents of group <n>
-  $*MARK or ${*MARK}  insert the name of the last (*MARK) encountered
+  $*MARK or ${*MARK}  insert a (*MARK), (*PRUNE), or (*THEN) name
 .sp
 Either a group number or a group name can be given for <n>. Curly brackets are
 required only if the following character would be interpreted as part of the
@@ -2868,24 +3163,41 @@
 For example, if the pattern a(b)c is matched with "=abc=" and the replacement
 string "+$1$0$1+", the result is "=+babcb+=".
 .P
-The facility for inserting a (*MARK) name can be used to perform simple
-simultaneous substitutions, as this \fBpcre2test\fP example shows:
+$*MARK inserts the name from the last encountered (*MARK), (*PRUNE), or (*THEN)
+on the matching path that has a name. (*MARK) must always include a name, but
+(*PRUNE) and (*THEN) need not. For example, in the case of (*MARK:A)(*PRUNE)
+the name inserted is "A", but for (*MARK:A)(*PRUNE:B) the relevant name is "B".
+This facility can be used to perform simple simultaneous substitutions, as this
+\fBpcre2test\fP example shows:
 .sp
-  /(*:pear)apple|(*:orange)lemon/g,replace=${*MARK}
+  /(*MARK:pear)apple|(*MARK:orange)lemon/g,replace=${*MARK}
       apple lemon
    2: pear orange
 .sp
 As well as the usual options for \fBpcre2_match()\fP, a number of additional
-options can be set in the \fIoptions\fP argument.
+options can be set in the \fIoptions\fP argument of \fBpcre2_substitute()\fP.
 .P
 PCRE2_SUBSTITUTE_GLOBAL causes the function to iterate over the subject string,
-replacing every matching substring. If this is not set, only the first matching
-substring is replaced. If any matched substring has zero length, after the
-substitution has happened, an attempt to find a non-empty match at the same
-position is performed. If this is not successful, the current position is
-advanced by one character except when CRLF is a valid newline sequence and the
-next two characters are CR, LF. In this case, the current position is advanced
-by two characters.
+replacing every matching substring. If this option is not set, only the first
+matching substring is replaced. The search for matches takes place in the
+original subject string (that is, previous replacements do not affect it).
+Iteration is implemented by advancing the \fIstartoffset\fP value for each
+search, which is always passed the entire subject string. If an offset limit is
+set in the match context, searching stops when that limit is reached.
+.P
+You can restrict the effect of a global substitution to a portion of the
+subject string by setting either or both of \fIstartoffset\fP and an offset
+limit. Here is a \fPpcre2test\fP example:
+.sp
+  /B/g,replace=!,use_offset_limit
+  ABC ABC ABC ABC\e=offset=3,offset_limit=12
+   2: ABC A!C A!C ABC
+.sp
+When continuing with global substitutions after matching a substring with zero
+length, an attempt to find a non-empty match at the same offset is performed.
+If this is not successful, the offset is advanced by one character except when
+CRLF is a valid newline sequence and the next two characters are CR, LF. In
+this case, the offset is advanced by two characters.
 .P
 PCRE2_SUBSTITUTE_OVERFLOW_LENGTH changes what happens when the output buffer is
 too small. The default action is to return PCRE2_ERROR_NOMEMORY immediately. If
@@ -2987,10 +3299,10 @@
 .P
 PCRE2_ERROR_BADREPLACEMENT is used for miscellaneous syntax errors in the
 replacement string, with more particular errors being PCRE2_ERROR_BADREPESCAPE
-(invalid escape sequence), PCRE2_ERROR_REPMISSING_BRACE (closing curly bracket
-not found), PCRE2_BADSUBSTITUTION (syntax error in extended group
-substitution), and PCRE2_BADSUBPATTERN (the pattern match ended before it
-started, which can happen if \eK is used in an assertion).
+(invalid escape sequence), PCRE2_ERROR_REPMISSINGBRACE (closing curly bracket
+not found), PCRE2_ERROR_BADSUBSTITUTION (syntax error in extended group
+substitution), and PCRE2_ERROR_BADSUBSPATTERN (the pattern match ended before
+it started, which can happen if \eK is used in an assertion).
 .P
 As for all PCRE2 errors, a text message that describes the error can be
 obtained by calling the \fBpcre2_get_error_message()\fP function (see
@@ -3084,11 +3396,12 @@
 .P
 The function \fBpcre2_dfa_match()\fP is called to match a subject string
 against a compiled pattern, using a matching algorithm that scans the subject
-string just once, and does not backtrack. This has different characteristics to
-the normal algorithm, and is not compatible with Perl. Some of the features of
-PCRE2 patterns are not supported. Nevertheless, there are times when this kind
-of matching can be useful. For a discussion of the two matching algorithms, and
-a list of features that \fBpcre2_dfa_match()\fP does not support, see the
+string just once (not counting lookaround assertions), and does not backtrack.
+This has different characteristics to the normal algorithm, and is not
+compatible with Perl. Some of the features of PCRE2 patterns are not supported.
+Nevertheless, there are times when this kind of matching can be useful. For a
+discussion of the two matching algorithms, and a list of features that
+\fBpcre2_dfa_match()\fP does not support, see the
 .\" HREF
 \fBpcre2matching\fP
 .\"
@@ -3115,7 +3428,7 @@
     11,             /* the length of the subject string */
     0,              /* start at offset 0 in the subject */
     0,              /* default options */
-    match_data,     /* the match data block */
+    md,             /* the match data block */
     NULL,           /* a match context; NULL means use defaults */
     wspace,         /* working space vector */
     20);            /* number of elements (NOT size in bytes) */
@@ -3124,11 +3437,11 @@
 .rs
 .sp
 The unused bits of the \fIoptions\fP argument for \fBpcre2_dfa_match()\fP must
-be zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_NOTBOL,
-PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART, PCRE2_NO_UTF_CHECK,
-PCRE2_PARTIAL_HARD, PCRE2_PARTIAL_SOFT, PCRE2_DFA_SHORTEST, and
-PCRE2_DFA_RESTART. All but the last four of these are exactly the same as for
-\fBpcre2_match()\fP, so their description is not repeated here.
+be zero. The only bits that may be set are PCRE2_ANCHORED, PCRE2_ENDANCHORED,
+PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART,
+PCRE2_NO_UTF_CHECK, PCRE2_PARTIAL_HARD, PCRE2_PARTIAL_SOFT, PCRE2_DFA_SHORTEST,
+and PCRE2_DFA_RESTART. All but the last four of these are exactly the same as
+for \fBpcre2_match()\fP, so their description is not repeated here.
 .sp
   PCRE2_PARTIAL_HARD
   PCRE2_PARTIAL_SOFT
@@ -3222,7 +3535,7 @@
 repeats at the end of a pattern (as well as internally). For example, the
 pattern "a\ed+" is compiled as if it were "a\ed++". For DFA matching, this
 means that only one possible match is found. If you really do want multiple
-matches in such cases, either use an ungreedy repeat auch as "a\ed+?" or set
+matches in such cases, either use an ungreedy repeat such as "a\ed+?" or set
 the PCRE2_NO_AUTO_POSSESS option when compiling.
 .
 .
@@ -3275,7 +3588,7 @@
 .sp
 \fBpcre2build\fP(3), \fBpcre2callout\fP(3), \fBpcre2demo(3)\fP,
 \fBpcre2matching\fP(3), \fBpcre2partial\fP(3), \fBpcre2posix\fP(3),
-\fBpcre2sample\fP(3), \fBpcre2stack\fP(3), \fBpcre2unicode\fP(3).
+\fBpcre2sample\fP(3), \fBpcre2unicode\fP(3).
 .
 .
 .SH AUTHOR
@@ -3292,6 +3605,6 @@
 .rs
 .sp
 .nf
-Last updated: 17 June 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 31 December 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2build.3 b/dist2/doc/pcre2build.3
index 11b1c57..7586d22 100644
--- a/dist2/doc/pcre2build.3
+++ b/dist2/doc/pcre2build.3
@@ -1,4 +1,4 @@
-.TH PCRE2BUILD 3 "01 April 2016" "PCRE2 10.22"
+.TH PCRE2BUILD 3 "18 July 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .
@@ -55,21 +55,21 @@
 .sp
   ./configure --help
 .sp
-The following sections include descriptions of options whose names begin with
---enable or --disable. These settings specify changes to the defaults for the
-\fBconfigure\fP command. Because of the way that \fBconfigure\fP works,
---enable and --disable always come in pairs, so the complementary option always
-exists as well, but as it specifies the default, it is not described.
+The following sections include descriptions of "on/off" options whose names
+begin with --enable or --disable. Because of the way that \fBconfigure\fP
+works, --enable and --disable always come in pairs, so the complementary option
+always exists as well, but as it specifies the default, it is not described.
+Options that specify values have names that start with --with.
 .
 .
 .SH "BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES"
 .rs
 .sp
 By default, a library called \fBlibpcre2-8\fP is built, containing functions
-that take string arguments contained in vectors of bytes, interpreted either as
+that take string arguments contained in arrays of bytes, interpreted either as
 single-byte characters, or UTF-8 strings. You can also build two other
 libraries, called \fBlibpcre2-16\fP and \fBlibpcre2-32\fP, which process
-strings that are contained in vectors of 16-bit and 32-bit code units,
+strings that are contained in arrays of 16-bit and 32-bit code units,
 respectively. These can be interpreted either as single-unit characters or
 UTF-16/UTF-32 strings. To build these additional libraries, add one or both of
 the following to the \fBconfigure\fP command:
@@ -119,10 +119,10 @@
 locked this out by setting PCRE2_NEVER_UTF.
 .P
 UTF support allows the libraries to process character code points up to
-0x10ffff in the strings that they handle. It also provides support for
-accessing the Unicode properties of such characters, using pattern escapes such
-as \eP, \ep, and \eX. Only the general category properties such as \fILu\fP and
-\fINd\fP are supported. Details are given in the
+0x10ffff in the strings that they handle. Unicode support also gives access to
+the Unicode properties of characters, using pattern escapes such as \eP, \ep,
+and \eX. Only the general category properties such as \fILu\fP and \fINd\fP are
+supported. Details are given in the
 .\" HREF
 \fBpcre2pattern\fP
 .\"
@@ -151,13 +151,18 @@
 .SH "JUST-IN-TIME COMPILER SUPPORT"
 .rs
 .sp
-Just-in-time compiler support is included in the build by specifying
+Just-in-time (JIT) compiler support is included in the build by specifying
 .sp
   --enable-jit
 .sp
 This support is available only for certain hardware architectures. If this
-option is set for an unsupported architecture, a building error occurs.
-See the
+option is set for an unsupported architecture, a building error occurs. If you
+are running under SELinux you may also want to add
+.sp
+  --enable-jit-sealloc
+.sp
+which enables the use of an execmem allocator in JIT that is compatible with
+SELinux. This has no effect if JIT is not enabled. See the
 .\" HREF
 \fBpcre2jit\fP
 .\"
@@ -192,18 +197,22 @@
   --enable-newline-is-anycrlf
 .sp
 which causes PCRE2 to recognize any of the three sequences CR, LF, or CRLF as
-indicating a line ending. Finally, a fifth option, specified by
+indicating a line ending. A fifth option, specified by
 .sp
   --enable-newline-is-any
 .sp
 causes PCRE2 to recognize any Unicode newline sequence. The Unicode newline
 sequences are the three just mentioned, plus the single characters VT (vertical
 tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line
-separator, U+2028), and PS (paragraph separator, U+2029).
+separator, U+2028), and PS (paragraph separator, U+2029). The final option is
+.sp
+  --enable-newline-is-nul
+.sp
+which causes NUL (binary zero) is set as the default line-ending character.
 .P
 Whatever default line ending convention is selected when PCRE2 is built can be
 overridden by applications that use the library. At build time it is
-conventional to use the standard for your operating system.
+recommended to use the standard for your operating system.
 .
 .
 .SH "WHAT \eR MATCHES"
@@ -217,7 +226,7 @@
 .sp
 the default is changed so that \eR matches only CR, LF, or CRLF. Whatever is
 selected when PCRE2 is built can be overridden by applications that use the
-called.
+library.
 .
 .
 .SH "HANDLING VERY LARGE PATTERNS"
@@ -241,41 +250,13 @@
 4 and cannot be overridden; the value of --with-link-size is ignored.
 .
 .
-.SH "AVOIDING EXCESSIVE STACK USAGE"
-.rs
-.sp
-When matching with the \fBpcre2_match()\fP function, PCRE2 implements
-backtracking by making recursive calls to an internal function called
-\fBmatch()\fP. In environments where the size of the stack is limited, this can
-severely limit PCRE2's operation. (The Unix environment does not usually suffer
-from this problem, but it may sometimes be necessary to increase the maximum
-stack size. There is a discussion in the
-.\" HREF
-\fBpcre2stack\fP
-.\"
-documentation.) An alternative approach to recursion that uses memory from the
-heap to remember data, instead of using recursive function calls, has been
-implemented to work round the problem of limited stack size. If you want to
-build a version of PCRE2 that works this way, add
-.sp
-  --disable-stack-for-recursion
-.sp
-to the \fBconfigure\fP command. By default, the system functions \fBmalloc()\fP
-and \fBfree()\fP are called to manage the heap memory that is required, but
-custom memory management functions can be called instead. PCRE2 runs noticeably
-more slowly when built in this way. This option affects only the
-\fBpcre2_match()\fP function; it is not relevant for \fBpcre2_dfa_match()\fP.
-.
-.
 .SH "LIMITING PCRE2 RESOURCE USAGE"
 .rs
 .sp
-Internally, PCRE2 has a function called \fBmatch()\fP, which it calls
-repeatedly (sometimes recursively) when matching a pattern with the
-\fBpcre2_match()\fP function. By controlling the maximum number of times this
-function may be called during a single matching operation, a limit can be
-placed on the resources used by a single call to \fBpcre2_match()\fP. The limit
-can be changed at run time, as described in the
+The \fBpcre2_match()\fP function increments a counter each time it goes round
+its main loop. Putting a limit on this counter controls the amount of computing
+resource used by a single call to \fBpcre2_match()\fP. The limit can be changed
+at run time, as described in the
 .\" HREF
 \fBpcre2api\fP
 .\"
@@ -284,19 +265,47 @@
 .sp
   --with-match-limit=500000
 .sp
-to the \fBconfigure\fP command. This setting has no effect on the
-\fBpcre2_dfa_match()\fP matching function.
+to the \fBconfigure\fP command. This setting also applies to the
+\fBpcre2_dfa_match()\fP matching function, and to JIT matching (though the
+counting is done differently).
 .P
-In some environments it is desirable to limit the depth of recursive calls of
-\fBmatch()\fP more strictly than the total number of calls, in order to
-restrict the maximum amount of stack (or heap, if --disable-stack-for-recursion
-is specified) that is used. A second limit controls this; it defaults to the
-value that is set for --with-match-limit, which imposes no additional
-constraints. However, you can set a lower limit by adding, for example,
+The \fBpcre2_match()\fP function starts out using a 20K vector on the system
+stack to record backtracking points. The more nested backtracking points there
+are (that is, the deeper the search tree), the more memory is needed. If the
+initial vector is not large enough, heap memory is used, up to a certain limit,
+which is specified in kilobytes. The limit can be changed at run time, as
+described in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+documentation. The default limit (in effect unlimited) is 20 million. You can
+change this by a setting such as
 .sp
-  --with-match-limit-recursion=10000
+  --with-heap-limit=500
 .sp
-to the \fBconfigure\fP command. This value can also be overridden at run time.
+which limits the amount of heap to 500 kilobytes. This limit applies only to
+interpretive matching in pcre2_match(). It does not apply when JIT (which has
+its own memory arrangements) is used, nor does it apply to
+\fBpcre2_dfa_match()\fP.
+.P
+You can also explicitly limit the depth of nested backtracking in the
+\fBpcre2_match()\fP interpreter. This limit defaults to the value that is set
+for --with-match-limit. You can set a lower default limit by adding, for
+example,
+.sp
+  --with-match-limit_depth=10000
+.sp
+to the \fBconfigure\fP command. This value can be overridden at run time. This
+depth limit indirectly limits the amount of heap memory that is used, but
+because the size of each backtracking "frame" depends on the number of
+capturing parentheses in a pattern, the amount of heap that is used before the
+limit is reached varies from pattern to pattern. This limit was more useful in
+versions before 10.30, where function recursion was used for backtracking.
+.P
+As well as applying to \fBpcre2_match()\fP, the depth limit also controls
+the depth of recursive function calls in \fBpcre2_dfa_match()\fP. These are
+used for lookaround assertions, atomic groups, and recursion within patterns.
+The limit does not apply to JIT matching.
 .
 .
 .SH "CREATING CHARACTER TABLES AT BUILD TIME"
@@ -312,10 +321,10 @@
 to the \fBconfigure\fP command, the distributed tables are no longer used.
 Instead, a program called \fBdftables\fP is compiled and run. This outputs the
 source for new set of tables, created in the default locale of your C run-time
-system. (This method of replacing the tables does not work if you are cross
+system. This method of replacing the tables does not work if you are cross
 compiling, because \fBdftables\fP is run on the local host. If you need to
 create alternative tables when cross compiling, you will have to do so "by
-hand".)
+hand".
 .
 .
 .SH "USING EBCDIC CODE"
@@ -385,16 +394,19 @@
 .sp
 \fBpcre2grep\fP uses an internal buffer to hold a "window" on the file it is
 scanning, in order to be able to output "before" and "after" lines when it
-finds a match. The size of the buffer is controlled by a parameter whose
-default value is 20K. The buffer itself is three times this size, but because
-of the way it is used for holding "before" lines, the longest line that is
-guaranteed to be processable is the parameter size. You can change the default
-parameter value by adding, for example,
+finds a match. The starting size of the buffer is controlled by a parameter
+whose default value is 20K. The buffer itself is three times this size, but
+because of the way it is used for holding "before" lines, the longest line that
+is guaranteed to be processable is the parameter size. If a longer line is
+encountered, \fBpcre2grep\fP automatically expands the buffer, up to a
+specified maximum size, whose default is 1M or the starting size, whichever is
+the larger. You can change the default parameter values by adding, for example,
 .sp
-  --with-pcre2grep-bufsize=50K
+  --with-pcre2grep-bufsize=51200
+  --with-pcre2grep-max-bufsize=2097152
 .sp
-to the \fBconfigure\fP command. The caller of \fPpcre2grep\fP can override this
-value by using --buffer-size on the command line.
+to the \fBconfigure\fP command. The caller of \fPpcre2grep\fP can override
+these values by using --buffer-size and --max-buffer-size on the command line.
 .
 .
 .SH "PCRE2TEST OPTION FOR LIBREADLINE SUPPORT"
@@ -512,6 +524,44 @@
 documentation.
 .
 .
+.SH "SUPPORT FOR FUZZERS"
+.rs
+.sp
+There is a special option for use by people who want to run fuzzing tests on
+PCRE2:
+.sp
+  --enable-fuzz-support
+.sp
+At present this applies only to the 8-bit library. If set, it causes an extra
+library called libpcre2-fuzzsupport.a to be built, but not installed. This
+contains a single function called LLVMFuzzerTestOneInput() whose arguments are
+a pointer to a string and the length of the string. When called, this function
+tries to compile the string as a pattern, and if that succeeds, to match it.
+This is done both with no options and with some random options bits that are
+generated from the string.
+.P
+Setting --enable-fuzz-support also causes a binary called \fBpcre2fuzzcheck\fP
+to be created. This is normally run under valgrind or used when PCRE2 is
+compiled with address sanitizing enabled. It calls the fuzzing function and
+outputs information about it is doing. The input strings are specified by
+arguments: if an argument starts with "=" the rest of it is a literal input
+string. Otherwise, it is assumed to be a file name, and the contents of the
+file are the test string.
+.
+.
+.SH "OBSOLETE OPTION"
+.rs
+.sp
+In versions of PCRE2 prior to 10.30, there were two ways of handling
+backtracking in the \fBpcre2_match()\fP function. The default was to use the
+system stack, but if
+.sp
+  --disable-stack-for-recursion
+.sp
+was set, memory on the heap was used. From release 10.30 onwards this has
+changed (the stack is no longer used) and this option now does nothing except
+give a warning.
+.
 .SH "SEE ALSO"
 .rs
 .sp
@@ -532,6 +582,6 @@
 .rs
 .sp
 .nf
-Last updated: 01 April 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 18 July 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2callout.3 b/dist2/doc/pcre2callout.3
index 6919f5a..e3fd600 100644
--- a/dist2/doc/pcre2callout.3
+++ b/dist2/doc/pcre2callout.3
@@ -1,4 +1,4 @@
-.TH PCRE2CALLOUT 3 "23 March 2015" "PCRE2 10.20"
+.TH PCRE2CALLOUT 3 "22 December 2017" "PCRE2 10.31"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH SYNOPSIS
@@ -40,13 +40,22 @@
 .sp
 If the PCRE2_AUTO_CALLOUT option bit is set when a pattern is compiled, PCRE2
 automatically inserts callouts, all with number 255, before each item in the
-pattern. For example, if PCRE2_AUTO_CALLOUT is used with the pattern
+pattern except for immediately before or after an explicit callout. For
+example, if PCRE2_AUTO_CALLOUT is used with the pattern
 .sp
-  A(\ed{2}|--)
+  A(?C3)B
 .sp
 it is processed as if it were
 .sp
-(?C255)A(?C255)((?C255)\ed{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
+  (?C255)A(?C3)B(?C255)
+.sp
+Here is a more complicated example:
+.sp
+  A(\ed{2}|--)
+.sp
+With PCRE2_AUTO_CALLOUT, this pattern is processed as if it were
+.sp
+  (?C255)A(?C255)((?C255)\ed{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
 .sp
 Notice that there is a callout before and after each parenthesis and
 alternation bar. If the pattern contains a conditional group whose condition is
@@ -91,10 +100,10 @@
   No match
 .sp
 This indicates that when matching [bc] fails, there is no backtracking into a+
-and therefore the callouts that would be taken for the backtracks do not occur.
-You can disable the auto-possessify feature by passing PCRE2_NO_AUTO_POSSESS to
-\fBpcre2_compile()\fP, or starting the pattern with (*NO_AUTO_POSSESS). In this
-case, the output changes to this:
+(because it is being treated as a++) and therefore the callouts that would be
+taken for the backtracks do not occur. You can disable the auto-possessify
+feature by passing PCRE2_NO_AUTO_POSSESS to \fBpcre2_compile()\fP, or starting
+the pattern with (*NO_AUTO_POSSESS). In this case, the output changes to this:
 .sp
   --->aaaa
    +0 ^        a+
@@ -115,10 +124,13 @@
 a pattern. If PCRE2_DOTALL is set, so that the dot can match any character, the
 pattern is automatically anchored. If PCRE2_DOTALL is not set, a match can
 start only after an internal newline or at the beginning of the subject, and
-\fBpcre2_compile()\fP remembers this. This optimization is disabled, however,
-if .* is in an atomic group or if there is a back reference to the capturing
-group in which it appears. It is also disabled if the pattern contains (*PRUNE)
-or (*SKIP). However, the presence of callouts does not affect it.
+\fBpcre2_compile()\fP remembers this. If a pattern has more than one top-level
+branch, automatic anchoring occurs if all branches are anchorable.
+.P
+This optimization is disabled, however, if .* is in an atomic group or if there
+is a back reference to the capturing group in which it appears. It is also
+disabled if the pattern contains (*PRUNE) or (*SKIP). However, the presence of
+callouts does not affect it.
 .P
 For example, if the pattern .*\ed is compiled with PCRE2_AUTO_CALLOUT and
 applied to the string "aa", the \fBpcre2test\fP output is:
@@ -148,9 +160,6 @@
 This shows more match attempts, starting at the second subject character.
 Another optimization, described in the next section, means that there is no
 subsequent attempt to match with an empty subject.
-.P
-If a pattern has more than one top-level branch, automatic anchoring occurs if
-all branches are anchorable.
 .
 .
 .SS "Other optimizations"
@@ -166,9 +175,10 @@
 start, and the callout is never reached. However, with "abyd", though the
 result is still no match, the callout is obeyed.
 .P
-PCRE2 also knows the minimum length of a matching string, and will immediately
-give a "no match" return without actually running a match if the subject is not
-long enough, or, for unanchored patterns, if it has been scanned far enough.
+For most patterns PCRE2 also knows the minimum length of a matching string, and
+will immediately give a "no match" return without actually running a match if
+the subject is not long enough, or, for unanchored patterns, if it has been
+scanned far enough.
 .P
 You can disable these optimizations by passing the PCRE2_NO_START_OPTIMIZE
 option to \fBpcre2_compile()\fP, or by starting the pattern with
@@ -181,20 +191,22 @@
 .rs
 .sp
 During matching, when PCRE2 reaches a callout point, if an external function is
-set in the match context, it is called. This applies to both normal and DFA
-matching. The first argument to the callout function is a pointer to a
-\fBpcre2_callout\fP block. The second argument is the void * callout data that
-was supplied when the callout was set up by calling \fBpcre2_set_callout()\fP
-(see the
+provided in the match context, it is called. This applies to both normal,
+DFA, and JIT matching. The first argument to the callout function is a pointer
+to a \fBpcre2_callout\fP block. The second argument is the void * callout data
+that was supplied when the callout was set up by calling
+\fBpcre2_set_callout()\fP (see the
 .\" HREF
 \fBpcre2api\fP
 .\"
-documentation). The callout block structure contains the following fields:
+documentation). The callout block structure contains the following fields, not
+necessarily in this order:
 .sp
   uint32_t      \fIversion\fP;
   uint32_t      \fIcallout_number\fP;
   uint32_t      \fIcapture_top\fP;
   uint32_t      \fIcapture_last\fP;
+  uint32_t      \fIcallout_flags\fP;
   PCRE2_SIZE   *\fIoffset_vector\fP;
   PCRE2_SPTR    \fImark\fP;
   PCRE2_SPTR    \fIsubject\fP;
@@ -208,11 +220,12 @@
   PCRE2_SPTR    \fIcallout_string\fP;
 .sp
 The \fIversion\fP field contains the version number of the block format. The
-current version is 1; the three callout string fields were added for this
-version. If you are writing an application that might use an earlier release of
-PCRE2, you should check the version number before accessing any of these
-fields. The version number will increase in future if more fields are added,
-but the intention is never to remove any of the existing fields.
+current version is 2; the three callout string fields were added for version 1,
+and the \fIcallout_flags\fP field for version 2. If you are writing an
+application that might use an earlier release of PCRE2, you should check the
+version number before accessing any of these fields. The version number will
+increase in future if more fields are added, but the intention is never to
+remove any of the existing fields.
 .
 .
 .SS "Fields for numerical callouts"
@@ -220,8 +233,8 @@
 .sp
 For a numerical callout, \fIcallout_string\fP is NULL, and \fIcallout_number\fP
 contains the number of the callout, in the range 0-255. This is the number
-that follows (?C for manual callouts; it is 255 for automatically generated
-callouts.
+that follows (?C for callouts that part of the pattern; it is 255 for
+automatically generated callouts.
 .
 .
 .SS "Fields for string callouts"
@@ -250,12 +263,38 @@
 The remaining fields in the callout block are the same for both kinds of
 callout.
 .P
-The \fIoffset_vector\fP field is a pointer to the vector of capturing offsets
-(the "ovector") that was passed to the matching function in the match data
-block. When \fBpcre2_match()\fP is used, the contents can be inspected in
+The \fIoffset_vector\fP field is a pointer to a vector of capturing offsets
+(the "ovector"). You may read the elements in this vector, but you must not
+change any of them.
+.P
+For calls to \fBpcre2_match()\fP, the \fIoffset_vector\fP field is not (since
+release 10.30) a pointer to the actual ovector that was passed to the matching
+function in the match data block. Instead it points to an internal ovector of a
+size large enough to hold all possible captured substrings in the pattern. Note
+that whenever a recursion or subroutine call within a pattern completes, the
+capturing state is reset to what it was before.
+.P
+The \fIcapture_last\fP field contains the number of the most recently captured
+substring, and the \fIcapture_top\fP field contains one more than the number of
+the highest numbered captured substring so far. If no substrings have yet been
+captured, the value of \fIcapture_last\fP is 0 and the value of
+\fIcapture_top\fP is 1. The values of these fields do not always differ by one;
+for example, when the callout in the pattern ((a)(b))(?C2) is taken,
+\fIcapture_last\fP is 1 but \fIcapture_top\fP is 4.
+.P
+The contents of ovector[2] to ovector[<capture_top>*2-1] can be inspected in
 order to extract substrings that have been matched so far, in the same way as
-for extracting substrings after a match has completed. For the DFA matching
-function, this field is not useful.
+extracting substrings after a match has completed. The values in ovector[0] and
+ovector[1] are always PCRE2_UNSET because the match is by definition not
+complete. Substrings that have not been captured but whose numbers are less
+than \fIcapture_top\fP also have both of their ovector slots set to
+PCRE2_UNSET.
+.P
+For DFA matching, the \fIoffset_vector\fP field points to the ovector that was
+passed to the matching function in the match data block, but it holds no useful
+information at callout time because \fBpcre2_dfa_match()\fP does not support
+substring capturing. The value of \fIcapture_top\fP is always 1 and the value
+of \fIcapture_last\fP is always 0 for DFA matching.
 .P
 The \fIsubject\fP and \fIsubject_length\fP fields contain copies of the values
 that were passed to the matching function.
@@ -270,26 +309,19 @@
 The \fIcurrent_position\fP field contains the offset within the subject of the
 current match pointer.
 .P
-When the \fBpcre2_match()\fP is used, the \fIcapture_top\fP field contains one
-more than the number of the highest numbered captured substring so far. If no
-substrings have been captured, the value of \fIcapture_top\fP is one. This is
-always the case when the DFA functions are used, because they do not support
-captured substrings.
-.P
-The \fIcapture_last\fP field contains the number of the most recently captured
-substring. However, when a recursion exits, the value reverts to what it was
-outside the recursion, as do the values of all captured substrings. If no
-substrings have been captured, the value of \fIcapture_last\fP is 0. This is
-always the case for the DFA matching functions.
-.P
 The \fIpattern_position\fP field contains the offset in the pattern string to
 the next item to be matched.
 .P
 The \fInext_item_length\fP field contains the length of the next item to be
-matched in the pattern string. When the callout immediately precedes an
-alternation bar, a closing parenthesis, or the end of the pattern, the length
-is zero. When the callout precedes an opening parenthesis, the length is that
-of the entire subpattern.
+processed in the pattern string. When the callout is at the end of the pattern,
+the length is zero. When the callout precedes an opening parenthesis, the
+length includes meta characters that follow the parenthesis. For example, in a
+callout before an assertion such as (?=ab) the length is 3. For an an
+alternation bar or a closing parenthesis, the length is one, unless a closing
+parenthesis is followed by a quantifier, in which case its length is included.
+(This changed in release 10.23. In earlier releases, before an opening
+parenthesis the length was that of the entire subpattern, and before an
+alternation bar or a closing parenthesis the length was zero.)
 .P
 The \fIpattern_position\fP and \fInext_item_length\fP fields are intended to
 help in distinguishing between different automatic callouts, which all have the
@@ -302,6 +334,33 @@
 (*THEN) item in the match, or NULL if no such items have been passed. Instances
 of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In
 callouts from the DFA matching function this field always contains NULL.
+.P
+The \fIcallout_flags\fP field is always zero in callouts from
+\fBpcre2_dfa_match()\fP or when JIT is being used. When \fBpcre2_match()\fP
+without JIT is used, the following bits may be set:
+.sp
+  PCRE2_CALLOUT_STARTMATCH
+.sp
+This is set for the first callout after the start of matching for each new
+starting position in the subject.
+.sp
+  PCRE2_CALLOUT_BACKTRACK
+.sp
+This is set if there has been a matching backtrack since the previous callout,
+or since the start of matching if this is the first callout from a
+\fBpcre2_match()\fP run.
+.P
+Both bits are set when a backtrack has caused a "bumpalong" to a new starting
+position in the subject. Output from \fBpcre2test\fP does not indicate the
+presence of these bits unless the \fBcallout_extra\fP modifier is set.
+.P
+The information in the \fBcallout_flags\fP field is provided so that
+applications can track and tell their users how matching with backtracking is
+done. This can be useful when trying to optimize patterns, or just to
+understand how PCRE2 works. There is no support in \fBpcre2_dfa_match()\fP
+because there is no backtracking in DFA matching, and there is no support in
+JIT because JIT is all about maximimizing matching performance. In both these
+cases the \fBcallout_flags\fP field is always zero.
 .
 .
 .SH "RETURN VALUES FROM CALLOUTS"
@@ -382,6 +441,6 @@
 .rs
 .sp
 .nf
-Last updated: 23 March 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 22 December 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2compat.3 b/dist2/doc/pcre2compat.3
index a3306d7..8094ebd 100644
--- a/dist2/doc/pcre2compat.3
+++ b/dist2/doc/pcre2compat.3
@@ -1,4 +1,4 @@
-.TH PCRE2COMPAT 3 "15 March 2015" "PCRE2 10.20"
+.TH PCRE2COMPAT 3 "18 April 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "DIFFERENCES BETWEEN PCRE2 AND PERL"
@@ -6,7 +6,8 @@
 .sp
 This document describes the differences in the ways that PCRE2 and Perl handle
 regular expressions. The differences described here are with respect to Perl
-versions 5.10 and above.
+versions 5.26, but as both Perl and PCRE2 are continually changing, the
+information may sometimes be out of date.
 .P
 1. PCRE2 has only a subset of Perl's Unicode support. Details of what it does
 have are given in the
@@ -15,16 +16,17 @@
 .\"
 page.
 .P
-2. PCRE2 allows repeat quantifiers only on parenthesized assertions, but they
-do not mean what you might think. For example, (?!a){3} does not assert that
-the next three characters are not "a". It just asserts that the next character
-is not "a" three times (in principle: PCRE2 optimizes this to run the assertion
-just once). Perl allows repeat quantifiers on other assertions such as \eb, but
-these do not seem to have any use.
+2. Like Perl, PCRE2 allows repeat quantifiers on parenthesized assertions, but
+they do not mean what you might think. For example, (?!a){3} does not assert
+that the next three characters are not "a". It just asserts that the next
+character is not "a" three times (in principle: PCRE2 optimizes this to run the
+assertion just once). Perl allows some repeat quantifiers on other assertions,
+for example, \eb* (but not \eb{3}), but these do not seem to have any use.
 .P
-3. Capturing subpatterns that occur inside negative lookahead assertions are
-counted, but their entries in the offsets vector are never set. Perl sometimes
-(but not always) sets its numerical variables from inside negative assertions.
+3. Capturing subpatterns that occur inside negative lookaround assertions are
+counted, but their entries in the offsets vector are set only when a negative
+assertion is a condition that has a matching branch (that is, the condition is
+false).
 .P
 4. The following Perl escape sequences are not supported: \el, \eu, \eL,
 \eU, and \eN when followed by a character name or Unicode value. (\eN on its
@@ -35,13 +37,13 @@
 \eU and \eu are interpreted as ECMAScript interprets them.
 .P
 5. The Perl escape sequences \ep, \eP, and \eX are supported only if PCRE2 is
-built with Unicode support. The properties that can be tested with \ep and \eP
-are limited to the general category properties such as Lu and Nd, script names
-such as Greek or Han, and the derived properties Any and L&. PCRE2 does support
-the Cs (surrogate) property, which Perl does not; the Perl documentation says
-"Because Perl hides the need for the user to understand the internal
-representation of Unicode characters, there is no need to implement the
-somewhat messy concept of surrogates."
+built with Unicode support (the default). The properties that can be tested
+with \ep and \eP are limited to the general category properties such as Lu and
+Nd, script names such as Greek or Han, and the derived properties Any and L&.
+PCRE2 does support the Cs (surrogate) property, which Perl does not; the Perl
+documentation says "Because Perl hides the need for the user to understand the
+internal representation of Unicode characters, there is no need to implement
+the somewhat messy concept of surrogates."
 .P
 6. PCRE2 does support the \eQ...\eE escape for quoting substrings. Characters
 in between are treated as literals. This is slightly different from Perl in
@@ -60,29 +62,16 @@
 The \eQ...\eE sequence is recognized both inside and outside character classes.
 .P
 7. Fairly obviously, PCRE2 does not support the (?{code}) and (??{code})
-constructions. However, there is support for recursive patterns. This is not
-available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE2 "callout"
-feature allows an external function to be called during pattern matching. See
-the
+constructions. However, there is support PCRE2's "callout" feature, which
+allows an external function to be called during pattern matching. See the
 .\" HREF
 \fBpcre2callout\fP
 .\"
 documentation for details.
 .P
-8. Subroutine calls (whether recursive or not) are treated as atomic groups.
-Atomic recursion is like Python, but unlike Perl. Captured values that are set
-outside a subroutine call can be referenced from inside in PCRE2, but not in
-Perl. There is a discussion that explains these differences in more detail in
-the
-.\" HTML <a href="pcre2pattern.html#recursiondifference">
-.\" </a>
-section on recursion differences from Perl
-.\"
-in the
-.\" HREF
-\fBpcre2pattern\fP
-.\"
-page.
+8. Subroutine calls (whether recursive or not) were treated as atomic groups up
+to PCRE2 release 10.23, but from release 10.30 this changed, and backtracking
+into subroutine calls is now supported, as in Perl.
 .P
 9. If any of the backtracking control verbs are used in a subpattern that is
 called as a subroutine (whether or not recursively), their effect is confined
@@ -96,7 +85,7 @@
 one that is backtracked onto acts. For example, in the pattern
 A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure in C
 triggers (*PRUNE). Perl's behaviour is more complex; in many cases it is the
-same as PCRE2, but there are examples where it differs.
+same as PCRE2, but there are cases where it differs.
 .P
 11. Most backtracking verbs in assertions have their normal actions. They are
 not confined to the assertion.
@@ -109,17 +98,18 @@
 13. PCRE2's handling of duplicate subpattern numbers and duplicate subpattern
 names is not as general as Perl's. This is a consequence of the fact the PCRE2
 works internally just with numbers, using an external table to translate
-between numbers and names. In particular, a pattern such as (?|(?<a>A)|(?<b)B),
+between numbers and names. In particular, a pattern such as (?|(?<a>A)|(?<b>B),
 where the two capturing parentheses have the same number but different names,
 is not supported, and causes an error at compile time. If it were allowed, it
 would not be possible to distinguish which parentheses matched, because both
 names map to capturing subpattern number 1. To avoid this confusing situation,
 an error is given at compile time.
 .P
-14. Perl recognizes comments in some places that PCRE2 does not, for example,
-between the ( and ? at the start of a subpattern. If the /x modifier is set,
-Perl allows white space between ( and ? (though current Perls warn that this is
-deprecated) but PCRE2 never does, even if the PCRE2_EXTENDED option is set.
+14. Perl used to recognize comments in some places that PCRE2 does not, for
+example, between the ( and ? at the start of a subpattern. If the /x modifier
+is set, Perl allowed white space between ( and ? though the latest Perls give
+an error (for a while it was just deprecated). There may still be some cases
+where Perl behaves differently.
 .P
 15. Perl, when in warning mode, gives warnings for character classes such as
 [A-\ed] or [a-[:digit:]]. It then treats the hyphens as literals. PCRE2 has no
@@ -129,46 +119,65 @@
 16. In PCRE2, the upper/lower case character properties Lu and Ll are not
 affected when case-independent matching is specified. For example, \ep{Lu}
 always matches an upper case letter. I think Perl has changed in this respect;
-in the release at the time of writing (5.16), \ep{Lu} and \ep{Ll} match all
+in the release at the time of writing (5.24), \ep{Lu} and \ep{Ll} match all
 letters, regardless of case, when case independence is specified.
 .P
 17. PCRE2 provides some extensions to the Perl regular expression facilities.
 Perl 5.10 includes new features that are not in earlier versions of Perl, some
-of which (such as named parentheses) have been in PCRE2 for some time. This
-list is with respect to Perl 5.10:
+of which (such as named parentheses) were in PCRE2 for some time before. This
+list is with respect to Perl 5.26:
 .sp
 (a) Although lookbehind assertions in PCRE2 must match fixed length strings,
 each alternative branch of a lookbehind assertion can match a different length
 of string. Perl requires them all to have the same length.
 .sp
-(b) If PCRE2_DOLLAR_ENDONLY is set and PCRE2_MULTILINE is not set, the $
+(b) From PCRE2 10.23, back references to groups of fixed length are supported
+in lookbehinds, provided that there is no possibility of referencing a
+non-unique number or name. Perl does not support backreferences in lookbehinds.
+.sp
+(c) If PCRE2_DOLLAR_ENDONLY is set and PCRE2_MULTILINE is not set, the $
 meta-character matches only at the very end of the string.
 .sp
-(c) A backslash followed by a letter with no special meaning is faulted. (Perl
+(d) A backslash followed by a letter with no special meaning is faulted. (Perl
 can be made to issue a warning.)
 .sp
-(d) If PCRE2_UNGREEDY is set, the greediness of the repetition quantifiers is
+(e) If PCRE2_UNGREEDY is set, the greediness of the repetition quantifiers is
 inverted, that is, by default they are not greedy, but if followed by a
 question mark they are.
 .sp
-(e) PCRE2_ANCHORED can be used at matching time to force a pattern to be tried
+(f) PCRE2_ANCHORED can be used at matching time to force a pattern to be tried
 only at the first matching position in the subject string.
 .sp
-(f) The PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY, PCRE2_NOTEMPTY_ATSTART, and
-PCRE2_NO_AUTO_CAPTURE options have no Perl equivalents.
+(g) The PCRE2_NOTBOL, PCRE2_NOTEOL, PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART
+options have no Perl equivalents.
 .sp
-(g) The \eR escape sequence can be restricted to match only CR, LF, or CRLF
+(h) The \eR escape sequence can be restricted to match only CR, LF, or CRLF
 by the PCRE2_BSR_ANYCRLF option.
 .sp
-(h) The callout facility is PCRE2-specific.
+(i) The callout facility is PCRE2-specific. Perl supports codeblocks and
+variable interpolation, but not general hooks on every match.
 .sp
-(i) The partial matching facility is PCRE2-specific.
+(j) The partial matching facility is PCRE2-specific.
 .sp
-(j) The alternative matching function (\fBpcre2_dfa_match()\fP matches in a
+(k) The alternative matching function (\fBpcre2_dfa_match()\fP matches in a
 different way and is not Perl-compatible.
 .sp
-(k) PCRE2 recognizes some special sequences such as (*CR) at the start of
-a pattern that set overall options that cannot be changed within the pattern.
+(l) PCRE2 recognizes some special sequences such as (*CR) or (*NO_JIT) at
+the start of a pattern that set overall options that cannot be changed within
+the pattern.
+.P
+18. The Perl /a modifier restricts /d numbers to pure ascii, and the /aa
+modifier restricts /i case-insensitive matching to pure ascii, ignoring Unicode
+rules. This separation cannot be represented with PCRE2_UCP.
+.P
+19. Perl has different limits than PCRE2. See the
+.\" HREF
+\fBpcre2limit\fP
+.\"
+documentation for details. Perl went with 5.10 from recursion to iteration
+keeping the intermediate matches on the heap, which is ~10% slower but does not
+fall into any stack-overflow limit. PCRE2 made a similar change at release
+10.30, and also has many build-time and run-time customizable limits.
 .
 .
 .SH AUTHOR
@@ -185,6 +194,6 @@
 .rs
 .sp
 .nf
-Last updated: 15 March 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 18 April 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2convert.3 b/dist2/doc/pcre2convert.3
new file mode 100644
index 0000000..3dadf6e
--- /dev/null
+++ b/dist2/doc/pcre2convert.3
@@ -0,0 +1,163 @@
+.TH PCRE2CONVERT 3 "12 July 2017" "PCRE2 10.30"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH "EXPERIMENTAL PATTERN CONVERSION FUNCTIONS"
+.rs
+.sp
+This document describes a set of functions that can be used to convert
+"foreign" patterns into PCRE2 regular expressions. This facility is currently
+experimental, and may be changed in future releases. Two kinds of pattern,
+globs and POSIX patterns, are supported.
+.
+.
+.SH "THE CONVERT CONTEXT"
+.rs
+.sp
+.nf
+.B pcre2_convert_context *pcre2_convert_context_create(
+.B "  pcre2_general_context *\fIgcontext\fP);"
+.sp
+.B pcre2_convert_context *pcre2_convert_context_copy(
+.B "  pcre2_convert_context *\fIcvcontext\fP);"
+.sp
+.B void pcre2_convert_context_free(pcre2_convert_context *\fIcvcontext\fP);
+.sp
+.B int pcre2_set_glob_escape(pcre2_convert_context *\fIcvcontext\fP,
+.B "  uint32_t \fIescape_char\fP);"
+.sp
+.B int pcre2_set_glob_separator(pcre2_convert_context *\fIcvcontext\fP,
+.B "  uint32_t \fIseparator_char\fP);"
+.fi
+.sp
+A convert context is used to hold parameters that affect the way that pattern
+conversion works. Like all PCRE2 contexts, you need to use a context only if
+you want to override the defaults. There are the usual create, copy, and free
+functions. If custom memory management functions are set in a general context
+that is passed to \fBpcre2_convert_context_create()\fP, they are used for all
+memory management within the conversion functions.
+.P
+There are only two parameters in the convert context at present. Both apply
+only to glob conversions. The escape character defaults to grave accent under
+Windows, otherwise backslash. It can be set to zero, meaning no escape
+character, or to any punctuation character with a code point less than 256.
+The separator character defaults to backslash under Windows, otherwise forward
+slash. It can be set to forward slash, backslash, or dot.
+.P
+The two setting functions return zero on success, or PCRE2_ERROR_BADDATA if
+their second argument is invalid.
+.
+.
+.SH "THE CONVERSION FUNCTION"
+.rs
+.sp
+.nf
+.B int pcre2_pattern_convert(PCRE2_SPTR \fIpattern\fP, PCRE2_SIZE \fIlength\fP,
+.B "  uint32_t \fIoptions\fP, PCRE2_UCHAR **\fIbuffer\fP,"
+.B "  PCRE2_SIZE *\fIblength\fP, pcre2_convert_context *\fIcvcontext\fP);"
+.sp
+.B void pcre2_converted_pattern_free(PCRE2_UCHAR *\fIconverted_pattern\fP);
+.fi
+.sp
+The first two arguments of \fBpcre2_pattern_convert()\fP define the foreign
+pattern that is to be converted. The length may be given as
+PCRE2_ZERO_TERMINATED. The \fBoptions\fP argument defines how the pattern is to
+be processed. If the input is UTF, the PCRE2_CONVERT_UTF option should be set.
+PCRE2_CONVERT_NO_UTF_CHECK may also be set if you are sure the input is valid.
+One or more of the glob options, or one of the following POSIX options must be
+set to define the type of conversion that is required:
+.sp
+  PCRE2_CONVERT_GLOB
+  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR
+  PCRE2_CONVERT_GLOB_NO_STARSTAR
+  PCRE2_CONVERT_POSIX_BASIC
+  PCRE2_CONVERT_POSIX_EXTENDED
+.sp
+Details of the conversions are given below. The \fBbuffer\fP and \fBblength\fP
+arguments define how the output is handled:
+.P
+If \fBbuffer\fP is NULL, the function just returns the length of the converted
+pattern via \fBblength\fP. This is one less than the length of buffer needed,
+because a terminating zero is always added to the output.
+.P
+If \fBbuffer\fP points to a NULL pointer, an output buffer is obtained using
+the allocator in the context or \fBmalloc()\fP if no context is supplied. A
+pointer to this buffer is placed in the variable to which \fBbuffer\fP points.
+When no longer needed the output buffer must be freed by calling
+\fBpcre2_converted_pattern_free()\fP.
+.P
+If \fBbuffer\fP points to a non-NULL pointer, \fBblength\fP must be set to the
+actual length of the buffer provided (in code units).
+.P
+In all cases, after successful conversion, the variable pointed to by
+\fBblength\fP is updated to the length actually used (in code units), excluding
+the terminating zero that is always added.
+.P
+If an error occurs, the length (via \fBblength\fP) is set to the offset
+within the input pattern where the error was detected. Only gross syntax errors
+are caught; there are plenty of errors that will get passed on for
+\fBpcre2_compile()\fP to discover.
+.P
+The return from \fBpcre2_pattern_convert()\fP is zero on success or a non-zero
+PCRE2 error code. Note that PCRE2 error codes may be positive or negative:
+\fBpcre2_compile()\fP uses mostly positive codes and \fBpcre2_match()\fP
+negative ones; \fBpcre2_convert()\fP uses existing codes of both kinds. A
+textual error message can be obtained by calling
+\fBpcre2_get_error_message()\fP.
+.
+.
+.SH "CONVERTING GLOBS"
+.rs
+.sp
+Globs are used to match file names, and consequently have the concept of a
+"path separator", which defaults to backslash under Windows and forward slash
+otherwise. If PCRE2_CONVERT_GLOB is set, the wildcards * and ? are not
+permitted to match separator characters, but the double-star (**) feature
+(which does match separators) is supported.
+.P
+PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR matches globs with wildcards allowed to
+match separator characters. PCRE2_GLOB_NO_STARSTAR matches globs with the
+double-star feature disabled. These options may be given together.
+.
+.
+.SH "CONVERTING POSIX PATTERNS"
+.rs
+.sp
+POSIX defines two kinds of regular expression pattern: basic and extended.
+These can be processed by setting PCRE2_CONVERT_POSIX_BASIC or
+PCRE2_CONVERT_POSIX_EXTENDED, respectively.
+.P
+In POSIX patterns, backslash is not special in a character class. Unmatched
+closing parentheses are treated as literals.
+.P
+In basic patterns, ? + | {} and () must be escaped to be recognized
+as metacharacters outside a character class. If the first character in the
+pattern is * it is treated as a literal. ^ is a metacharacter only at the start
+of a branch.
+.P
+In extended patterns, a backslash not in a character class always
+makes the next character literal, whatever it is. There are no backreferences.
+.P
+Note: POSIX mandates that the longest possible match at the first matching
+position must be found. This is not what \fBpcre2_match()\fP does; it yields
+the first match that is found. An application can use \fBpcre2_dfa_match()\fP
+to find the longest match, but that does not support backreferences (but then
+neither do POSIX extended patterns).
+.
+.
+.SH AUTHOR
+.rs
+.sp
+.nf
+Philip Hazel
+University Computing Service
+Cambridge, England.
+.fi
+.
+.
+.SH REVISION
+.rs
+.sp
+.nf
+Last updated: 12 July 2017
+Copyright (c) 1997-2017 University of Cambridge.
+.fi
diff --git a/dist2/doc/pcre2demo.3 b/dist2/doc/pcre2demo.3
index c02dcd9..a9e58e2 100644
--- a/dist2/doc/pcre2demo.3
+++ b/dist2/doc/pcre2demo.3
@@ -228,6 +228,21 @@
 if (rc == 0)
   printf("ovector was not big enough for all the captured substrings\en");
 
+/* We must guard against patterns such as /(?=.\eK)/ that use \eK in an assertion
+to set the start of a match later than its end. In this demonstration program,
+we just detect this case and give up. */
+
+if (ovector[0] > ovector[1])
+  {
+  printf("\e\eK was used in an assertion to set the match start after its end.\en"
+    "From end to start the match was: %.*s\en", (int)(ovector[0] - ovector[1]),
+      (char *)(subject + ovector[1]));
+  printf("Run abandoned\en");
+  pcre2_match_data_free(match_data);
+  pcre2_code_free(re);
+  return 1;
+  }
+
 /* Show substrings stored in the output vector by number. Obviously, in a real
 application you might want to do things other than print them. */
 
@@ -355,6 +370,29 @@
     options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
     }
 
+  /* If the previous match was not an empty string, there is one tricky case to
+  consider. If a pattern contains \eK within a lookbehind assertion at the
+  start, the end of the matched string can be at the offset where the match
+  started. Without special action, this leads to a loop that keeps on matching
+  the same substring. We must detect this case and arrange to move the start on
+  by one character. The pcre2_get_startchar() function returns the starting
+  offset that was passed to pcre2_match(). */
+
+  else
+    {
+    PCRE2_SIZE startchar = pcre2_get_startchar(match_data);
+    if (start_offset <= startchar)
+      {
+      if (startchar >= subject_length) break;   /* Reached end of subject.   */
+      start_offset = startchar + 1;             /* Advance by one character. */
+      if (utf8)                                 /* If UTF-8, it may be more  */
+        {                                       /*   than one code unit.     */
+        for (; start_offset < subject_length; start_offset++)
+          if ((subject[start_offset] & 0xc0) != 0x80) break;
+        }
+      }
+    }
+
   /* Run the next matching operation */
 
   rc = pcre2_match(
@@ -419,6 +457,21 @@
   if (rc == 0)
     printf("ovector was not big enough for all the captured substrings\en");
 
+  /* We must guard against patterns such as /(?=.\eK)/ that use \eK in an
+  assertion to set the start of a match later than its end. In this
+  demonstration program, we just detect this case and give up. */
+
+  if (ovector[0] > ovector[1])
+    {
+    printf("\e\eK was used in an assertion to set the match start after its end.\en"
+      "From end to start the match was: %.*s\en", (int)(ovector[0] - ovector[1]),
+        (char *)(subject + ovector[1]));
+    printf("Run abandoned\en");
+    pcre2_match_data_free(match_data);
+    pcre2_code_free(re);
+    return 1;
+    }
+
   /* As before, show substrings stored in the output vector by number, and then
   also any named substrings. */
 
diff --git a/dist2/doc/pcre2grep.1 b/dist2/doc/pcre2grep.1
index 6d27780..5e5cbea 100644
--- a/dist2/doc/pcre2grep.1
+++ b/dist2/doc/pcre2grep.1
@@ -1,4 +1,4 @@
-.TH PCRE2GREP 1 "19 June 2016" "PCRE2 10.22"
+.TH PCRE2GREP 1 "13 November 2017" "PCRE2 10.31"
 .SH NAME
 pcre2grep - a grep with Perl-compatible regular expressions.
 .SH SYNOPSIS
@@ -52,11 +52,18 @@
 \fB-N\fP (\fB--newline\fP) option.
 .P
 The amount of memory used for buffering files that are being scanned is
-controlled by a parameter that can be set by the \fB--buffer-size\fP option.
-The default value for this parameter is specified when \fBpcre2grep\fP is
-built, with the default default being 20K. A block of memory three times this
-size is used (to allow for buffering "before" and "after" lines). An error
-occurs if a line overflows the buffer.
+controlled by parameters that can be set by the \fB--buffer-size\fP and
+\fB--max-buffer-size\fP options. The first of these sets the size of buffer
+that is obtained at the start of processing. If an input file contains very
+long lines, a larger buffer may be needed; this is handled by automatically
+extending the buffer, up to the limit specified by \fB--max-buffer-size\fP. The
+default values for these parameters are specified when \fBpcre2grep\fP is
+built, with the default defaults being 20K and 1M respectively. An error occurs
+if a line is too long and the buffer can no longer be expanded.
+.P
+The block of memory that is actually used is three times the "buffer size", to
+allow for buffering "before" and "after" lines. If the buffer size is too
+small, fewer than requested "before" and "after" lines may be output.
 .P
 Patterns can be no longer than 8K or BUFSIZ bytes, whichever is the greater.
 BUFSIZ is defined in \fB<stdio.h>\fP. When there is more than one pattern
@@ -94,27 +101,31 @@
 .rs
 .sp
 It is possible to compile \fBpcre2grep\fP so that it uses \fBlibz\fP or
-\fBlibbz2\fP to read files whose names end in \fB.gz\fP or \fB.bz2\fP,
-respectively. You can find out whether your binary has support for one or both
-of these file types by running it with the \fB--help\fP option. If the
-appropriate support is not present, files are treated as plain text. The
-standard input is always so treated.
+\fBlibbz2\fP to read compressed files whose names end in \fB.gz\fP or
+\fB.bz2\fP, respectively. You can find out whether your \fBpcre2grep\fP binary
+has support for one or both of these file types by running it with the
+\fB--help\fP option. If the appropriate support is not present, all files are
+treated as plain text. The standard input is always so treated. When input is
+from a compressed .gz or .bz2 file, the \fB--line-buffered\fP option is
+ignored.
 .
 .
 .SH "BINARY FILES"
 .rs
 .sp
 By default, a file that contains a binary zero byte within the first 1024 bytes
-is identified as a binary file, and is processed specially. (GNU grep also
-identifies binary files in this manner.) See the \fB--binary-files\fP option
-for a means of changing the way binary files are handled.
+is identified as a binary file, and is processed specially. (GNU grep
+identifies binary files in this manner.) However, if the newline type is
+specified as "nul", that is, the line terminator is a binary zero, the test for
+a binary file is not applied. See the \fB--binary-files\fP option for a means
+of changing the way binary files are handled.
 .
 .
 .SH OPTIONS
 .rs
 .sp
 The order in which some of the options appear can affect the output. For
-example, both the \fB-h\fP and \fB-l\fP options affect the printing of file
+example, both the \fB-H\fP and \fB-l\fP options affect the printing of file
 names. Whichever comes later in the command line will be the one that takes
 effect. Similarly, except where noted below, if an option is given twice, the
 later setting is used. Numerical values for options may be followed by K or M,
@@ -126,24 +137,27 @@
 processing of patterns and file names that start with hyphens.
 .TP
 \fB-A\fP \fInumber\fP, \fB--after-context=\fP\fInumber\fP
-Output \fInumber\fP lines of context after each matching line. If file names
-and/or line numbers are being output, a hyphen separator is used instead of a
-colon for the context lines. A line containing "--" is output between each
-group of lines, unless they are in fact contiguous in the input file. The value
-of \fInumber\fP is expected to be relatively small. However, \fBpcre2grep\fP
-guarantees to have up to 8K of following text available for context output.
+Output up to \fInumber\fP lines of context after each matching line. Fewer
+lines are output if the next match or the end of the file is reached, or if the
+processing buffer size has been set too small. If file names and/or line
+numbers are being output, a hyphen separator is used instead of a colon for the
+context lines. A line containing "--" is output between each group of lines,
+unless they are in fact contiguous in the input file. The value of \fInumber\fP
+is expected to be relatively small. When \fB-c\fP is used, \fB-A\fP is ignored.
 .TP
 \fB-a\fP, \fB--text\fP
 Treat binary files as text. This is equivalent to
 \fB--binary-files\fP=\fItext\fP.
 .TP
 \fB-B\fP \fInumber\fP, \fB--before-context=\fP\fInumber\fP
-Output \fInumber\fP lines of context before each matching line. If file names
-and/or line numbers are being output, a hyphen separator is used instead of a
-colon for the context lines. A line containing "--" is output between each
-group of lines, unless they are in fact contiguous in the input file. The value
-of \fInumber\fP is expected to be relatively small. However, \fBpcre2grep\fP
-guarantees to have up to 8K of preceding text available for context output.
+Output up to \fInumber\fP lines of context before each matching line. Fewer
+lines are output if the previous match or the start of the file is within
+\fInumber\fP lines, or if the processing buffer size has been set too small. If
+file names and/or line numbers are being output, a hyphen separator is used
+instead of a colon for the context lines. A line containing "--" is output
+between each group of lines, unless they are in fact contiguous in the input
+file. The value of \fInumber\fP is expected to be relatively small. When
+\fB-c\fP is used, \fB-B\fP is ignored.
 .TP
 \fB--binary-files=\fP\fIword\fP
 Specify how binary files are to be processed. If the word is "binary" (the
@@ -158,8 +172,9 @@
 return code.
 .TP
 \fB--buffer-size=\fP\fInumber\fP
-Set the parameter that controls how much memory is used for buffering files
-that are being scanned.
+Set the parameter that controls how much memory is obtained at the start of
+processing for buffering files that are being scanned. See also
+\fB--max-buffer-size\fP below.
 .TP
 \fB-C\fP \fInumber\fP, \fB--context=\fP\fInumber\fP
 Output \fInumber\fP lines of context both before and after each matching line.
@@ -167,13 +182,15 @@
 .TP
 \fB-c\fP, \fB--count\fP
 Do not output lines from the files that are being scanned; instead output the
-number of matches (or non-matches if \fB-v\fP is used) that would otherwise
-have caused lines to be shown. By default, this count is the same as the number
-of suppressed lines, but if the \fB-M\fP (multiline) option is used (without
-\fB-v\fP), there may be more suppressed lines than the number of matches.
+number of lines that would have been shown, either because they matched, or, if
+\fB-v\fP is set, because they failed to match. By default, this count is
+exactly the same as the number of lines that would have been output, but if the
+\fB-M\fP (multiline) option is used (without \fB-v\fP), there may be more
+suppressed lines than the count (that is, the number of matches).
 .sp
 If no lines are selected, the number zero is output. If several files are are
-being scanned, a count is output for each of them. However, if the
+being scanned, a count is output for each of them and the \fB-t\fP option can
+be used to cause a total to be output at the end. However, if the
 \fB--files-with-matches\fP option is also used, only those files whose counts
 are greater than zero are listed. When \fB-c\fP is used, the \fB-A\fP,
 \fB-B\fP, and \fB-C\fP options are ignored.
@@ -192,12 +209,22 @@
 because \fBpcre2grep\fP has to search for all possible matches in a line, not
 just one, in order to colour them all.
 .sp
-The colour that is used can be specified by setting the environment variable
-PCRE2GREP_COLOUR or PCRE2GREP_COLOR. The value of this variable should be a
-string of two numbers, separated by a semicolon. They are copied directly into
-the control string for setting colour on a terminal, so it is your
-responsibility to ensure that they make sense. If neither of the environment
-variables is set, the default is "1;31", which gives red.
+The colour that is used can be specified by setting one of the environment
+variables PCRE2GREP_COLOUR, PCRE2GREP_COLOR, PCREGREP_COLOUR, or
+PCREGREP_COLOR, which are checked in that order. If none of these are set,
+\fBpcre2grep\fP looks for GREP_COLORS or GREP_COLOR (in that order). The value
+of the variable should be a string of two numbers, separated by a semicolon,
+except in the case of GREP_COLORS, which must start with "ms=" or "mt="
+followed by two semicolon-separated colours, terminated by the end of the
+string or by a colon. If GREP_COLORS does not start with "ms=" or "mt=" it is
+ignored, and GREP_COLOR is checked.
+.sp
+If the string obtained from one of the above variables contains any characters
+other than semicolon or digits, the setting is ignored and the default colour
+is used. The string is copied directly into the control string for setting
+colour on a terminal, so it is your responsibility to ensure that the values
+make sense. If no relevant environment variable is set, the default is "1;31",
+which gives red.
 .TP
 \fB-D\fP \fIaction\fP, \fB--devices=\fP\fIaction\fP
 If an input path is not a regular file or a directory, "action" specifies how
@@ -213,6 +240,9 @@
 operating systems the effect of reading a directory like this is an immediate
 end-of-file; in others it may provoke an error.
 .TP
+\fB--depth-limit\fP=\fInumber\fP
+See \fB--match-limit\fP below.
+.TP
 \fB-e\fP \fIpattern\fP, \fB--regex=\fP\fIpattern\fP, \fB--regexp=\fP\fIpattern\fP
 Specify a pattern to be matched. This option can be used multiple times in
 order to specify several patterns. It can also be used as a way of specifying a
@@ -273,17 +303,17 @@
 \fB--exclude\fP options.
 .TP
 \fB-f\fP \fIfilename\fP, \fB--file=\fP\fIfilename\fP
-Read patterns from the file, one per line, and match them against
-each line of input. What constitutes a newline when reading the file is the
-operating system's default. The \fB--newline\fP option has no effect on this
-option. Trailing white space is removed from each line, and blank lines are
-ignored. An empty file contains no patterns and therefore matches nothing. See
-also the comments about multiple patterns versus a single pattern with
-alternatives in the description of \fB-e\fP above.
+Read patterns from the file, one per line, and match them against each line of
+input. What constitutes a newline when reading the file is the operating
+system's default. The \fB--newline\fP option has no effect on this option.
+Trailing white space is removed from each line, and blank lines are ignored. An
+empty file contains no patterns and therefore matches nothing. See also the
+comments about multiple patterns versus a single pattern with alternatives in
+the description of \fB-e\fP above.
 .sp
-If this option is given more than once, all the specified files are
-read. A data line is output if any of the patterns match it. A file name can
-be given as "-" to refer to the standard input. When \fB-f\fP is used, patterns
+If this option is given more than once, all the specified files are read. A
+data line is output if any of the patterns match it. A file name can be given
+as "-" to refer to the standard input. When \fB-f\fP is used, patterns
 specified on the command line using \fB-e\fP may also be present; they are
 tested before the file's patterns. However, no other pattern is taken from the
 command line; all arguments are treated as the names of paths to be searched.
@@ -304,8 +334,8 @@
 offset from the start of the file and a length, separated by a comma. In this
 mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and \fB-C\fP
 options are ignored. If there is more than one match in a line, each of them is
-shown separately. This option is mutually exclusive with \fB--line-offsets\fP
-and \fB--only-matching\fP.
+shown separately. This option is mutually exclusive with \fB--output\fP,
+\fB--line-offsets\fP, and \fB--only-matching\fP.
 .TP
 \fB-H\fP, \fB--with-filename\fP
 Force the inclusion of the file name at the start of output lines when
@@ -313,13 +343,18 @@
 For matching lines, the file name is followed by a colon; for context lines, a
 hyphen separator is used. If a line number is also being output, it follows the
 file name. When the \fB-M\fP option causes a pattern to match more than one
-line, only the first is preceded by the file name.
+line, only the first is preceded by the file name. This option overrides any
+previous \fB-h\fP, \fB-l\fP, or \fB-L\fP options.
 .TP
 \fB-h\fP, \fB--no-filename\fP
 Suppress the output file names when searching multiple files. By default,
 file names are shown when multiple files are searched. For matching lines, the
 file name is followed by a colon; for context lines, a hyphen separator is used.
-If a line number is also being output, it follows the file name.
+If a line number is also being output, it follows the file name. This option
+overrides any previous \fB-H\fP, \fB-L\fP, or \fB-l\fP options.
+.TP
+\fB--heap-limit\fP=\fInumber\fP
+See \fB--match-limit\fP below.
 .TP
 \fB--help\fP
 Output a help message, giving brief details of the command options and file
@@ -365,16 +400,18 @@
 \fB-L\fP, \fB--files-without-match\fP
 Instead of outputting lines from the files, just output the names of the files
 that do not contain any lines that would have been output. Each file name is
-output once, on a separate line.
+output once, on a separate line. This option overrides any previous \fB-H\fP,
+\fB-h\fP, or \fB-l\fP options.
 .TP
 \fB-l\fP, \fB--files-with-matches\fP
 Instead of outputting lines from the files, just output the names of the files
-containing lines that would have been output. Each file name is output
-once, on a separate line. Searching normally stops as soon as a matching line
-is found in a file. However, if the \fB-c\fP (count) option is also used,
-matching continues in order to obtain the correct count, and those files that
-have at least one match are listed along with their counts. Using this option
-with \fB-c\fP is a way of suppressing the listing of files with no matches.
+containing lines that would have been output. Each file name is output once, on
+a separate line. Searching normally stops as soon as a matching line is found
+in a file. However, if the \fB-c\fP (count) option is also used, matching
+continues in order to obtain the correct count, and those files that have at
+least one match are listed along with their counts. Using this option with
+\fB-c\fP is a way of suppressing the listing of files with no matches. This
+opeion overrides any previous \fB-H\fP, \fB-h\fP, or \fB-L\fP options.
 .TP
 \fB--label\fP=\fIname\fP
 This option supplies a name to be used for the standard input when file names
@@ -382,14 +419,16 @@
 short form for this option.
 .TP
 \fB--line-buffered\fP
-When this option is given, input is read and processed line by line, and the
-output is flushed after each write. By default, input is read in large chunks,
-unless \fBpcre2grep\fP can determine that it is reading from a terminal (which
-is currently possible only in Unix-like environments). Output to terminal is
-normally automatically flushed by the operating system. This option can be
-useful when the input or output is attached to a pipe and you do not want
-\fBpcre2grep\fP to buffer up large amounts of data. However, its use will
-affect performance, and the \fB-M\fP (multiline) option ceases to work.
+When this option is given, non-compressed input is read and processed line by
+line, and the output is flushed after each write. By default, input is read in
+large chunks, unless \fBpcre2grep\fP can determine that it is reading from a
+terminal (which is currently possible only in Unix-like environments). Output
+to terminal is normally automatically flushed by the operating system. This
+option can be useful when the input or output is attached to a pipe and you do
+not want \fBpcre2grep\fP to buffer up large amounts of data. However, its use
+will affect performance, and the \fB-M\fP (multiline) option ceases to work.
+When input is from a compressed .gz or .bz2 file, \fB--line-buffered\fP is
+ignored.
 .TP
 \fB--line-offsets\fP
 Instead of showing lines or parts of lines that match, show each match as a
@@ -398,7 +437,8 @@
 offset and length are separated by a comma. In this mode, no context is shown.
 That is, the \fB-A\fP, \fB-B\fP, and \fB-C\fP options are ignored. If there is
 more than one match in a line, each of them is shown separately. This option is
-mutually exclusive with \fB--file-offsets\fP and \fB--only-matching\fP.
+mutually exclusive with \fB--output\fP, \fB--file-offsets\fP, and
+\fB--only-matching\fP.
 .TP
 \fB--locale\fP=\fIlocale-name\fP
 This option specifies a locale to be used for pattern matching. It overrides
@@ -407,46 +447,51 @@
 used. There is no short form for this option.
 .TP
 \fB--match-limit\fP=\fInumber\fP
-Processing some regular expression patterns can require a very large amount of
-memory, leading in some cases to a program crash if not enough is available.
-Other patterns may take a very long time to search for all possible matching
-strings. The \fBpcre2_match()\fP function that is called by \fBpcre2grep\fP to
-do the matching has two parameters that can limit the resources that it uses.
+Processing some regular expression patterns may take a very long time to search
+for all possible matching strings. Others may require a very large amount of
+memory. There are three options that set resource limits for matching.
 .sp
-The \fB--match-limit\fP option provides a means of limiting resource usage
-when processing patterns that are not going to match, but which have a very
-large number of possibilities in their search trees. The classic example is a
-pattern that uses nested unlimited repeats. Internally, PCRE2 uses a function
-called \fBmatch()\fP which it calls repeatedly (sometimes recursively). The
-limit set by \fB--match-limit\fP is imposed on the number of times this
-function is called during a match, which has the effect of limiting the amount
-of backtracking that can take place.
+The \fB--match-limit\fP option provides a means of limiting computing resource
+usage when processing patterns that are not going to match, but which have a
+very large number of possibilities in their search trees. The classic example
+is a pattern that uses nested unlimited repeats. Internally, PCRE2 has a
+counter that is incremented each time around its main processing loop. If the
+value set by \fB--match-limit\fP is reached, an error occurs.
 .sp
-The \fB--recursion-limit\fP option is similar to \fB--match-limit\fP, but
-instead of limiting the total number of times that \fBmatch()\fP is called, it
-limits the depth of recursive calls, which in turn limits the amount of memory
-that can be used. The recursion depth is a smaller number than the total number
-of calls, because not all calls to \fBmatch()\fP are recursive. This limit is
-of use only if it is set smaller than \fB--match-limit\fP.
+The \fB--heap-limit\fP option specifies, as a number of kilobytes, the amount
+of heap memory that may be used for matching. Heap memory is needed only if
+matching the pattern requires a significant number of nested backtracking
+points to be remembered. This parameter can be set to zero to forbid the use of
+heap memory altogether.
+.sp
+The \fB--depth-limit\fP option limits the depth of nested backtracking points,
+which indirectly limits the amount of memory that is used. The amount of memory
+needed for each backtracking point depends on the number of capturing
+parentheses in the pattern, so the amount of memory that is used before this
+limit acts varies from pattern to pattern. This limit is of use only if it is
+set smaller than \fB--match-limit\fP.
 .sp
 There are no short forms for these options. The default settings are specified
-when the PCRE2 library is compiled, with the default default being 10 million.
+when the PCRE2 library is compiled, with the default defaults being very large
+and so effectively unlimited.
+.TP
+\fB--max-buffer-size=\fInumber\fP
+This limits the expansion of the processing buffer, whose initial size can be
+set by \fB--buffer-size\fP. The maximum buffer size is silently forced to be no
+smaller than the starting buffer size.
 .TP
 \fB-M\fP, \fB--multiline\fP
-Allow patterns to match more than one line. When this option is given, patterns
-may usefully contain literal newline characters and internal occurrences of ^
-and $ characters. The output for a successful match may consist of more than
-one line. The first is the line in which the match started, and the last is the
-line in which the match ended. If the matched string ends with a newline
-sequence the output ends at the end of that line.
-.sp
-When this option is set, the PCRE2 library is called in "multiline" mode. This
-allows a matched string to extend past the end of a line and continue on one or
-more subsequent lines. However, \fBpcre2grep\fP still processes the input line
-by line. Once a match has been handled, scanning restarts at the beginning of
-the next line, just as it does when \fB-M\fP is not present. This means that it
-is possible for the second or subsequent lines in a multiline match to be
-output again as part of another match.
+Allow patterns to match more than one line. When this option is set, the PCRE2
+library is called in "multiline" mode. This allows a matched string to extend
+past the end of a line and continue on one or more subsequent lines. Patterns
+used with \fB-M\fP may usefully contain literal newline characters and internal
+occurrences of ^ and $ characters. The output for a successful match may
+consist of more than one line. The first line is the line in which the match
+started, and the last line is the line in which the match ended. If the matched
+string ends with a newline sequence, the output ends at the end of that line.
+If \fB-v\fP is set, none of the lines in a multi-line match are output. Once a
+match has been handled, scanning restarts at the beginning of the line after
+the one in which the match ended.
 .sp
 The newline sequence that separates multiple lines must be matched as part of
 the pattern. For example, to find the phrase "regular expression" in a file
@@ -460,11 +505,8 @@
 well as possibly handling a two-character newline sequence.
 .sp
 There is a limit to the number of lines that can be matched, imposed by the way
-that \fBpcre2grep\fP buffers the input file as it scans it. However,
-\fBpcre2grep\fP ensures that at least 8K characters or the rest of the file
-(whichever is the shorter) are available for forward matching, and similarly
-the previous 8K characters (or all the previous characters, if fewer than 8K)
-are guaranteed to be available for lookbehind assertions. The \fB-M\fP option
+that \fBpcre2grep\fP buffers the input file as it scans it. With a sufficiently
+large processing buffer, this should not be a problem, but the \fB-M\fP option
 does not work when input is read line by line (see \fP--line-buffered\fP.)
 .TP
 \fB-N\fP \fInewline-type\fP, \fB--newline\fP=\fInewline-type\fP
@@ -503,16 +545,41 @@
 use of JIT at run time. It is provided for testing and working round problems.
 It should never be needed in normal use.
 .TP
+\fB-O\fP \fItext\fP, \fB--output\fP=\fItext\fP
+When there is a match, instead of outputting the whole line that matched,
+output just the given text. This option is mutually exclusive with
+\fB--only-matching\fP, \fB--file-offsets\fP, and \fB--line-offsets\fP. Escape
+sequences starting with a dollar character may be used to insert the contents
+of the matched part of the line and/or captured substrings into the text.
+.sp
+$<digits> or ${<digits>} is replaced by the captured
+substring of the given decimal number; zero substitutes the whole match. If
+the number is greater than the number of capturing substrings, or if the
+capture is unset, the replacement is empty.
+.sp
+$a is replaced by bell; $b by backspace; $e by escape; $f by form feed; $n by
+newline; $r by carriage return; $t by tab; $v by vertical tab.
+.sp
+$o<digits> is replaced by the character represented by the given octal
+number; up to three digits are processed.
+.sp
+$x<digits> is replaced by the character represented by the given hexadecimal
+number; up to two digits are processed.
+.sp
+Any other character is substituted by itself. In particular, $$ is replaced by
+a single dollar.
+.TP
 \fB-o\fP, \fB--only-matching\fP
 Show only the part of the line that matched a pattern instead of the whole
 line. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and
 \fB-C\fP options are ignored. If there is more than one match in a line, each
-of them is shown separately. If \fB-o\fP is combined with \fB-v\fP (invert the
-sense of the match to find non-matching lines), no output is generated, but the
-return code is set appropriately. If the matched portion of the line is empty,
-nothing is output unless the file name or line number are being printed, in
-which case they are shown on an otherwise empty line. This option is mutually
-exclusive with \fB--file-offsets\fP and \fB--line-offsets\fP.
+of them is shown separately, on a separate line of output. If \fB-o\fP is
+combined with \fB-v\fP (invert the sense of the match to find non-matching
+lines), no output is generated, but the return code is set appropriately. If
+the matched portion of the line is empty, nothing is output unless the file
+name or line number are being printed, in which case they are shown on an
+otherwise empty line. This option is mutually exclusive with \fB--output\fP,
+\fB--file-offsets\fP and \fB--line-offsets\fP.
 .TP
 \fB-o\fP\fInumber\fP, \fB--only-matching\fP=\fInumber\fP
 Show only the part of the line that matched the capturing parentheses of the
@@ -520,14 +587,15 @@
 equivalent to \fB-o\fP without a number. Because these options can be given
 without an argument (see above), if an argument is present, it must be given in
 the same shell item, for example, -o3 or --only-matching=2. The comments given
-for the non-argument case above also apply to this case. If the specified
+for the non-argument case above also apply to this option. If the specified
 capturing parentheses do not exist in the pattern, or were not set in the
 match, nothing is output unless the file name or line number are being output.
 .sp
-If this option is given multiple times, multiple substrings are output, in the
-order the options are given. For example, -o3 -o1 -o3 causes the substrings
-matched by capturing parentheses 3 and 1 and then 3 again to be output. By
-default, there is no separator (but see the next option).
+If this option is given multiple times, multiple substrings are output for each
+match, in the order the options are given, and all on one line. For example,
+-o3 -o1 -o3 causes the substrings matched by capturing parentheses 3 and 1 and
+then 3 again to be output. By default, there is no separator (but see the next
+option).
 .TP
 \fB--om-separator\fP=\fItext\fP
 Specify a separating string for multiple occurrences of \fB-o\fP. The default
@@ -552,6 +620,17 @@
 quietly skipped. However, the return code is still 2, even if matches were
 found in other files.
 .TP
+\fB-t\fP, \fB--total-count\fP
+This option is useful when scanning more than one file. If used on its own,
+\fB-t\fP suppresses all output except for a grand total number of matching
+lines (or non-matching lines if \fB-v\fP is used) in all the files. If \fB-t\fP
+is used with \fB-c\fP, a grand total is output except when the previous output
+is just one line. In other words, it is not output when just one file's count
+is listed. If file names are being output, the grand total is preceded by
+"TOTAL:". Otherwise, it appears as just another number. The \fB-t\fP option is
+ignored when used with \fB-L\fP (list files without matches), because the grand
+total would always be zero.
+.TP
 \fB-u\fP, \fB--utf-8\fP
 Operate in UTF-8 mode. This option is available only if PCRE2 has been compiled
 with UTF-8 support. All patterns (including those for any \fB--exclude\fP and
@@ -568,16 +647,18 @@
 the patterns are the ones that are found.
 .TP
 \fB-w\fP, \fB--word-regex\fP, \fB--word-regexp\fP
-Force the patterns to match only whole words. This is equivalent to having \eb
-at the start and end of the pattern. This option applies only to the patterns
-that are matched against the contents of files; it does not apply to patterns
-specified by any of the \fB--include\fP or \fB--exclude\fP options.
+Force the patterns only to match "words". That is, there must be a word
+boundary at the start and end of each matched string. This is equivalent to
+having "\eb(?:" at the start of each pattern, and ")\eb" at the end. This
+option applies only to the patterns that are matched against the contents of
+files; it does not apply to patterns specified by any of the \fB--include\fP or
+\fB--exclude\fP options.
 .TP
 \fB-x\fP, \fB--line-regex\fP, \fB--line-regexp\fP
-Force the patterns to be anchored (each must start matching at the beginning of
-a line) and in addition, require them to match entire lines. This is equivalent
-to having ^ and $ characters at the start and end of each alternative top-level
-branch in every pattern. This option applies only to the patterns that are
+Force the patterns to start matching only at the beginnings of lines, and in
+addition, require them to match entire lines. In multiline mode the match may
+be more than one line. This is equivalent to having "^(?:" at the start of each
+pattern and ")$" at the end. This option applies only to the patterns that are
 matched against the contents of files; it does not apply to patterns specified
 by any of the \fB--include\fP or \fB--exclude\fP options.
 .
@@ -612,10 +693,11 @@
 Many of the short and long forms of \fBpcre2grep\fP's options are the same
 as in the GNU \fBgrep\fP program. Any long option of the form
 \fB--xxx-regexp\fP (GNU terminology) is also available as \fB--xxx-regex\fP
-(PCRE2 terminology). However, the \fB--file-list\fP, \fB--file-offsets\fP,
-\fB--include-dir\fP, \fB--line-offsets\fP, \fB--locale\fP, \fB--match-limit\fP,
-\fB-M\fP, \fB--multiline\fP, \fB-N\fP, \fB--newline\fP, \fB--om-separator\fP,
-\fB--recursion-limit\fP, \fB-u\fP, and \fB--utf-8\fP options are specific to
+(PCRE2 terminology). However, the \fB--depth-limit\fP, \fB--file-list\fP,
+\fB--file-offsets\fP, \fB--heap-limit\fP, \fB--include-dir\fP,
+\fB--line-offsets\fP, \fB--locale\fP, \fB--match-limit\fP, \fB-M\fP,
+\fB--multiline\fP, \fB-N\fP, \fB--newline\fP, \fB--om-separator\fP,
+\fB--output\fP, \fB-u\fP, and \fB--utf-8\fP options are specific to
 \fBpcre2grep\fP, as is the use of the \fB--only-matching\fP option with a
 capturing parentheses number.
 .P
@@ -658,14 +740,14 @@
 character. Otherwise \fBpcre2grep\fP will assume that it has no data.
 .
 .
-.SH "CALLING EXTERNAL SCRIPTS"
+.SH "USING PCRE2'S CALLOUT FACILITY"
 .rs
 .sp
-On non-Windows systems, \fBpcre2grep\fP has, by default, support for calling
-external programs or scripts during matching by making use of PCRE2's callout
-facility. However, this support can be disabled when \fBpcre2grep\fP is built.
-You can find out whether your binary has support for callouts by running it
-with the \fB--help\fP option. If the support is not enabled, all callouts in
+\fBpcre2grep\fP has, by default, support for calling external programs or
+scripts or echoing specific strings during matching by making use of PCRE2's
+callout facility. However, this support can be disabled when \fBpcre2grep\fP is
+built. You can find out whether your binary has support for callouts by running
+it with the \fB--help\fP option. If the support is not enabled, all callouts in
 patterns are ignored by \fBpcre2grep\fP.
 .P
 A callout in a PCRE2 pattern is of the form (?C<arg>) where the argument is
@@ -673,10 +755,17 @@
 .\" HREF
 \fBpcre2callout\fP
 .\"
-documentation for details). Numbered callouts are ignored by \fBpcre2grep\fP.
-String arguments are parsed as a list of substrings separated by pipe (vertical
-bar) characters. The first substring must be an executable name, with the
-following substrings specifying arguments:
+documentation for details). Numbered callouts are ignored by \fBpcre2grep\fP;
+only callouts with string arguments are useful.
+.
+.
+.SS "Calling external programs or scripts"
+.rs
+.sp
+If the callout string does not start with a pipe (vertical bar) character, it
+is parsed into a list of substrings separated by pipe characters. The first
+substring must be an executable name, with the following substrings specifying
+arguments:
 .sp
   executable_name|arg1|arg2|...
 .sp
@@ -710,6 +799,19 @@
 matcher backtracks in the normal way.
 .
 .
+.SS "Echoing a specific string"
+.rs
+.sp
+If the callout string starts with a pipe (vertical bar) character, the rest of
+the string is written to the output, having been passed through the same escape
+processing as text from the --output option. This provides a simple echoing
+facility that avoids calling an external program or script. No terminator is
+added to the string, so if you want a newline, you must include it explicitly.
+Matching continues normally after the string is output. If you want to see only
+the callout output but not any output from an actual match, you should end the
+relevant pattern with (*FAIL).
+.
+.
 .SH "MATCHING ERRORS"
 .rs
 .sp
@@ -722,9 +824,9 @@
 there are more than 20 such errors, \fBpcre2grep\fP gives up.
 .P
 The \fB--match-limit\fP option of \fBpcre2grep\fP can be used to set the
-overall resource limit; there is a second option called \fB--recursion-limit\fP
-that sets a limit on the amount of memory (usually stack) that is used (see the
-discussion of these options above).
+overall resource limit. There are also other limits that affect the amount of
+memory used during matching; see the discussion of \fB--heap-limit\fP and
+\fB--depth-limit\fP above.
 .
 .
 .SH DIAGNOSTICS
@@ -735,6 +837,9 @@
 matches were found in other files) or too many matching errors. Using the
 \fB-s\fP option to suppress error messages about inaccessible files does not
 affect the return code.
+.P
+When run under VMS, the return code is placed in the symbol PCRE2GREP_RC
+because VMS does not distinguish between exit(0) and exit(1).
 .
 .
 .SH "SEE ALSO"
@@ -757,6 +862,6 @@
 .rs
 .sp
 .nf
-Last updated: 19 June 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 13 November 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2grep.txt b/dist2/doc/pcre2grep.txt
index 31aa610..30517b4 100644
--- a/dist2/doc/pcre2grep.txt
+++ b/dist2/doc/pcre2grep.txt
@@ -51,61 +51,73 @@
        boundary is controlled by the -N (--newline) option.
 
        The amount of memory used for buffering files that are being scanned is
-       controlled  by a parameter that can be set by the --buffer-size option.
-       The default value for this parameter is  specified  when  pcre2grep  is
-       built,  with  the  default  default  being 20K. A block of memory three
-       times this size is used (to allow for buffering  "before"  and  "after"
-       lines). An error occurs if a line overflows the buffer.
+       controlled  by  parameters  that  can  be  set by the --buffer-size and
+       --max-buffer-size options. The first of these sets the size  of  buffer
+       that  is obtained at the start of processing. If an input file contains
+       very long lines, a larger buffer may be  needed;  this  is  handled  by
+       automatically extending the buffer, up to the limit specified by --max-
+       buffer-size. The default values for these parameters are specified when
+       pcre2grep  is built, with the default defaults being 20K and 1M respec-
+       tively. An error occurs if a line is too long and  the  buffer  can  no
+       longer be expanded.
 
-       Patterns  can  be  no  longer than 8K or BUFSIZ bytes, whichever is the
-       greater.  BUFSIZ is defined in <stdio.h>. When there is more  than  one
+       The  block  of  memory that is actually used is three times the "buffer
+       size", to allow for buffering "before" and "after" lines. If the buffer
+       size  is too small, fewer than requested "before" and "after" lines may
+       be output.
+
+       Patterns can be no longer than 8K or BUFSIZ  bytes,  whichever  is  the
+       greater.   BUFSIZ  is defined in <stdio.h>. When there is more than one
        pattern (specified by the use of -e and/or -f), each pattern is applied
-       to each line in the order in which they are defined,  except  that  all
+       to  each  line  in the order in which they are defined, except that all
        the -e patterns are tried before the -f patterns.
 
-       By  default, as soon as one pattern matches a line, no further patterns
+       By default, as soon as one pattern matches a line, no further  patterns
        are considered. However, if --colour (or --color) is used to colour the
-       matching  substrings, or if --only-matching, --file-offsets, or --line-
-       offsets is used to output only  the  part  of  the  line  that  matched
+       matching substrings, or if --only-matching, --file-offsets, or  --line-
+       offsets  is  used  to  output  only  the  part of the line that matched
        (either shown literally, or as an offset), scanning resumes immediately
-       following the match, so that further matches on the same  line  can  be
-       found.  If  there  are  multiple  patterns,  they  are all tried on the
-       remainder of the line, but patterns that follow the  one  that  matched
+       following  the  match,  so that further matches on the same line can be
+       found. If there are multiple  patterns,  they  are  all  tried  on  the
+       remainder  of  the  line, but patterns that follow the one that matched
        are not tried on the earlier part of the line.
 
-       This  behaviour  means  that  the  order in which multiple patterns are
-       specified can affect the output when one of the above options is  used.
-       This  is no longer the same behaviour as GNU grep, which now manages to
-       display earlier matches for later patterns (as  long  as  there  is  no
+       This behaviour means that the order  in  which  multiple  patterns  are
+       specified  can affect the output when one of the above options is used.
+       This is no longer the same behaviour as GNU grep, which now manages  to
+       display  earlier  matches  for  later  patterns (as long as there is no
        overlap).
 
-       Patterns  that can match an empty string are accepted, but empty string
+       Patterns that can match an empty string are accepted, but empty  string
        matches   are   never   recognized.   An   example   is   the   pattern
-       "(super)?(man)?",  in  which  all components are optional. This pattern
-       finds all occurrences of both "super" and  "man";  the  output  differs
-       from  matching  with  "super|man" when only the matching substrings are
+       "(super)?(man)?", in which all components are  optional.  This  pattern
+       finds  all  occurrences  of  both "super" and "man"; the output differs
+       from matching with "super|man" when only the  matching  substrings  are
        being shown.
 
-       If the LC_ALL or LC_CTYPE environment variable is set,  pcre2grep  uses
+       If  the  LC_ALL or LC_CTYPE environment variable is set, pcre2grep uses
        the value to set a locale when calling the PCRE2 library.  The --locale
        option can be used to override this.
 
 
 SUPPORT FOR COMPRESSED FILES
 
-       It is possible to compile pcre2grep so that it uses libz or  libbz2  to
-       read  files  whose names end in .gz or .bz2, respectively. You can find
-       out whether your binary has support for one or both of these file types
-       by running it with the --help option. If the appropriate support is not
-       present, files are treated as plain text. The standard input is  always
-       so treated.
+       It  is  possible to compile pcre2grep so that it uses libz or libbz2 to
+       read compressed files whose names end in .gz or .bz2, respectively. You
+       can  find out whether your pcre2grep binary has support for one or both
+       of these file types by running it with the --help option. If the appro-
+       priate support is not present, all files are treated as plain text. The
+       standard input is always so treated. When input is  from  a  compressed
+       .gz or .bz2 file, the --line-buffered option is ignored.
 
 
 BINARY FILES
 
        By  default,  a  file that contains a binary zero byte within the first
        1024 bytes is identified as a binary file, and is processed  specially.
-       (GNU  grep  also  identifies  binary  files  in  this  manner.) See the
+       (GNU grep identifies binary files in this manner.) However, if the new-
+       line type is specified as "nul", that is,  the  line  terminator  is  a
+       binary  zero,  the  test  for  a  binary  file  is not applied. See the
        --binary-files option for a means of changing the way binary files  are
        handled.
 
@@ -113,7 +125,7 @@
 OPTIONS
 
        The  order  in  which some of the options appear can affect the output.
-       For example, both the -h and -l options affect  the  printing  of  file
+       For example, both the -H and -l options affect  the  printing  of  file
        names.  Whichever  comes later in the command line will be the one that
        takes effect. Similarly, except where noted  below,  if  an  option  is
        given  twice,  the  later setting is used. Numerical values for options
@@ -126,46 +138,50 @@
                  names that start with hyphens.
 
        -A number, --after-context=number
-                 Output number lines of context after each matching  line.  If
-                 file  names  and/or  line  numbers are being output, a hyphen
-                 separator is used instead of a colon for the context lines. A
-                 line  containing  "--" is output between each group of lines,
-                 unless they are in fact contiguous in  the  input  file.  The
-                 value  of number is expected to be relatively small. However,
-                 pcre2grep guarantees to have  up  to  8K  of  following  text
-                 available for context output.
+                 Output up to number lines  of  context  after  each  matching
+                 line.  Fewer lines are output if the next match or the end of
+                 the file is reached, or if the  processing  buffer  size  has
+                 been  set  too  small.  If file names and/or line numbers are
+                 being output, a hyphen separator is used instead of  a  colon
+                 for  the  context  lines.  A  line  containing "--" is output
+                 between each group of lines, unless they are in fact contigu-
+                 ous  in the input file. The value of number is expected to be
+                 relatively small. When -c is used, -A is ignored.
 
        -a, --text
-                 Treat  binary  files as text. This is equivalent to --binary-
+                 Treat binary files as text. This is equivalent  to  --binary-
                  files=text.
 
        -B number, --before-context=number
-                 Output number lines of context before each matching line.  If
-                 file  names  and/or  line  numbers are being output, a hyphen
-                 separator is used instead of a colon for the context lines. A
-                 line  containing  "--" is output between each group of lines,
-                 unless they are in fact contiguous in  the  input  file.  The
-                 value  of number is expected to be relatively small. However,
-                 pcre2grep guarantees to have  up  to  8K  of  preceding  text
-                 available for context output.
+                 Output  up  to  number  lines of context before each matching
+                 line. Fewer lines are output if the  previous  match  or  the
+                 start  of the file is within number lines, or if the process-
+                 ing buffer size has been set too small. If file names  and/or
+                 line  numbers  are  being  output, a hyphen separator is used
+                 instead of a colon for the context lines. A  line  containing
+                 "--"  is  output between each group of lines, unless they are
+                 in fact contiguous in the input file. The value of number  is
+                 expected  to  be  relatively  small.  When  -c is used, -B is
+                 ignored.
 
        --binary-files=word
-                 Specify  how binary files are to be processed. If the word is
-                 "binary" (the default),  pattern  matching  is  performed  on
-                 binary  files,  but  the  only  output is "Binary file <name>
-                 matches" when a match succeeds. If the word is "text",  which
-                 is  equivalent  to  the -a or --text option, binary files are
-                 processed in the same way as any other file.  In  this  case,
-                 when  a  match  succeeds,  the  output may be binary garbage,
-                 which can have nasty effects if sent to a  terminal.  If  the
-                 word  is  "without-match",  which  is  equivalent  to  the -I
-                 option, binary files are  not  processed  at  all;  they  are
+                 Specify how binary files are to be processed. If the word  is
+                 "binary"  (the  default),  pattern  matching  is performed on
+                 binary files, but the only  output  is  "Binary  file  <name>
+                 matches"  when a match succeeds. If the word is "text", which
+                 is equivalent to the -a or --text option,  binary  files  are
+                 processed  in  the  same way as any other file. In this case,
+                 when a match succeeds, the  output  may  be  binary  garbage,
+                 which  can  have  nasty effects if sent to a terminal. If the
+                 word is  "without-match",  which  is  equivalent  to  the  -I
+                 option,  binary  files  are  not  processed  at all; they are
                  assumed not to be of interest and are skipped without causing
                  any output or affecting the return code.
 
        --buffer-size=number
-                 Set the parameter that controls how much memory is  used  for
-                 buffering files that are being scanned.
+                 Set  the  parameter that controls how much memory is obtained
+                 at the start of processing for buffering files that are being
+                 scanned. See also --max-buffer-size below.
 
        -C number, --context=number
                  Output  number  lines  of  context both before and after each
@@ -174,19 +190,21 @@
 
        -c, --count
                  Do  not  output  lines from the files that are being scanned;
-                 instead output the number of matches (or non-matches if -v is
-                 used)  that would otherwise have caused lines to be shown. By
-                 default, this count is the same as the number  of  suppressed
-                 lines, but if the -M (multiline) option is used (without -v),
-                 there may  be  more  suppressed  lines  than  the  number  of
-                 matches.
+                 instead output the number  of  lines  that  would  have  been
+                 shown, either because they matched, or, if -v is set, because
+                 they failed to match. By default, this count is  exactly  the
+                 same  as the number of lines that would have been output, but
+                 if the -M (multiline) option is used (without -v), there  may
+                 be  more suppressed lines than the count (that is, the number
+                 of matches).
 
-                 If  no lines are selected, the number zero is output. If sev-
-                 eral files are are being scanned, a count is output for  each
-                 of  them. However, if the --files-with-matches option is also
-                 used, only those files whose counts are greater than zero are
-                 listed.  When  -c  is  used,  the  -A, -B, and -C options are
-                 ignored.
+                 If no lines are selected, the number zero is output. If  sev-
+                 eral  files are are being scanned, a count is output for each
+                 of them and the -t option can be used to cause a total to  be
+                 output  at  the  end.  However,  if  the --files-with-matches
+                 option is also  used,  only  those  files  whose  counts  are
+                 greater  than  zero  are listed. When -c is used, the -A, -B,
+                 and -C options are ignored.
 
        --colour, --color
                  If this option is given without any data, it is equivalent to
@@ -204,205 +222,225 @@
                  possible  matches in a line, not just one, in order to colour
                  them all.
 
-                 The colour that is used can be specified by setting the envi-
-                 ronment  variable  PCRE2GREP_COLOUR  or  PCRE2GREP_COLOR. The
-                 value of this variable should be a  string  of  two  numbers,
-                 separated  by  a semicolon. They are copied directly into the
-                 control string for setting colour on a  terminal,  so  it  is
-                 your  responsibility  to ensure that they make sense. If nei-
-                 ther of the environment variables  is  set,  the  default  is
-                 "1;31", which gives red.
+                 The colour that is used can be specified by  setting  one  of
+                 the  environment variables PCRE2GREP_COLOUR, PCRE2GREP_COLOR,
+                 PCREGREP_COLOUR, or PCREGREP_COLOR, which are checked in that
+                 order.  If  none  of  these  are  set,  pcre2grep  looks  for
+                 GREP_COLORS or GREP_COLOR (in that order). The value  of  the
+                 variable  should  be  a string of two numbers, separated by a
+                 semicolon, except in the  case  of  GREP_COLORS,  which  must
+                 start with "ms=" or "mt=" followed by two semicolon-separated
+                 colours, terminated by the end of the string or by  a  colon.
+                 If  GREP_COLORS  does  not  start  with  "ms=" or "mt=" it is
+                 ignored, and GREP_COLOR is checked.
+
+                 If the string obtained from one of the above  variables  con-
+                 tains any characters other than semicolon or digits, the set-
+                 ting is ignored and the default colour is used. The string is
+                 copied directly into the control string for setting colour on
+                 a terminal, so it is your responsibility to ensure  that  the
+                 values  make  sense.  If  no relevant environment variable is
+                 set, the default is "1;31", which gives red.
 
        -D action, --devices=action
-                 If  an  input  path  is  not  a  regular file or a directory,
-                 "action" specifies how it is to be  processed.  Valid  values
+                 If an input path is  not  a  regular  file  or  a  directory,
+                 "action"  specifies  how  it is to be processed. Valid values
                  are "read" (the default) or "skip" (silently skip the path).
 
        -d action, --directories=action
                  If an input path is a directory, "action" specifies how it is
-                 to be processed.  Valid values are  "read"  (the  default  in
-                 non-Windows  environments,  for compatibility with GNU grep),
-                 "recurse" (equivalent to the -r option), or "skip"  (silently
-                 skip  the  path, the default in Windows environments). In the
-                 "read" case, directories are read as if  they  were  ordinary
-                 files.  In  some  operating  systems  the effect of reading a
+                 to  be  processed.   Valid  values are "read" (the default in
+                 non-Windows environments, for compatibility with  GNU  grep),
+                 "recurse"  (equivalent to the -r option), or "skip" (silently
+                 skip the path, the default in Windows environments).  In  the
+                 "read"  case,  directories  are read as if they were ordinary
+                 files. In some operating systems  the  effect  of  reading  a
                  directory like this is an immediate end-of-file; in others it
                  may provoke an error.
 
+       --depth-limit=number
+                 See --match-limit below.
+
        -e pattern, --regex=pattern, --regexp=pattern
                  Specify a pattern to be matched. This option can be used mul-
                  tiple times in order to specify several patterns. It can also
-                 be  used  as a way of specifying a single pattern that starts
-                 with a hyphen. When -e is used, no argument pattern is  taken
-                 from  the  command  line;  all  arguments are treated as file
-                 names. There is no limit to the number of patterns. They  are
-                 applied  to  each line in the order in which they are defined
+                 be used as a way of specifying a single pattern  that  starts
+                 with  a hyphen. When -e is used, no argument pattern is taken
+                 from the command line; all  arguments  are  treated  as  file
+                 names.  There is no limit to the number of patterns. They are
+                 applied to each line in the order in which they  are  defined
                  until one matches.
 
-                 If -f is used with -e, the command line patterns are  matched
+                 If  -f is used with -e, the command line patterns are matched
                  first, followed by the patterns from the file(s), independent
-                 of the order in which these options are specified. Note  that
-                 multiple  use  of -e is not the same as a single pattern with
+                 of  the order in which these options are specified. Note that
+                 multiple use of -e is not the same as a single  pattern  with
                  alternatives. For example, X|Y finds the first character in a
-                 line  that  is  X or Y, whereas if the two patterns are given
+                 line that is X or Y, whereas if the two  patterns  are  given
                  separately, with X first, pcre2grep finds X if it is present,
                  even if it follows Y in the line. It finds Y only if there is
-                 no X in the line. This matters only if you are  using  -o  or
+                 no  X  in  the line. This matters only if you are using -o or
                  --colo(u)r to show the part(s) of the line that matched.
 
        --exclude=pattern
                  Files (but not directories) whose names match the pattern are
-                 skipped without being processed. This applies to  all  files,
-                 whether  listed  on  the  command line, obtained from --file-
+                 skipped  without  being processed. This applies to all files,
+                 whether listed on the command  line,  obtained  from  --file-
                  list, or by scanning a directory. The pattern is a PCRE2 reg-
-                 ular  expression,  and is matched against the final component
-                 of the file name, not the entire path. The  -F,  -w,  and  -x
+                 ular expression, and is matched against the  final  component
+                 of  the  file  name,  not the entire path. The -F, -w, and -x
                  options do not apply to this pattern. The option may be given
                  any number of times in order to specify multiple patterns. If
-                 a  file  name matches both an --include and an --exclude pat-
+                 a file name matches both an --include and an  --exclude  pat-
                  tern, it is excluded. There is no short form for this option.
 
        --exclude-from=filename
-                 Treat each non-empty line of the file  as  the  data  for  an
+                 Treat  each  non-empty  line  of  the file as the data for an
                  --exclude option. What constitutes a newline when reading the
-                 file is the operating system's default. The --newline  option
-                 has  no  effect on this option. This option may be given more
+                 file  is the operating system's default. The --newline option
+                 has no effect on this option. This option may be  given  more
                  than once in order to specify a number of files to read.
 
        --exclude-dir=pattern
                  Directories whose names match the pattern are skipped without
-                 being  processed,  whatever  the  setting  of the --recursive
-                 option. This applies to all directories,  whether  listed  on
+                 being processed, whatever  the  setting  of  the  --recursive
+                 option.  This  applies  to all directories, whether listed on
                  the command line, obtained from --file-list, or by scanning a
-                 parent directory. The pattern is a PCRE2 regular  expression,
-                 and  is  matched against the final component of the directory
-                 name, not the entire path. The -F, -w, and -x options do  not
-                 apply  to this pattern. The option may be given any number of
-                 times in order to specify more than one pattern. If a  direc-
-                 tory  matches  both  --include-dir  and  --exclude-dir, it is
+                 parent  directory. The pattern is a PCRE2 regular expression,
+                 and is matched against the final component of  the  directory
+                 name,  not the entire path. The -F, -w, and -x options do not
+                 apply to this pattern. The option may be given any number  of
+                 times  in order to specify more than one pattern. If a direc-
+                 tory matches both  --include-dir  and  --exclude-dir,  it  is
                  excluded. There is no short form for this option.
 
        -F, --fixed-strings
-                 Interpret each data-matching  pattern  as  a  list  of  fixed
-                 strings,  separated  by  newlines,  instead  of  as a regular
-                 expression. What constitutes a newline for  this  purpose  is
-                 controlled  by the --newline option. The -w (match as a word)
-                 and -x (match whole line) options can be used with -F.   They
+                 Interpret  each  data-matching  pattern  as  a  list of fixed
+                 strings, separated by  newlines,  instead  of  as  a  regular
+                 expression.  What  constitutes  a newline for this purpose is
+                 controlled by the --newline option. The -w (match as a  word)
+                 and  -x (match whole line) options can be used with -F.  They
                  apply to each of the fixed strings. A line is selected if any
                  of the fixed strings are found in it (subject to -w or -x, if
-                 present).  This  option applies only to the patterns that are
-                 matched against the contents of files; it does not  apply  to
-                 patterns  specified  by  any  of  the  --include or --exclude
+                 present). This option applies only to the patterns  that  are
+                 matched  against  the contents of files; it does not apply to
+                 patterns specified by  any  of  the  --include  or  --exclude
                  options.
 
        -f filename, --file=filename
-                 Read patterns from the file, one per  line,  and  match  them
-                 against  each  line of input. What constitutes a newline when
-                 reading the file  is  the  operating  system's  default.  The
-                 --newline option has no effect on this option. Trailing white
-                 space is removed from each line, and blank lines are ignored.
-                 An  empty  file  contains  no  patterns and therefore matches
-                 nothing. See also the comments about multiple patterns versus
-                 a  single  pattern with alternatives in the description of -e
-                 above.
+                 Read  patterns  from  the  file, one per line, and match them
+                 against each line of input. What constitutes a  newline  when
+                 reading  the  file  is  the  operating  system's default. The
+                 --newline option has no  effect  on  this  option.   Trailing
+                 white  space  is  removed from each line, and blank lines are
+                 ignored. An empty file contains  no  patterns  and  therefore
+                 matches  nothing.  See  also the comments about multiple pat-
+                 terns versus  a  single  pattern  with  alternatives  in  the
+                 description of -e above.
 
-                 If this option is given more than  once,  all  the  specified
-                 files  are read. A data line is output if any of the patterns
-                 match it. A file name can be given as "-"  to  refer  to  the
-                 standard  input.  When  -f is used, patterns specified on the
-                 command line using -e may also be present;  they  are  tested
-                 before  the  file's  patterns.  However,  no other pattern is
+                 If  this  option  is  given more than once, all the specified
+                 files are read. A data line is output if any of the  patterns
+                 match  it.  A  file  name can be given as "-" to refer to the
+                 standard input. When -f is used, patterns  specified  on  the
+                 command  line  using  -e may also be present; they are tested
+                 before the file's patterns.  However,  no  other  pattern  is
                  taken from the command line; all arguments are treated as the
                  names of paths to be searched.
 
        --file-list=filename
-                 Read  a  list  of  files  and/or  directories  that are to be
-                 scanned from the given file, one  per  line.  Trailing  white
+                 Read a list of  files  and/or  directories  that  are  to  be
+                 scanned  from  the  given  file, one per line. Trailing white
                  space is removed from each line, and blank lines are ignored.
-                 These paths are processed before any that are listed  on  the
-                 command  line.  The file name can be given as "-" to refer to
+                 These  paths  are processed before any that are listed on the
+                 command line. The file name can be given as "-" to  refer  to
                  the standard input.  If --file and --file-list are both spec-
-                 ified  as  "-",  patterns are read first. This is useful only
-                 when the standard input is a  terminal,  from  which  further
-                 lines  (the  list  of files) can be read after an end-of-file
-                 indication. If this option is given more than once,  all  the
+                 ified as "-", patterns are read first. This  is  useful  only
+                 when  the  standard  input  is a terminal, from which further
+                 lines (the list of files) can be read  after  an  end-of-file
+                 indication.  If  this option is given more than once, all the
                  specified files are read.
 
        --file-offsets
-                 Instead  of  showing lines or parts of lines that match, show
-                 each match as an offset from the start  of  the  file  and  a
-                 length,  separated  by  a  comma. In this mode, no context is
-                 shown. That is, the -A, -B, and -C options  are  ignored.  If
+                 Instead of showing lines or parts of lines that  match,  show
+                 each  match  as  an  offset  from the start of the file and a
+                 length, separated by a comma. In this  mode,  no  context  is
+                 shown.  That  is,  the -A, -B, and -C options are ignored. If
                  there is more than one match in a line, each of them is shown
-                 separately. This option is mutually  exclusive  with  --line-
-                 offsets and --only-matching.
+                 separately.  This option is mutually exclusive with --output,
+                 --line-offsets, and --only-matching.
 
        -H, --with-filename
-                 Force  the  inclusion of the file name at the start of output
+                 Force the inclusion of the file name at the start  of  output
                  lines when searching a single file. By default, the file name
                  is not shown in this case.  For matching lines, the file name
                  is followed by a colon; for context lines, a hyphen separator
-                 is  used.  If  a line number is also being output, it follows
-                 the file name. When the -M option causes a pattern  to  match
-                 more  than  one  line, only the first is preceded by the file
-                 name.
+                 is used. If a line number is also being  output,  it  follows
+                 the  file  name. When the -M option causes a pattern to match
+                 more than one line, only the first is preceded  by  the  file
+                 name.  This  option  overrides  any  previous  -h,  -l, or -L
+                 options.
 
        -h, --no-filename
                  Suppress the output file names when searching multiple files.
                  By  default,  file  names  are  shown when multiple files are
                  searched. For matching lines, the file name is followed by  a
                  colon;  for  context lines, a hyphen separator is used.  If a
-                 line number is also being output, it follows the file name.
+                 line number is also being output, it follows the  file  name.
+                 This option overrides any previous -H, -L, or -l options.
 
-       --help    Output a help message, giving brief details  of  the  command
-                 options  and  file type support, and then exit. Anything else
+       --heap-limit=number
+                 See --match-limit below.
+
+       --help    Output  a  help  message, giving brief details of the command
+                 options and file type support, and then exit.  Anything  else
                  on the command line is ignored.
 
-       -I        Ignore  binary  files.  This  is  equivalent   to   --binary-
+       -I        Ignore   binary   files.  This  is  equivalent  to  --binary-
                  files=without-match.
 
        -i, --ignore-case
                  Ignore upper/lower case distinctions during comparisons.
 
        --include=pattern
-                 If  any --include patterns are specified, the only files that
-                 are processed are those that match one of the  patterns  (and
-                 do  not  match  an  --exclude  pattern). This option does not
-                 affect directories, but it  applies  to  all  files,  whether
-                 listed  on the command line, obtained from --file-list, or by
-                 scanning a directory. The pattern is a PCRE2 regular  expres-
-                 sion,  and is matched against the final component of the file
-                 name, not the entire path. The -F, -w, and -x options do  not
-                 apply  to this pattern. The option may be given any number of
-                 times. If a file  name  matches  both  an  --include  and  an
-                 --exclude  pattern,  it  is excluded.  There is no short form
+                 If any --include patterns are specified, the only files  that
+                 are  processed  are those that match one of the patterns (and
+                 do not match an --exclude  pattern).  This  option  does  not
+                 affect  directories,  but  it  applies  to all files, whether
+                 listed on the command line, obtained from --file-list, or  by
+                 scanning  a directory. The pattern is a PCRE2 regular expres-
+                 sion, and is matched against the final component of the  file
+                 name,  not the entire path. The -F, -w, and -x options do not
+                 apply to this pattern. The option may be given any number  of
+                 times.  If  a  file  name  matches  both  an --include and an
+                 --exclude pattern, it is excluded.  There is  no  short  form
                  for this option.
 
        --include-from=filename
-                 Treat each non-empty line of the file  as  the  data  for  an
+                 Treat  each  non-empty  line  of  the file as the data for an
                  --include option. What constitutes a newline for this purpose
-                 is the operating system's default. The --newline  option  has
+                 is  the  operating system's default. The --newline option has
                  no effect on this option. This option may be given any number
                  of times; all the files are read.
 
        --include-dir=pattern
-                 If any --include-dir patterns are specified, the only  direc-
-                 tories  that  are  processed  are those that match one of the
-                 patterns (and do not match an  --exclude-dir  pattern).  This
-                 applies  to  all  directories,  whether listed on the command
-                 line, obtained from --file-list,  or  by  scanning  a  parent
-                 directory.  The pattern is a PCRE2 regular expression, and is
-                 matched against the final component of  the  directory  name,
-                 not  the entire path. The -F, -w, and -x options do not apply
+                 If  any --include-dir patterns are specified, the only direc-
+                 tories that are processed are those that  match  one  of  the
+                 patterns  (and  do  not match an --exclude-dir pattern). This
+                 applies to all directories, whether  listed  on  the  command
+                 line,  obtained  from  --file-list,  or  by scanning a parent
+                 directory. The pattern is a PCRE2 regular expression, and  is
+                 matched  against  the  final component of the directory name,
+                 not the entire path. The -F, -w, and -x options do not  apply
                  to this pattern. The option may be given any number of times.
-                 If  a directory matches both --include-dir and --exclude-dir,
+                 If a directory matches both --include-dir and  --exclude-dir,
                  it is excluded. There is no short form for this option.
 
        -L, --files-without-match
-                 Instead of outputting lines from the files, just  output  the
-                 names  of  the files that do not contain any lines that would
-                 have been output. Each file name is output once, on  a  sepa-
-                 rate line.
+                 Instead  of  outputting lines from the files, just output the
+                 names of the files that do not contain any lines  that  would
+                 have  been  output. Each file name is output once, on a sepa-
+                 rate line. This option overrides any previous -H, -h,  or  -l
+                 options.
 
        -l, --files-with-matches
                  Instead  of  outputting lines from the files, just output the
@@ -413,7 +451,8 @@
                  matching continues in order to obtain the correct count,  and
                  those  files  that  have  at least one match are listed along
                  with their counts. Using this option with -c is a way of sup-
-                 pressing the listing of files with no matches.
+                 pressing  the  listing  of files with no matches. This opeion
+                 overrides any previous -H, -h, or -L options.
 
        --label=name
                  This option supplies a name to be used for the standard input
@@ -421,163 +460,194 @@
                  input)" is used. There is no short form for this option.
 
        --line-buffered
-                 When  this  option is given, input is read and processed line
-                 by line, and the output  is  flushed  after  each  write.  By
-                 default,  input is read in large chunks, unless pcre2grep can
-                 determine that it is reading from a terminal (which  is  cur-
-                 rently  possible  only  in Unix-like environments). Output to
-                 terminal is normally automatically flushed by  the  operating
-                 system. This option can be useful when the input or output is
-                 attached to a pipe and you do not want pcre2grep to buffer up
-                 large  amounts  of data. However, its use will affect perfor-
-                 mance, and the -M (multiline) option ceases to work.
+                 When this option is given, non-compressed input is  read  and
+                 processed  line by line, and the output is flushed after each
+                 write. By default, input is  read  in  large  chunks,  unless
+                 pcre2grep  can  determine  that it is reading from a terminal
+                 (which is currently possible only in Unix-like environments).
+                 Output  to  terminal is normally automatically flushed by the
+                 operating system. This option can be useful when the input or
+                 output is attached to a pipe and you do not want pcre2grep to
+                 buffer up large amounts of data. However, its use will affect
+                 performance,  and  the  -M (multiline) option ceases to work.
+                 When input is from a compressed .gz  or  .bz2  file,  --line-
+                 buffered is ignored.
 
        --line-offsets
-                 Instead of showing lines or parts of lines that  match,  show
+                 Instead  of  showing lines or parts of lines that match, show
                  each match as a line number, the offset from the start of the
-                 line, and a length. The line number is terminated by a  colon
-                 (as  usual; see the -n option), and the offset and length are
-                 separated by a comma. In this  mode,  no  context  is  shown.
-                 That  is, the -A, -B, and -C options are ignored. If there is
-                 more than one match in a line, each of them  is  shown  sepa-
-                 rately. This option is mutually exclusive with --file-offsets
-                 and --only-matching.
+                 line,  and a length. The line number is terminated by a colon
+                 (as usual; see the -n option), and the offset and length  are
+                 separated  by  a  comma.  In  this mode, no context is shown.
+                 That is, the -A, -B, and -C options are ignored. If there  is
+                 more  than  one  match in a line, each of them is shown sepa-
+                 rately. This option  is  mutually  exclusive  with  --output,
+                 --file-offsets, and --only-matching.
 
        --locale=locale-name
-                 This option specifies a locale to be used for pattern  match-
-                 ing.  It  overrides the value in the LC_ALL or LC_CTYPE envi-
-                 ronment variables. If  no  locale  is  specified,  the  PCRE2
-                 library's  default (usually the "C" locale) is used. There is
+                 This  option specifies a locale to be used for pattern match-
+                 ing. It overrides the value in the LC_ALL or  LC_CTYPE  envi-
+                 ronment  variables.  If  no  locale  is  specified, the PCRE2
+                 library's default (usually the "C" locale) is used. There  is
                  no short form for this option.
 
        --match-limit=number
-                 Processing some regular expression  patterns  can  require  a
-                 very  large amount of memory, leading in some cases to a pro-
-                 gram crash if not enough is available.   Other  patterns  may
-                 take  a  very  long  time to search for all possible matching
-                 strings.  The  pcre2_match()  function  that  is  called   by
-                 pcre2grep  to  do  the  matching  has two parameters that can
-                 limit the resources that it uses.
+                 Processing  some  regular expression patterns may take a very
+                 long time to search for all possible matching strings. Others
+                 may  require  a  very large amount of memory. There are three
+                 options that set resource limits for matching.
 
-                 The  --match-limit  option  provides  a  means  of   limiting
-                 resource usage when processing patterns that are not going to
-                 match, but which have a very large number of possibilities in
-                 their  search  trees.  The  classic example is a pattern that
-                 uses nested unlimited repeats. Internally, PCRE2 uses a func-
-                 tion  called  match()  which  it  calls repeatedly (sometimes
-                 recursively). The limit set by --match-limit  is  imposed  on
-                 the  number  of times this function is called during a match,
-                 which has the effect of limiting the amount  of  backtracking
-                 that can take place.
+                 The --match-limit option provides a means of limiting comput-
+                 ing  resource  usage  when  processing  patterns that are not
+                 going to match, but which have a very large number of  possi-
+                 bilities in their search trees. The classic example is a pat-
+                 tern that uses nested unlimited  repeats.  Internally,  PCRE2
+                 has  a  counter that is incremented each time around its main
+                 processing  loop.  If  the  value  set  by  --match-limit  is
+                 reached, an error occurs.
 
-                 The --recursion-limit option is similar to --match-limit, but
-                 instead of limiting the total number of times that match() is
-                 called, it limits the depth of recursive calls, which in turn
-                 limits the amount of memory that can be used.  The  recursion
-                 depth  is  a  smaller  number than the total number of calls,
-                 because not all calls to match() are recursive. This limit is
-                 of use only if it is set smaller than --match-limit.
+                 The  --heap-limit option specifies, as a number of kilobytes,
+                 the amount of heap memory that may be used for matching. Heap
+                 memory is needed only if matching the pattern requires a sig-
+                 nificant number of nested backtracking points  to  be  remem-
+                 bered. This parameter can be set to zero to forbid the use of
+                 heap memory altogether.
 
-                 There  are no short forms for these options. The default set-
-                 tings are specified when the PCRE2 library is compiled,  with
-                 the default default being 10 million.
+                 The --depth-limit option limits the  depth  of  nested  back-
+                 tracking points, which indirectly limits the amount of memory
+                 that is used. The amount of memory needed for each backtrack-
+                 ing  point  depends on the number of capturing parentheses in
+                 the pattern, so the amount of memory that is used before this
+                 limit  acts  varies from pattern to pattern. This limit is of
+                 use only if it is set smaller than --match-limit.
+
+                 There are no short forms for these options. The default  set-
+                 tings  are specified when the PCRE2 library is compiled, with
+                 the default defaults being  very  large  and  so  effectively
+                 unlimited.
+
+       --max-buffer-size=number
+                 This  limits  the  expansion  of the processing buffer, whose
+                 initial size can be set by --buffer-size. The maximum  buffer
+                 size  is  silently  forced to be no smaller than the starting
+                 buffer size.
 
        -M, --multiline
-                 Allow  patterns to match more than one line. When this option
-                 is given, patterns may usefully contain literal newline char-
-                 acters  and  internal  occurrences of ^ and $ characters. The
-                 output for a successful match may consist of  more  than  one
-                 line.  The  first is the line in which the match started, and
-                 the last is the line in which the match ended. If the matched
-                 string  ends  with  a newline sequence the output ends at the
-                 end of that line.
+                 Allow patterns to match more than one line. When this  option
+                 is set, the PCRE2 library is called in "multiline" mode. This
+                 allows a matched string to extend past the end of a line  and
+                 continue  on one or more subsequent lines. Patterns used with
+                 -M may usefully contain literal newline characters and inter-
+                 nal  occurrences of ^ and $ characters. The output for a suc-
+                 cessful match may consist of more than one  line.  The  first
+                 line  is  the  line  in which the match started, and the last
+                 line is the line in which the match  ended.  If  the  matched
+                 string  ends  with a newline sequence, the output ends at the
+                 end of that line.  If -v is set,  none  of  the  lines  in  a
+                 multi-line  match  are output. Once a match has been handled,
+                 scanning restarts at the beginning of the line after the  one
+                 in which the match ended.
 
-                 When this option is set, the PCRE2 library is called in "mul-
-                 tiline" mode. This allows a matched string to extend past the
-                 end of a line and continue on one or more  subsequent  lines.
-                 However,  pcre2grep  still  processes the input line by line.
-                 Once a match has  been  handled,  scanning  restarts  at  the
-                 beginning  of  the  next line, just as it does when -M is not
-                 present. This means that it is possible  for  the  second  or
-                 subsequent  lines  in a multiline match to be output again as
-                 part of another match.
-
-                 The newline sequence that separates multiple  lines  must  be
-                 matched  as  part  of  the  pattern. For example, to find the
-                 phrase "regular expression" in a file where  "regular"  might
-                 be  at the end of a line and "expression" at the start of the
+                 The  newline  sequence  that separates multiple lines must be
+                 matched as part of the pattern.  For  example,  to  find  the
+                 phrase  "regular  expression" in a file where "regular" might
+                 be at the end of a line and "expression" at the start of  the
                  next line, you could use this command:
 
                    pcre2grep -M 'regular\s+expression' <file>
 
-                 The \s escape sequence matches  any  white  space  character,
-                 including  newlines,  and  is  followed  by  + so as to match
-                 trailing white space on the first line as  well  as  possibly
+                 The  \s  escape  sequence  matches any white space character,
+                 including newlines, and is followed  by  +  so  as  to  match
+                 trailing  white  space  on the first line as well as possibly
                  handling a two-character newline sequence.
 
-                 There  is a limit to the number of lines that can be matched,
-                 imposed by the way that pcre2grep buffers the input  file  as
-                 it  scans  it.  However,  pcre2grep  ensures that at least 8K
-                 characters or the rest of the file (whichever is the shorter)
-                 are  available for forward matching, and similarly the previ-
-                 ous 8K characters (or all the previous characters,  if  fewer
-                 than 8K) are guaranteed to be available for lookbehind asser-
-                 tions. The -M option does not work when input is read line by
-                 line (see --line-buffered.)
+                 There is a limit to the number of lines that can be  matched,
+                 imposed  by  the way that pcre2grep buffers the input file as
+                 it scans it. With a  sufficiently  large  processing  buffer,
+                 this should not be a problem, but the -M option does not work
+                 when input is read line by line (see --line-buffered.)
 
        -N newline-type, --newline=newline-type
-                 The  PCRE2  library  supports  five different conventions for
-                 indicating the ends of lines. They are  the  single-character
-                 sequences  CR  (carriage  return) and LF (linefeed), the two-
-                 character sequence CRLF, an "anycrlf" convention, which  rec-
-                 ognizes  any  of the preceding three types, and an "any" con-
+                 The PCRE2 library supports  five  different  conventions  for
+                 indicating  the  ends of lines. They are the single-character
+                 sequences CR (carriage return) and LF  (linefeed),  the  two-
+                 character  sequence CRLF, an "anycrlf" convention, which rec-
+                 ognizes any of the preceding three types, and an  "any"  con-
                  vention, in which any Unicode line ending sequence is assumed
-                 to  end a line. The Unicode sequences are the three just men-
-                 tioned, plus  VT  (vertical  tab,  U+000B),  FF  (form  feed,
-                 U+000C),   NEL  (next  line,  U+0085),  LS  (line  separator,
+                 to end a line. The Unicode sequences are the three just  men-
+                 tioned,  plus  VT  (vertical  tab,  U+000B),  FF  (form feed,
+                 U+000C),  NEL  (next  line,  U+0085),  LS  (line   separator,
                  U+2028), and PS (paragraph separator, U+2029).
 
-                 When the  PCRE2  library  is  built,  a  default  line-ending
-                 sequence   is  specified.   This  is  normally  the  standard
+                 When  the  PCRE2  library  is  built,  a  default line-ending
+                 sequence  is  specified.   This  is  normally  the   standard
                  sequence for the operating system. Unless otherwise specified
-                 by  this  option,  pcre2grep uses the library's default.  The
+                 by this option, pcre2grep uses the  library's  default.   The
                  possible values for this option are CR, LF, CRLF, ANYCRLF, or
-                 ANY.  This  makes  it possible to use pcre2grep to scan files
+                 ANY. This makes it possible to use pcre2grep  to  scan  files
                  that have come from other environments without having to mod-
-                 ify  their  line  endings.  If the data that is being scanned
-                 does not agree  with  the  convention  set  by  this  option,
-                 pcre2grep  may  behave in strange ways. Note that this option
-                 does not apply to files specified by the -f,  --exclude-from,
-                 or  --include-from  options,  which  are  expected to use the
+                 ify their line endings. If the data  that  is  being  scanned
+                 does  not  agree  with  the  convention  set  by this option,
+                 pcre2grep may behave in strange ways. Note that  this  option
+                 does  not apply to files specified by the -f, --exclude-from,
+                 or --include-from options, which  are  expected  to  use  the
                  operating system's standard newline sequence.
 
        -n, --line-number
                  Precede each output line by its line number in the file, fol-
-                 lowed  by  a colon for matching lines or a hyphen for context
+                 lowed by a colon for matching lines or a hyphen  for  context
                  lines. If the file name is also being output, it precedes the
-                 line  number.  When  the  -M option causes a pattern to match
-                 more than one line, only the first is preceded  by  its  line
+                 line number. When the -M option causes  a  pattern  to  match
+                 more  than  one  line, only the first is preceded by its line
                  number. This option is forced if --line-offsets is used.
 
-       --no-jit  If  the  PCRE2 library is built with support for just-in-time
+       --no-jit  If the PCRE2 library is built with support  for  just-in-time
                  compiling (which speeds up matching), pcre2grep automatically
                  makes use of this, unless it was explicitly disabled at build
-                 time. This option can be used to disable the use  of  JIT  at
-                 run  time. It is provided for testing and working round prob-
+                 time.  This  option  can be used to disable the use of JIT at
+                 run time. It is provided for testing and working round  prob-
                  lems.  It should never be needed in normal use.
 
+       -O text, --output=text
+                 When  there  is a match, instead of outputting the whole line
+                 that matched, output just the  given  text.  This  option  is
+                 mutually  exclusive with --only-matching, --file-offsets, and
+                 --line-offsets. Escape sequences starting with a dollar char-
+                 acter  may be used to insert the contents of the matched part
+                 of the line and/or captured substrings into the text.
+
+                 $<digits> or ${<digits>} is replaced  by  the  captured  sub-
+                 string  of  the  given  decimal  number; zero substitutes the
+                 whole match. If the number is greater than the number of cap-
+                 turing  substrings,  or if the capture is unset, the replace-
+                 ment is empty.
+
+                 $a is replaced by bell; $b by backspace; $e by escape; $f  by
+                 form  feed;  $n by newline; $r by carriage return; $t by tab;
+                 $v by vertical tab.
+
+                 $o<digits> is replaced by the character  represented  by  the
+                 given octal number; up to three digits are processed.
+
+                 $x<digits>  is  replaced  by the character represented by the
+                 given hexadecimal number; up to two digits are processed.
+
+                 Any other character is substituted by itself. In  particular,
+                 $$ is replaced by a single dollar.
+
        -o, --only-matching
                  Show only the part of the line that matched a pattern instead
-                 of  the  whole  line. In this mode, no context is shown. That
-                 is, the -A, -B, and -C options are ignored. If there is  more
-                 than  one  match in a line, each of them is shown separately.
-                 If -o is combined with -v (invert the sense of the  match  to
-                 find  non-matching  lines),  no  output is generated, but the
-                 return code is set appropriately. If the matched  portion  of
-                 the  line is empty, nothing is output unless the file name or
-                 line number are being printed, in which case they  are  shown
-                 on an otherwise empty line. This option is mutually exclusive
-                 with --file-offsets and --line-offsets.
+                 of the whole line. In this mode, no context  is  shown.  That
+                 is,  the -A, -B, and -C options are ignored. If there is more
+                 than one match in a line, each of them is  shown  separately,
+                 on  a  separate  line  of  output.  If -o is combined with -v
+                 (invert the sense of the match to find  non-matching  lines),
+                 no  output is generated, but the return code is set appropri-
+                 ately. If the matched portion of the line is  empty,  nothing
+                 is  output  unless  the  file  name  or line number are being
+                 printed, in which case they are shown on an  otherwise  empty
+                 line.  This  option  is  mutually  exclusive  with  --output,
+                 --file-offsets and --line-offsets.
 
        -onumber, --only-matching=number
                  Show only the part of the line  that  matched  the  capturing
@@ -587,82 +657,98 @@
                  (see above), if an argument is present, it must be  given  in
                  the  same  shell item, for example, -o3 or --only-matching=2.
                  The comments given for the non-argument case above also apply
-                 to  this  case. If the specified capturing parentheses do not
+                 to this option. If the specified capturing parentheses do not
                  exist in the pattern, or were not set in the  match,  nothing
                  is  output unless the file name or line number are being out-
                  put.
 
                  If this option is given multiple times,  multiple  substrings
-                 are  output, in the order the options are given. For example,
-                 -o3 -o1 -o3 causes the substrings matched by capturing paren-
-                 theses  3  and  1  and then 3 again to be output. By default,
-                 there is no separator (but see the next option).
+                 are  output  for  each  match,  in  the order the options are
+                 given, and all on one line. For example, -o3 -o1  -o3  causes
+                 the  substrings  matched by capturing parentheses 3 and 1 and
+                 then 3 again to be output. By default, there is no  separator
+                 (but see the next option).
 
        --om-separator=text
-                 Specify a separating string for multiple occurrences  of  -o.
-                 The  default is an empty string. Separating strings are never
+                 Specify  a  separating string for multiple occurrences of -o.
+                 The default is an empty string. Separating strings are  never
                  coloured.
 
        -q, --quiet
                  Work quietly, that is, display nothing except error messages.
-                 The  exit  status  indicates  whether or not any matches were
+                 The exit status indicates whether or  not  any  matches  were
                  found.
 
        -r, --recursive
-                 If any given path is a directory, recursively scan the  files
-                 it  contains, taking note of any --include and --exclude set-
-                 tings. By default, a directory is read as a normal  file;  in
-                 some  operating  systems this gives an immediate end-of-file.
-                 This option is a shorthand  for  setting  the  -d  option  to
+                 If  any given path is a directory, recursively scan the files
+                 it contains, taking note of any --include and --exclude  set-
+                 tings.  By  default, a directory is read as a normal file; in
+                 some operating systems this gives an  immediate  end-of-file.
+                 This  option  is  a  shorthand  for  setting the -d option to
                  "recurse".
 
        --recursion-limit=number
                  See --match-limit above.
 
        -s, --no-messages
-                 Suppress  error  messages  about  non-existent  or unreadable
-                 files. Such files are quietly skipped.  However,  the  return
+                 Suppress error  messages  about  non-existent  or  unreadable
+                 files.  Such  files  are quietly skipped. However, the return
                  code is still 2, even if matches were found in other files.
 
+       -t, --total-count
+                 This option is useful when scanning more than  one  file.  If
+                 used  on its own, -t suppresses all output except for a grand
+                 total number of matching lines (or non-matching lines  if  -v
+                 is  used)  in  all  the files. If -t is used with -c, a grand
+                 total is output except when the previous output is  just  one
+                 line.  In  other words, it is not output when just one file's
+                 count is listed. If file names are being  output,  the  grand
+                 total  is preceded by "TOTAL:". Otherwise, it appears as just
+                 another number. The -t option is ignored when  used  with  -L
+                 (list  files  without matches), because the grand total would
+                 always be zero.
+
        -u, --utf-8
                  Operate in UTF-8 mode. This option is available only if PCRE2
                  has been compiled with UTF-8 support. All patterns (including
-                 those  for  any --exclude and --include options) and all sub-
-                 ject lines that are scanned must be valid  strings  of  UTF-8
+                 those for any --exclude and --include options) and  all  sub-
+                 ject  lines  that  are scanned must be valid strings of UTF-8
                  characters.
 
        -V, --version
-                 Write  the version numbers of pcre2grep and the PCRE2 library
-                 to the standard output and then exit. Anything  else  on  the
+                 Write the version numbers of pcre2grep and the PCRE2  library
+                 to  the  standard  output and then exit. Anything else on the
                  command line is ignored.
 
        -v, --invert-match
-                 Invert  the  sense  of  the match, so that lines which do not
+                 Invert the sense of the match, so that  lines  which  do  not
                  match any of the patterns are the ones that are found.
 
        -w, --word-regex, --word-regexp
-                 Force the patterns to match only whole words. This is equiva-
-                 lent  to  having \b at the start and end of the pattern. This
-                 option applies only to the patterns that are matched  against
-                 the  contents  of files; it does not apply to patterns speci-
-                 fied by any of the --include or --exclude options.
+                 Force the patterns only to match "words". That is, there must
+                 be a word boundary at the  start  and  end  of  each  matched
+                 string.  This is equivalent to having "\b(?:" at the start of
+                 each pattern, and ")\b" at the end. This option applies  only
+                 to  the  patterns  that  are  matched against the contents of
+                 files; it does not apply to patterns specified by any of  the
+                 --include or --exclude options.
 
        -x, --line-regex, --line-regexp
-                 Force the patterns to be anchored (each must  start  matching
-                 at  the beginning of a line) and in addition, require them to
-                 match entire lines. This is equivalent  to  having  ^  and  $
-                 characters at the start and end of each alternative top-level
-                 branch in every pattern. This option applies only to the pat-
-                 terns that are matched against the contents of files; it does
-                 not apply to patterns specified by any of  the  --include  or
-                 --exclude options.
+                 Force  the  patterns to start matching only at the beginnings
+                 of lines, and in  addition,  require  them  to  match  entire
+                 lines. In multiline mode the match may be more than one line.
+                 This is equivalent to having "^(?:" at the start of each pat-
+                 tern  and  ")$"  at  the end. This option applies only to the
+                 patterns that are matched against the contents of  files;  it
+                 does  not apply to patterns specified by any of the --include
+                 or --exclude options.
 
 
 ENVIRONMENT VARIABLES
 
-       The  environment  variables  LC_ALL  and LC_CTYPE are examined, in that
-       order, for a locale. The first one that is set is  used.  This  can  be
-       overridden  by  the  --locale  option.  If  no locale is set, the PCRE2
+       The environment variables LC_ALL and LC_CTYPE  are  examined,  in  that
+       order,  for  a  locale.  The first one that is set is used. This can be
+       overridden by the --locale option. If  no  locale  is  set,  the  PCRE2
        library's default (usually the "C" locale) is used.
 
 
@@ -670,82 +756,87 @@
 
        The -N (--newline) option allows pcre2grep to scan files with different
        newline conventions from the default. Any parts of the input files that
-       are written to the standard output are copied identically,  with  what-
-       ever  newline sequences they have in the input. However, the setting of
-       this option does not affect the interpretation of  files  specified  by
+       are  written  to the standard output are copied identically, with what-
+       ever newline sequences they have in the input. However, the setting  of
+       this  option  does  not affect the interpretation of files specified by
        the -f, --exclude-from, or --include-from options, which are assumed to
-       use the operating system's  standard  newline  sequence,  nor  does  it
-       affect  the way in which pcre2grep writes informational messages to the
+       use  the  operating  system's  standard  newline  sequence, nor does it
+       affect the way in which pcre2grep writes informational messages to  the
        standard error and output streams. For these it uses the string "\n" to
-       indicate  newlines,  relying on the C I/O library to convert this to an
+       indicate newlines, relying on the C I/O library to convert this  to  an
        appropriate sequence.
 
 
 OPTIONS COMPATIBILITY
 
        Many of the short and long forms of pcre2grep's options are the same as
-       in  the GNU grep program. Any long option of the form --xxx-regexp (GNU
+       in the GNU grep program. Any long option of the form --xxx-regexp  (GNU
        terminology) is also available as --xxx-regex (PCRE2 terminology). How-
-       ever,  the  --file-list, --file-offsets, --include-dir, --line-offsets,
-       --locale, --match-limit, -M, --multiline, -N,  --newline,  --om-separa-
-       tor,  --recursion-limit,  -u,  and  --utf-8  options  are  specific  to
-       pcre2grep, as is the use of the --only-matching option with a capturing
-       parentheses number.
+       ever, the  --depth-limit,  --file-list,  --file-offsets,  --heap-limit,
+       --include-dir,  --line-offsets,  --locale,  --match-limit, -M, --multi-
+       line, -N, --newline, --om-separator, --output, -u, and --utf-8  options
+       are  specific to pcre2grep, as is the use of the --only-matching option
+       with a capturing parentheses number.
 
-       Although  most  of the common options work the same way, a few are dif-
-       ferent in pcre2grep. For example, the --include option's argument is  a
-       glob  for GNU grep, but a regular expression for pcre2grep. If both the
-       -c and -l options are given, GNU grep lists only  file  names,  without
+       Although most of the common options work the same way, a few  are  dif-
+       ferent  in pcre2grep. For example, the --include option's argument is a
+       glob for GNU grep, but a regular expression for pcre2grep. If both  the
+       -c  and  -l  options are given, GNU grep lists only file names, without
        counts, but pcre2grep gives the counts as well.
 
 
 OPTIONS WITH DATA
 
        There are four different ways in which an option with data can be spec-
-       ified.  If a short form option is used, the  data  may  follow  immedi-
+       ified.   If  a  short  form option is used, the data may follow immedi-
        ately, or (with one exception) in the next command line item. For exam-
        ple:
 
          -f/some/file
          -f /some/file
 
-       The exception is the -o option, which may appear with or without  data.
-       Because  of this, if data is present, it must follow immediately in the
+       The  exception is the -o option, which may appear with or without data.
+       Because of this, if data is present, it must follow immediately in  the
        same item, for example -o3.
 
-       If a long form option is used, the data may appear in the same  command
-       line  item,  separated by an equals character, or (with two exceptions)
+       If  a long form option is used, the data may appear in the same command
+       line item, separated by an equals character, or (with  two  exceptions)
        it may appear in the next command line item. For example:
 
          --file=/some/file
          --file /some/file
 
-       Note, however, that if you want to supply a file name beginning with  ~
-       as  data  in  a  shell  command,  and have the shell expand ~ to a home
+       Note,  however, that if you want to supply a file name beginning with ~
+       as data in a shell command, and have the  shell  expand  ~  to  a  home
        directory, you must separate the file name from the option, because the
        shell does not treat ~ specially unless it is at the start of an item.
 
-       The  exceptions  to the above are the --colour (or --color) and --only-
-       matching options, for which the data  is  optional.  If  one  of  these
-       options  does  have  data, it must be given in the first form, using an
+       The exceptions to the above are the --colour (or --color)  and  --only-
+       matching  options,  for  which  the  data  is optional. If one of these
+       options does have data, it must be given in the first  form,  using  an
        equals character. Otherwise pcre2grep will assume that it has no data.
 
 
-CALLING EXTERNAL SCRIPTS
+USING PCRE2'S CALLOUT FACILITY
 
-       On non-Windows systems, pcre2grep has, by default, support for  calling
-       external  programs  or scripts during matching by making use of PCRE2's
-       callout facility. However, this support can be disabled when  pcre2grep
-       is  built.   You can find out whether your binary has support for call-
-       outs by running it with the  --help  option.  If  the  support  is  not
-       enabled, all callouts in patterns are ignored by pcre2grep.
+       pcre2grep  has,  by  default,  support for calling external programs or
+       scripts or echoing specific strings during matching by  making  use  of
+       PCRE2's  callout  facility.  However, this support can be disabled when
+       pcre2grep is built. You can find out whether your  binary  has  support
+       for  callouts  by  running it with the --help option. If the support is
+       not enabled, all callouts in patterns are ignored by pcre2grep.
 
-       A  callout  in a PCRE2 pattern is of the form (?C<arg>) where the argu-
-       ment is either a number or a quoted string (see the pcre2callout  docu-
-       mentation  for  details).  Numbered  callouts are ignored by pcre2grep.
-       String arguments are parsed as a list of substrings separated  by  pipe
-       (vertical  bar)  characters.  The first substring must be an executable
-       name, with the following substrings specifying arguments:
+       A callout in a PCRE2 pattern is of the form (?C<arg>) where  the  argu-
+       ment  is either a number or a quoted string (see the pcre2callout docu-
+       mentation for details). Numbered callouts  are  ignored  by  pcre2grep;
+       only callouts with string arguments are useful.
+
+   Calling external programs or scripts
+
+       If the callout string does not start with a pipe (vertical bar) charac-
+       ter, it is parsed into a list of substrings separated by  pipe  charac-
+       ters.  The first substring must be an executable name, with the follow-
+       ing substrings specifying arguments:
 
          executable_name|arg1|arg2|...
 
@@ -781,6 +872,18 @@
        local matching failure occurs and the matcher backtracks in the  normal
        way.
 
+   Echoing a specific string
+
+       If  the callout string starts with a pipe (vertical bar) character, the
+       rest of the string is written to the output, having been passed through
+       the  same escape processing as text from the --output option. This pro-
+       vides a simple echoing facility that avoids calling an external program
+       or  script. No terminator is added to the string, so if you want a new-
+       line, you must include  it  explicitly.   Matching  continues  normally
+       after  the string is output. If you want to see only the callout output
+       but not any output from an actual match, you should  end  the  relevant
+       pattern with (*FAIL).
+
 
 MATCHING ERRORS
 
@@ -794,9 +897,9 @@
        such errors, pcre2grep gives up.
 
        The --match-limit option of pcre2grep can be used to  set  the  overall
-       resource  limit; there is a second option called --recursion-limit that
-       sets a limit on the amount of memory (usually stack) that is used  (see
-       the discussion of these options above).
+       resource  limit.  There are also other limits that affect the amount of
+       memory used during matching; see the  discussion  of  --heap-limit  and
+       --depth-limit above.
 
 
 DIAGNOSTICS
@@ -807,6 +910,10 @@
        errors. Using the -s option to suppress error messages about inaccessi-
        ble files does not affect the return code.
 
+       When   run  under  VMS,  the  return  code  is  placed  in  the  symbol
+       PCRE2GREP_RC because VMS  does  not  distinguish  between  exit(0)  and
+       exit(1).
+
 
 SEE ALSO
 
@@ -822,5 +929,5 @@
 
 REVISION
 
-       Last updated: 19 June 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 13 November 2017
+       Copyright (c) 1997-2017 University of Cambridge.
diff --git a/dist2/doc/pcre2jit.3 b/dist2/doc/pcre2jit.3
index 0b95b4d..f6d17ca 100644
--- a/dist2/doc/pcre2jit.3
+++ b/dist2/doc/pcre2jit.3
@@ -1,4 +1,4 @@
-.TH PCRE2JIT 3 "05 June 2016" "PCRE2 10.22"
+.TH PCRE2JIT 3 "31 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 JUST-IN-TIME COMPILER SUPPORT"
@@ -152,7 +152,7 @@
 The error code PCRE2_ERROR_MATCHLIMIT is returned by the JIT code if searching
 a very large pattern tree goes on for too long, as it is in the same
 circumstance when JIT is not used, but the details of exactly what is counted
-are not the same. The PCRE2_ERROR_RECURSIONLIMIT error code is never returned
+are not the same. The PCRE2_ERROR_DEPTHLIMIT error code is never returned
 when JIT matching is used.
 .
 .
@@ -178,11 +178,8 @@
 pointer to an opaque structure of type \fBpcre2_jit_stack\fP, or NULL if there
 is an error. The \fBpcre2_jit_stack_free()\fP function is used to free a stack
 that is no longer needed. (For the technically minded: the address space is
-allocated by mmap or VirtualAlloc.)
-.P
-JIT uses far less memory for recursion than the interpretive code,
-and a maximum stack size of 512K to 1M should be more than enough for any
-pattern.
+allocated by mmap or VirtualAlloc.) A maximum stack size of 512K to 1M should
+be more than enough for any pattern.
 .P
 The \fBpcre2_jit_stack_assign()\fP function specifies which stack JIT code
 should use. Its arguments are as follows:
@@ -413,6 +410,6 @@
 .rs
 .sp
 .nf
-Last updated: 05 June 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 31 March 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2limits.3 b/dist2/doc/pcre2limits.3
index a5bab81..88944db 100644
--- a/dist2/doc/pcre2limits.3
+++ b/dist2/doc/pcre2limits.3
@@ -1,4 +1,4 @@
-.TH PCRE2LIMITS 3 "05 November 2015" "PCRE2 10.21"
+.TH PCRE2LIMITS 3 "30 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "SIZE AND OTHER LIMITATIONS"
@@ -30,15 +30,6 @@
 ~(PCRE2_SIZE)0) is reserved as a special indicator for zero-terminated strings
 and unset offsets.
 .P
-Note that when using the traditional matching function, PCRE2 uses recursion to
-handle subpatterns and indefinite repetition. This means that the available
-stack space may limit the size of a subject string that can be processed by
-certain patterns. For a discussion of stack issues, see the
-.\" HREF
-\fBpcre2stack\fP
-.\"
-documentation.
-.P
 All values in repeating quantifiers must be less than 65536.
 .P
 The maximum length of a lookbehind assertion is 65535 characters.
@@ -46,19 +37,20 @@
 There is no limit to the number of parenthesized subpatterns, but there can be
 no more than 65535 capturing subpatterns. There is, however, a limit to the
 depth of nesting of parenthesized subpatterns of all kinds. This is imposed in
-order to limit the amount of system stack used at compile time. The limit can
-be specified when PCRE2 is built; the default is 250.
-.P
-There is a limit to the number of forward references to subsequent subpatterns
-of around 200,000. Repeated forward references with fixed upper limits, for
-example, (?2){0,100} when subpattern number 2 is to the right, are included in
-the count. There is no limit to the number of backward references.
+order to limit the amount of system stack used at compile time. The default
+limit can be specified when PCRE2 is built; the default default is 250. An
+application can change this limit by calling pcre2_set_parens_nest_limit() to
+set the limit in a compile context.
 .P
 The maximum length of name for a named subpattern is 32 code units, and the
 maximum number of named subpatterns is 10000.
 .P
 The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb
-is 255 for the 8-bit library and 65535 for the 16-bit and 32-bit libraries.
+is 255 code units for the 8-bit library and 65535 code units for the 16-bit and
+32-bit libraries.
+.P
+The maximum length of a string argument to a callout is the largest number a
+32-bit unsigned integer can hold.
 .
 .
 .SH AUTHOR
@@ -75,6 +67,6 @@
 .rs
 .sp
 .nf
-Last updated: 05 November 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 30 March 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2pattern.3 b/dist2/doc/pcre2pattern.3
index 70ac14a..5c0daa8 100644
--- a/dist2/doc/pcre2pattern.3
+++ b/dist2/doc/pcre2pattern.3
@@ -1,4 +1,4 @@
-.TH PCRE2PATTERN 3 "20 June 2016" "PCRE2 10.22"
+.TH PCRE2PATTERN 3 "12 September 2017" "PCRE2 10.31"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 REGULAR EXPRESSION DETAILS"
@@ -138,36 +138,52 @@
 \fBpcre2_jit_compile()\fP is ignored.
 .
 .
-.SS "Setting match and recursion limits"
+.SS "Setting match resource limits"
 .rs
 .sp
-The caller of \fBpcre2_match()\fP can set a limit on the number of times the
-internal \fBmatch()\fP function is called and on the maximum depth of
-recursive calls. These facilities are provided to catch runaway matches that
-are provoked by patterns with huge matching trees (a typical example is a
-pattern with nested unlimited repeats) and to avoid running out of system stack
-by too much recursion. When one of these limits is reached, \fBpcre2_match()\fP
-gives an error return. The limits can also be set by items at the start of the
-pattern of the form
+The pcre2_match() function contains a counter that is incremented every time it
+goes round its main loop. The caller of \fBpcre2_match()\fP can set a limit on
+this counter, which therefore limits the amount of computing resource used for
+a match. The maximum depth of nested backtracking can also be limited; this
+indirectly restricts the amount of heap memory that is used, but there is also
+an explicit memory limit that can be set.
+.P
+These facilities are provided to catch runaway matches that are provoked by
+patterns with huge matching trees (a typical example is a pattern with nested
+unlimited repeats applied to a long string that does not match). When one of
+these limits is reached, \fBpcre2_match()\fP gives an error return. The limits
+can also be set by items at the start of the pattern of the form
 .sp
+  (*LIMIT_HEAP=d)
   (*LIMIT_MATCH=d)
-  (*LIMIT_RECURSION=d)
+  (*LIMIT_DEPTH=d)
 .sp
 where d is any number of decimal digits. However, the value of the setting must
 be less than the value set (or defaulted) by the caller of \fBpcre2_match()\fP
 for it to have any effect. In other words, the pattern writer can lower the
 limits set by the programmer, but not raise them. If there is more than one
 setting of one of these limits, the lower value is used.
+.P
+Prior to release 10.30, LIMIT_DEPTH was called LIMIT_RECURSION. This name is
+still recognized for backwards compatibility.
+.P
+The heap limit applies only when the \fBpcre2_match()\fP interpreter is used
+for matching. It does not apply to JIT or DFA matching. The match limit is used
+(but in a different way) when JIT is being used, or when
+\fBpcre2_dfa_match()\fP is called, to limit computing resource usage by those
+matching functions. The depth limit is ignored by JIT but is relevant for DFA
+matching, which uses function recursion for recursions within the pattern. In
+this case, the depth limit controls the amount of system stack that is used.
 .
 .
 .\" HTML <a name="newlines"></a>
 .SS "Newline conventions"
 .rs
 .sp
-PCRE2 supports five different conventions for indicating line breaks in
+PCRE2 supports six different conventions for indicating line breaks in
 strings: a single CR (carriage return) character, a single LF (linefeed)
-character, the two-character sequence CRLF, any of the three preceding, or any
-Unicode newline sequence. The
+character, the two-character sequence CRLF, any of the three preceding, any
+Unicode newline sequence, or the NUL character (binary zero). The
 .\" HREF
 \fBpcre2api\fP
 .\"
@@ -180,13 +196,14 @@
 \fBpcre2_compile()\fP.
 .P
 It is also possible to specify a newline convention by starting a pattern
-string with one of the following five sequences:
+string with one of the following sequences:
 .sp
   (*CR)        carriage return
   (*LF)        linefeed
   (*CRLF)      carriage return, followed by linefeed
   (*ANYCRLF)   any of the three above
   (*ANY)       all Unicode newline sequences
+  (*NUL)       the NUL character (binary zero)
 .sp
 These override the default and the options given to the compiling function. For
 example, on a Unix system where LF is the default newline sequence, the pattern
@@ -201,8 +218,8 @@
 true. It also affects the interpretation of the dot metacharacter when
 PCRE2_DOTALL is not set, and the behaviour of \eN. However, it does not affect
 what the \eR escape sequence matches. By default, this is any Unicode newline
-sequence, for Perl compatibility. However, this can be changed; see the
-description of \eR in the section entitled
+sequence, for Perl compatibility. However, this can be changed; see the next
+section and the description of \eR in the section entitled
 .\" HTML <a href="#newlineseq">
 .\" </a>
 "Newline sequences"
@@ -225,7 +242,7 @@
 .rs
 .sp
 PCRE2 can be compiled to run in an environment that uses EBCDIC as its
-character code rather than ASCII or Unicode (typically a mainframe system). In
+character code instead of ASCII or Unicode (typically a mainframe system). In
 the sections below, character code values are ASCII or Unicode; in an EBCDIC
 environment these characters may have different code values, and there are no
 code points greater than 255.
@@ -292,11 +309,11 @@
 that character may have. This use of backslash as an escape character applies
 both inside and outside character classes.
 .P
-For example, if you want to match a * character, you write \e* in the pattern.
-This escaping action applies whether or not the following character would
-otherwise be interpreted as a metacharacter, so it is always safe to precede a
-non-alphanumeric with backslash to specify that it stands for itself. In
-particular, if you want to match a backslash, you write \e\e.
+For example, if you want to match a * character, you must write \e* in the
+pattern. This escaping action applies whether or not the following character
+would otherwise be interpreted as a metacharacter, so it is always safe to
+precede a non-alphanumeric with backslash to specify that it stands for itself.
+In particular, if you want to match a backslash, you write \e\e.
 .P
 In a UTF mode, only ASCII numbers and letters have any special meaning after a
 backslash. All other characters (in particular, those whose codepoints are
@@ -326,7 +343,7 @@
 by \eE later in the pattern, the literal interpretation continues to the end of
 the pattern (that is, \eE is assumed at the end). If the isolated \eQ is inside
 a character class, this causes an error, because the character class is not
-terminated.
+terminated by a closing square bracket.
 .
 .
 .\" HTML <a name="digitsafterbackslash"></a>
@@ -359,29 +376,28 @@
 40) is inverted. Thus \ecA to \ecZ become hex 01 to hex 1A (A is 41, Z is 5A),
 but \ec{ becomes hex 3B ({ is 7B), and \ec; becomes hex 7B (; is 3B). If the
 code unit following \ec has a value less than 32 or greater than 126, a
-compile-time error occurs. This locks out non-printable ASCII characters in all
-modes.
+compile-time error occurs.
 .P
 When PCRE2 is compiled in EBCDIC mode, \ea, \ee, \ef, \en, \er, and \et
 generate the appropriate EBCDIC code values. The \ec escape is processed
 as specified for Perl in the \fBperlebcdic\fP document. The only characters
 that are allowed after \ec are A-Z, a-z, or one of @, [, \e, ], ^, _, or ?. Any
-other character provokes a compile-time error. The sequence \e@ encodes
-character code 0; the letters (in either case) encode characters 1-26 (hex 01
-to hex 1A); [, \e, ], ^, and _ encode characters 27-31 (hex 1B to hex 1F), and
-\e? becomes either 255 (hex FF) or 95 (hex 5F).
+other character provokes a compile-time error. The sequence \ec@ encodes
+character code 0; after \ec the letters (in either case) encode characters 1-26
+(hex 01 to hex 1A); [, \e, ], ^, and _ encode characters 27-31 (hex 1B to hex
+1F), and \ec? becomes either 255 (hex FF) or 95 (hex 5F).
 .P
-Thus, apart from \e?, these escapes generate the same character code values as
+Thus, apart from \ec?, these escapes generate the same character code values as
 they do in an ASCII environment, though the meanings of the values mostly
-differ. For example, \eG always generates code value 7, which is BEL in ASCII
+differ. For example, \ecG always generates code value 7, which is BEL in ASCII
 but DEL in EBCDIC.
 .P
-The sequence \e? generates DEL (127, hex 7F) in an ASCII environment, but
+The sequence \ec? generates DEL (127, hex 7F) in an ASCII environment, but
 because 127 is not a control character in EBCDIC, Perl makes it generate the
 APC character. Unfortunately, there are several variants of EBCDIC. In most of
 them the APC character has the value 255 (hex FF), but in the one Perl calls
 POSIX-BC its value is 95 (hex 5F). If certain other characters have POSIX-BC
-values, PCRE2 makes \e? generate 95; otherwise it generates 255.
+values, PCRE2 makes \ec? generate 95; otherwise it generates 255.
 .P
 After \e0 up to two further octal digits are read. If there are fewer than two
 digits, just those that are present are used. Thus the sequence \e0\ex\e015
@@ -455,9 +471,9 @@
 .P
 If the PCRE2_ALT_BSUX option is set, the interpretation of \ex is as just
 described only when it is followed by two hexadecimal digits. Otherwise, it
-matches a literal "x" character. In this mode mode, support for code points
-greater than 256 is provided by \eu, which must be followed by four hexadecimal
-digits; otherwise it matches a literal "u" character.
+matches a literal "x" character. In this mode, support for code points greater
+than 256 is provided by \eu, which must be followed by four hexadecimal digits;
+otherwise it matches a literal "u" character.
 .P
 Characters whose value is less than 256 can be defined by either of the two
 syntaxes for \ex (or by \eu in PCRE2_ALT_BSUX mode). There is no difference in
@@ -471,15 +487,15 @@
 Characters that are specified using octal or hexadecimal numbers are
 limited to certain values, as follows:
 .sp
-  8-bit non-UTF mode    less than 0x100
-  8-bit UTF-8 mode      less than 0x10ffff and a valid codepoint
-  16-bit non-UTF mode   less than 0x10000
-  16-bit UTF-16 mode    less than 0x10ffff and a valid codepoint
-  32-bit non-UTF mode   less than 0x100000000
-  32-bit UTF-32 mode    less than 0x10ffff and a valid codepoint
+  8-bit non-UTF mode    no greater than 0xff
+  16-bit non-UTF mode   no greater than 0xffff
+  32-bit non-UTF mode   no greater than 0xffffffff
+  All UTF modes         no greater than 0x10ffff and a valid codepoint
 .sp
-Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called
-"surrogate" codepoints), and 0xffef.
+Invalid Unicode codepoints are all those in the range 0xd800 to 0xdfff (the
+so-called "surrogate" codepoints). The check for these can be disabled by the
+caller of \fBpcre2_compile()\fP by setting the option
+PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES.
 .
 .
 .SS "Escape sequences in character classes"
@@ -502,15 +518,15 @@
 handler and used to modify the case of following characters. By default, PCRE2
 does not support these escape sequences. However, if the PCRE2_ALT_BSUX option
 is set, \eU matches a "U" character, and \eu can be used to define a character
-by code point, as described in the previous section.
+by code point, as described above.
 .
 .
 .SS "Absolute and relative back references"
 .rs
 .sp
-The sequence \eg followed by an unsigned or a negative number, optionally
-enclosed in braces, is an absolute or relative back reference. A named back
-reference can be coded as \eg{name}. Back references are discussed
+The sequence \eg followed by a signed or unsigned number, optionally enclosed
+in braces, is an absolute or relative back reference. A named back reference
+can be coded as \eg{name}. Back references are discussed
 .\" HTML <a href="#backreferences">
 .\" </a>
 later,
@@ -710,7 +726,9 @@
 sequences that match characters with specific properties are available. In
 8-bit non-UTF-8 mode, these sequences are of course limited to testing
 characters whose codepoints are less than 256, but they do work in this mode.
-The extra escape sequences are:
+In 32-bit non-UTF mode, codepoints greater than 0x10ffff (the Unicode limit)
+may be encountered. These are all treated as being in the Common script and
+with an unassigned type. The extra escape sequences are:
 .sp
   \ep{\fIxx\fP}   a character with the \fIxx\fP property
   \eP{\fIxx\fP}   a character without the \fIxx\fP property
@@ -738,6 +756,7 @@
 Those that are not part of an identified script are lumped together as
 "Common". The current list of scripts is:
 .P
+Adlam,
 Ahom,
 Anatolian_Hieroglyphs,
 Arabic,
@@ -748,6 +767,7 @@
 Bassa_Vah,
 Batak,
 Bengali,
+Bhaiksuki,
 Bopomofo,
 Brahmi,
 Braille,
@@ -809,6 +829,8 @@
 Malayalam,
 Mandaic,
 Manichaean,
+Marchen,
+Masaram_Gondi,
 Meetei_Mayek,
 Mende_Kikakui,
 Meroitic_Cursive,
@@ -821,7 +843,9 @@
 Myanmar,
 Nabataean,
 New_Tai_Lue,
+Newa,
 Nko,
+Nushu,
 Ogham,
 Ol_Chiki,
 Old_Hungarian,
@@ -832,6 +856,7 @@
 Old_South_Arabian,
 Old_Turkic,
 Oriya,
+Osage,
 Osmanya,
 Pahawh_Hmong,
 Palmyrene,
@@ -849,6 +874,7 @@
 SignWriting,
 Sinhala,
 Sora_Sompeng,
+Soyombo,
 Sundanese,
 Syloti_Nagri,
 Syriac,
@@ -859,6 +885,7 @@
 Tai_Viet,
 Takri,
 Tamil,
+Tangut,
 Telugu,
 Thaana,
 Thai,
@@ -868,7 +895,8 @@
 Ugaritic,
 Vai,
 Warang_Citi,
-Yi.
+Yi,
+Zanabazar_Square.
 .P
 Each character has exactly one Unicode general category property, specified by
 a two-letter abbreviation. For compatibility with Perl, negation can be
@@ -972,9 +1000,11 @@
 .\"
 Unicode supports various kinds of composite character by giving each character
 a grapheme breaking property, and having rules that use these properties to
-define the boundaries of extended grapheme clusters. \eX always matches at
-least one character. Then it decides whether to add additional characters
-according to the following rules for ending a cluster:
+define the boundaries of extended grapheme clusters. The rules are defined in
+Unicode Standard Annex 29, "Unicode Text Segmentation".
+.P
+\eX always matches at least one character. Then it decides whether to add
+additional characters according to the following rules for ending a cluster:
 .P
 1. End at the end of the subject string.
 .P
@@ -985,11 +1015,22 @@
 L, V, LV, or LVT character; an LV or V character may be followed by a V or T
 character; an LVT or T character may be follwed only by a T character.
 .P
-4. Do not end before extending characters or spacing marks. Characters with
-the "mark" property always have the "extend" grapheme breaking property.
+4. Do not end before extending characters or spacing marks or the "zero-width
+joiner" characters. Characters with the "mark" property always have the
+"extend" grapheme breaking property.
 .P
 5. Do not end after prepend characters.
 .P
+6. Do not break within emoji modifier sequences (a base character followed by a
+modifier). Extending characters are allowed before the modifier.
+.P
+7. Do not break within emoji zwj sequences (zero-width jointer followed by
+"glue after ZWJ" or "base glue after ZWJ").
+.P
+8. Do not break within emoji flag sequences. That is, do not break between
+regional indicator (RI) characters if there are an odd number of RI characters
+before the break point.
+.P
 6. Otherwise, end the cluster.
 .
 .
@@ -1325,46 +1366,6 @@
 whatever setting of the PCRE2_DOTALL and PCRE2_MULTILINE options is used. A
 class such as [^a] always matches one of these characters.
 .P
-The minus (hyphen) character can be used to specify a range of characters in a
-character class. For example, [d-m] matches any letter between d and m,
-inclusive. If a minus character is required in a class, it must be escaped with
-a backslash or appear in a position where it cannot be interpreted as
-indicating a range, typically as the first or last character in the class, or
-immediately after a range. For example, [b-d-z] matches letters in the range b
-to d, a hyphen character, or z.
-.P
-It is not possible to have the literal character "]" as the end character of a
-range. A pattern such as [W-]46] is interpreted as a class of two characters
-("W" and "-") followed by a literal string "46]", so it would match "W46]" or
-"-46]". However, if the "]" is escaped with a backslash it is interpreted as
-the end of range, so [W-\e]46] is interpreted as a class containing a range
-followed by two other characters. The octal or hexadecimal representation of
-"]" can also be used to end a range.
-.P
-An error is generated if a POSIX character class (see below) or an escape
-sequence other than one that defines a single character appears at a point
-where a range ending character is expected. For example, [z-\exff] is valid,
-but [A-\ed] and [A-[:digit:]] are not.
-.P
-Ranges normally include all code points between the start and end characters,
-inclusive. They can also be used for code points specified numerically, for
-example [\e000-\e037]. Ranges can include any characters that are valid for the
-current mode.
-.P
-There is a special case in EBCDIC environments for ranges whose end points are
-both specified as literal letters in the same case. For compatibility with
-Perl, EBCDIC code points within the range that are not letters are omitted. For
-example, [h-k] matches only four characters, even though the codes for h and k
-are 0x88 and 0x92, a range of 11 code points. However, if the range is
-specified numerically, for example, [\ex88-\ex92] or [h-\ex92], all code points
-are included.
-.P
-If a range that includes letters is used when caseless matching is set, it
-matches the letters in either case. For example, [W-c] is equivalent to
-[][\e\e^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character
-tables for a French locale are in use, [\exc8-\excb] matches accented E
-characters in both cases.
-.P
 The character escape sequences \ed, \eD, \eh, \eH, \ep, \eP, \es, \eS, \ev,
 \eV, \ew, and \eW may appear in a character class, and add the characters that
 they match to the class. For example, [\edABCDEF] matches any hexadecimal
@@ -1380,6 +1381,51 @@
 are not special inside a character class. Like any other unrecognized escape
 sequences, they cause an error.
 .P
+The minus (hyphen) character can be used to specify a range of characters in a
+character class. For example, [d-m] matches any letter between d and m,
+inclusive. If a minus character is required in a class, it must be escaped with
+a backslash or appear in a position where it cannot be interpreted as
+indicating a range, typically as the first or last character in the class,
+or immediately after a range. For example, [b-d-z] matches letters in the range
+b to d, a hyphen character, or z.
+.P
+Perl treats a hyphen as a literal if it appears before or after a POSIX class
+(see below) or before or after a character type escape such as as \ed or \eH.
+However, unless the hyphen is the last character in the class, Perl outputs a
+warning in its warning mode, as this is most likely a user error. As PCRE2 has
+no facility for warning, an error is given in these cases.
+.P
+It is not possible to have the literal character "]" as the end character of a
+range. A pattern such as [W-]46] is interpreted as a class of two characters
+("W" and "-") followed by a literal string "46]", so it would match "W46]" or
+"-46]". However, if the "]" is escaped with a backslash it is interpreted as
+the end of range, so [W-\e]46] is interpreted as a class containing a range
+followed by two other characters. The octal or hexadecimal representation of
+"]" can also be used to end a range.
+.P
+Ranges normally include all code points between the start and end characters,
+inclusive. They can also be used for code points specified numerically, for
+example [\e000-\e037]. Ranges can include any characters that are valid for the
+current mode. In any UTF mode, the so-called "surrogate" characters (those
+whose code points lie between 0xd800 and 0xdfff inclusive) may not be specified
+explicitly by default (the PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES option disables
+this check). However, ranges such as [\ex{d7ff}-\ex{e000}], which include the
+surrogates, are always permitted.
+.P
+There is a special case in EBCDIC environments for ranges whose end points are
+both specified as literal letters in the same case. For compatibility with
+Perl, EBCDIC code points within the range that are not letters are omitted. For
+example, [h-k] matches only four characters, even though the codes for h and k
+are 0x88 and 0x92, a range of 11 code points. However, if the range is
+specified numerically, for example, [\ex88-\ex92] or [h-\ex92], all code points
+are included.
+.P
+If a range that includes letters is used when caseless matching is set, it
+matches the letters in either case. For example, [W-c] is equivalent to
+[][\e\e^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character
+tables for a French locale are in use, [\exc8-\excb] matches accented E
+characters in both cases.
+.P
 A circumflex can conveniently be used with the upper case character types to
 specify a more restricted set of characters than the matching lower case type.
 For example, the class [^\eW_] matches any letter or digit, but not underscore,
@@ -1527,20 +1573,25 @@
 .SH "INTERNAL OPTION SETTING"
 .rs
 .sp
-The settings of the PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL, and
-PCRE2_EXTENDED options (which are Perl-compatible) can be changed from within
-the pattern by a sequence of Perl option letters enclosed between "(?" and ")".
-The option letters are
+The settings of the PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL,
+PCRE2_EXTENDED, PCRE2_EXTENDED_MORE, and PCRE2_NO_AUTO_CAPTURE options (which
+are Perl-compatible) can be changed from within the pattern by a sequence of
+Perl option letters enclosed between "(?" and ")". The option letters are
 .sp
   i  for PCRE2_CASELESS
   m  for PCRE2_MULTILINE
+  n  for PCRE2_NO_AUTO_CAPTURE
   s  for PCRE2_DOTALL
   x  for PCRE2_EXTENDED
+  xx for PCRE2_EXTENDED_MORE
 .sp
 For example, (?im) sets caseless, multiline matching. It is also possible to
-unset these options by preceding the letter with a hyphen, and a combined
-setting and unsetting such as (?im-sx), which sets PCRE2_CASELESS and
-PCRE2_MULTILINE while unsetting PCRE2_DOTALL and PCRE2_EXTENDED, is also
+unset these options by preceding the letter with a hyphen. The two "extended"
+options are not independent; unsetting either one cancels the effects of both
+of them.
+.P
+A combined setting and unsetting such as (?im-sx), which sets PCRE2_CASELESS
+and PCRE2_MULTILINE while unsetting PCRE2_DOTALL and PCRE2_EXTENDED, is also
 permitted. If a letter appears both before and after the hyphen, the option is
 unset. An empty options setting "(?)" is allowed. Needless to say, it has no
 effect.
@@ -1551,12 +1602,8 @@
 .P
 When one of these option changes occurs at top level (that is, not inside
 subpattern parentheses), the change applies to the remainder of the pattern
-that follows. If the change is placed right at the start of a pattern, PCRE2
-extracts it into the global options (and it will therefore show up in data
-extracted by the \fBpcre2_pattern_info()\fP function).
-.P
-An option change within a subpattern (see below for a description of
-subpatterns) affects only that part of the subpattern that follows it, so
+that follows. An option change within a subpattern (see below for a description
+of subpatterns) affects only that part of the subpattern that follows it, so
 .sp
   (a(?i)b)c
 .sp
@@ -2096,9 +2143,9 @@
 subpattern is possible using named parentheses (see below).
 .P
 Another way of avoiding the ambiguity inherent in the use of digits following a
-backslash is to use the \eg escape sequence. This escape must be followed by an
-unsigned number or a negative number, optionally enclosed in braces. These
-examples are all identical:
+backslash is to use the \eg escape sequence. This escape must be followed by a
+signed or unsigned number, optionally enclosed in braces. These examples are
+all identical:
 .sp
   (ring), \e1
   (ring), \eg1
@@ -2106,8 +2153,7 @@
 .sp
 An unsigned number specifies an absolute reference without the ambiguity that
 is present in the older syntax. It is also useful when literal digits follow
-the reference. A negative number is a relative reference. Consider this
-example:
+the reference. A signed number is a relative reference. Consider this example:
 .sp
   (abc(def)ghi)\eg{-1}
 .sp
@@ -2117,6 +2163,10 @@
 can be helpful in long patterns, and also in patterns that are created by
 joining together fragments that contain references within themselves.
 .P
+The sequence \eg{+1} is a reference to the next capturing subpattern. This kind
+of forward reference can be useful it patterns that repeat. Perl does not
+support the use of + in this way.
+.P
 A back reference matches whatever actually matched the capturing subpattern in
 the current subject string, rather than anything matching the subpattern
 itself (see
@@ -2215,14 +2265,28 @@
 .P
 More complicated assertions are coded as subpatterns. There are two kinds:
 those that look ahead of the current position in the subject string, and those
-that look behind it. An assertion subpattern is matched in the normal way,
-except that it does not cause the current matching position to be changed.
+that look behind it, and in each case an assertion may be positive (must
+succeed for matching to continue) or negative (must not succeed for matching to
+continue). An assertion subpattern is matched in the normal way, except that,
+when matching continues afterwards, the matching position in the subject string
+is as it was at the start of the assertion.
 .P
-Assertion subpatterns are not capturing subpatterns. If such an assertion
-contains capturing subpatterns within it, these are counted for the purposes of
+Assertion subpatterns are not capturing subpatterns. If an assertion contains
+capturing subpatterns within it, these are counted for the purposes of
 numbering the capturing subpatterns in the whole pattern. However, substring
-capturing is carried out only for positive assertions. (Perl sometimes, but not
-always, does do capturing in negative assertions.)
+capturing is carried out only for positive assertions that succeed, that is,
+one of their branches matches, so matching continues after the assertion. If
+all branches of a positive assertion fail to match, nothing is captured, and
+control is passed to the previous backtracking point.
+.P
+No capturing is done for a negative assertion unless it is being used as a
+condition in a
+.\" HTML <a href="#subpatternsassubroutines">
+.\" </a>
+conditional subpattern
+.\"
+(see the discussion below). Matching continues after a non-conditional negative
+assertion only if all its branches fail to match.
 .P
 For compatibility with Perl, most assertion subpatterns may be repeated; though
 it makes no sense to assert the same thing several times, the side effect of
@@ -2321,23 +2385,34 @@
 match. If there are insufficient characters before the current position, the
 assertion fails.
 .P
-In a UTF mode, PCRE2 does not allow the \eC escape (which matches a single code
-unit even in a UTF mode) to appear in lookbehind assertions, because it makes
-it impossible to calculate the length of the lookbehind. The \eX and \eR
-escapes, which can match different numbers of code units, are also not
-permitted.
+In UTF-8 and UTF-16 modes, PCRE2 does not allow the \eC escape (which matches a
+single code unit even in a UTF mode) to appear in lookbehind assertions,
+because it makes it impossible to calculate the length of the lookbehind. The
+\eX and \eR escapes, which can match different numbers of code units, are never
+permitted in lookbehinds.
 .P
 .\" HTML <a href="#subpatternsassubroutines">
 .\" </a>
 "Subroutine"
 .\"
 calls (see below) such as (?2) or (?&X) are permitted in lookbehinds, as long
-as the subpattern matches a fixed-length string.
+as the subpattern matches a fixed-length string. However,
 .\" HTML <a href="#recursion">
 .\" </a>
-Recursion,
+recursion,
 .\"
-however, is not supported.
+that is, a "subroutine" call into a group that is already active,
+is not supported.
+.P
+Perl does not support back references in lookbehinds. PCRE2 does support them,
+but only if certain conditions are met. The PCRE2_MATCH_UNSET_BACKREF option
+must not be set, there must be no use of (?| in the pattern (it creates
+duplicate subpattern numbers), and if the back reference is by name, the name
+must be unique. Of course, the referenced subpattern must itself be of fixed
+length. The following pattern matches words containing at least two characters
+that begin and end with the same character:
+.sp
+   \eb(\ew)\ew++(?<=\e1)
 .P
 Possessive quantifiers can be used in conjunction with lookbehind assertions to
 specify efficient matching of fixed-length strings at the end of subject
@@ -2476,7 +2551,9 @@
 .sp
 Perl uses the syntax (?(<name>)...) or (?('name')...) to test for a used
 subpattern by name. For compatibility with earlier versions of PCRE1, which had
-this facility before Perl, the syntax (?(name)...) is also recognized.
+this facility before Perl, the syntax (?(name)...) is also recognized. Note,
+however, that undelimited names consisting of the letter R followed by digits
+are ambiguous (see the following section).
 .P
 Rewriting the above example to use a named subpattern gives this:
 .sp
@@ -2490,33 +2567,55 @@
 .SS "Checking for pattern recursion"
 .rs
 .sp
-If the condition is the string (R), and there is no subpattern with the name R,
-the condition is true if a recursive call to the whole pattern or any
-subpattern has been made. If digits or a name preceded by ampersand follow the
-letter R, for example:
-.sp
-  (?(R3)...) or (?(R&name)...)
-.sp
-the condition is true if the most recent recursion is into a subpattern whose
-number or name is given. This condition does not check the entire recursion
-stack. If the name used in a condition of this kind is a duplicate, the test is
-applied to all subpatterns of the same name, and is true if any one of them is
-the most recent recursion.
-.P
-At "top level", all these recursion test conditions are false.
+"Recursion" in this sense refers to any subroutine-like call from one part of
+the pattern to another, whether or not it is actually recursive. See the
+sections entitled
 .\" HTML <a href="#recursion">
 .\" </a>
-The syntax for recursive patterns
+"Recursive patterns"
 .\"
-is described below.
+and
+.\" HTML <a href="#subpatternsassubroutines">
+.\" </a>
+"Subpatterns as subroutines"
+.\"
+below for details of recursion and subpattern calls.
+.P
+If a condition is the string (R), and there is no subpattern with the name R,
+the condition is true if matching is currently in a recursion or subroutine
+call to the whole pattern or any subpattern. If digits follow the letter R, and
+there is no subpattern with that name, the condition is true if the most recent
+call is into a subpattern with the given number, which must exist somewhere in
+the overall pattern. This is a contrived example that is equivalent to a+b:
+.sp
+  ((?(R1)a+|(?1)b))
+.sp
+However, in both cases, if there is a subpattern with a matching name, the
+condition tests for its being set, as described in the section above, instead
+of testing for recursion. For example, creating a group with the name R1 by
+adding (?<R1>) to the above pattern completely changes its meaning.
+.P
+If a name preceded by ampersand follows the letter R, for example:
+.sp
+  (?(R&name)...)
+.sp
+the condition is true if the most recent recursion is into a subpattern of that
+name (which must exist within the pattern).
+.P
+This condition does not check the entire recursion stack. It tests only the
+current level. If the name used in a condition of this kind is a duplicate, the
+test is applied to all subpatterns of the same name, and is true if any one of
+them is the most recent recursion.
+.P
+At "top level", all these recursion test conditions are false.
 .
 .
 .\" HTML <a name="subdefine"></a>
 .SS "Defining subpatterns for use by reference only"
 .rs
 .sp
-If the condition is the string (DEFINE), and there is no subpattern with the
-name DEFINE, the condition is always false. In this case, there may be only one
+If the condition is the string (DEFINE), the condition is always false, even if
+there is a group with the name DEFINE. In this case, there may be only one
 alternative in the subpattern. It is always skipped if control reaches this
 point in the pattern; the idea of DEFINE is that it can be used to define
 subroutines that can be referenced from elsewhere. (The use of
@@ -2574,6 +2673,12 @@
 subject is matched against the first alternative; otherwise it is matched
 against the second. This pattern matches strings in one of the two forms
 dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.
+.P
+When an assertion that is a condition contains capturing subpatterns, any
+capturing that occurs in a matching branch is retained afterwards, for both
+positive and negative assertions, because matching always continues after the
+assertion, whether it succeeds or fails. (Compare non-conditional assertions,
+when captures are retained only for positive assertions that succeed.)
 .
 .
 .\" HTML <a name="comments"></a>
@@ -2753,88 +2858,53 @@
 .SS "Differences in recursion processing between PCRE2 and Perl"
 .rs
 .sp
-Recursion processing in PCRE2 differs from Perl in two important ways. In PCRE2
-(like Python, but unlike Perl), a recursive subpattern call is always treated
-as an atomic group. That is, once it has matched some of the subject string, it
-is never re-entered, even if it contains untried alternatives and there is a
-subsequent matching failure. This can be illustrated by the following pattern,
-which purports to match a palindromic string that contains an odd number of
-characters (for example, "a", "aba", "abcba", "abcdcba"):
-.sp
-  ^(.|(.)(?1)\e2)$
-.sp
-The idea is that it either matches a single character, or two identical
-characters surrounding a sub-palindrome. In Perl, this pattern works; in PCRE2
-it does not if the pattern is longer than three characters. Consider the
-subject string "abcba":
+Some former differences between PCRE2 and Perl no longer exist.
 .P
-At the top level, the first character is matched, but as it is not at the end
-of the string, the first alternative fails; the second alternative is taken
-and the recursion kicks in. The recursive call to subpattern 1 successfully
-matches the next character ("b"). (Note that the beginning and end of line
-tests are not part of the recursion).
+Before release 10.30, recursion processing in PCRE2 differed from Perl in that
+a recursive subpattern call was always treated as an atomic group. That is,
+once it had matched some of the subject string, it was never re-entered, even
+if it contained untried alternatives and there was a subsequent matching
+failure. (Historical note: PCRE implemented recursion before Perl did.)
 .P
-Back at the top level, the next character ("c") is compared with what
-subpattern 2 matched, which was "a". This fails. Because the recursion is
-treated as an atomic group, there are now no backtracking points, and so the
-entire match fails. (Perl is able, at this point, to re-enter the recursion and
-try the second alternative.) However, if the pattern is written with the
-alternatives in the other order, things are different:
-.sp
-  ^((.)(?1)\e2|.)$
-.sp
-This time, the recursing alternative is tried first, and continues to recurse
-until it runs out of characters, at which point the recursion fails. But this
-time we do have another alternative to try at the higher level. That is the big
-difference: in the previous case the remaining alternative is at a deeper
-recursion level, which PCRE2 cannot use.
+Starting with release 10.30, recursive subroutine calls are no longer treated
+as atomic. That is, they can be re-entered to try unused alternatives if there
+is a matching failure later in the pattern. This is now compatible with the way
+Perl works. If you want a subroutine call to be atomic, you must explicitly
+enclose it in an atomic group.
 .P
-To change the pattern so that it matches all palindromic strings, not just
-those with an odd number of characters, it is tempting to change the pattern to
-this:
+Supporting backtracking into recursions simplifies certain types of recursive
+pattern. For example, this pattern matches palindromic strings:
 .sp
   ^((.)(?1)\e2|.?)$
 .sp
-Again, this works in Perl, but not in PCRE2, and for the same reason. When a
-deeper recursion has matched a single character, it cannot be entered again in
-order to match an empty string. The solution is to separate the two cases, and
-write out the odd and even cases as alternatives at the higher level:
+The second branch in the group matches a single central character in the
+palindrome when there are an odd number of characters, or nothing when there
+are an even number of characters, but in order to work it has to be able to try
+the second case when the rest of the pattern match fails. If you want to match
+typical palindromic phrases, the pattern has to ignore all non-word characters,
+which can be done like this:
 .sp
-  ^(?:((.)(?1)\e2|)|((.)(?3)\e4|.))
-.sp
-If you want to match typical palindromic phrases, the pattern has to ignore all
-non-word characters, which can be done like this:
-.sp
-  ^\eW*+(?:((.)\eW*+(?1)\eW*+\e2|)|((.)\eW*+(?3)\eW*+\e4|\eW*+.\eW*+))\eW*+$
+  ^\eW*+((.)\eW*+(?1)\eW*+\e2|\eW*+.?)\eW*+$
 .sp
 If run with the PCRE2_CASELESS option, this pattern matches phrases such as "A
-man, a plan, a canal: Panama!" and it works in both PCRE2 and Perl. Note the
-use of the possessive quantifier *+ to avoid backtracking into sequences of
-non-word characters. Without this, PCRE2 takes a great deal longer (ten times
-or more) to match typical phrases, and Perl takes so long that you think it has
-gone into a loop.
+man, a plan, a canal: Panama!". Note the use of the possessive quantifier *+ to
+avoid backtracking into sequences of non-word characters. Without this, PCRE2
+takes a great deal longer (ten times or more) to match typical phrases, and
+Perl takes so long that you think it has gone into a loop.
 .P
-\fBWARNING\fP: The palindrome-matching patterns above work only if the subject
-string does not start with a palindrome that is shorter than the entire string.
-For example, although "abcba" is correctly matched, if the subject is "ababa",
-PCRE2 finds the palindrome "aba" at the start, then fails at top level because
-the end of the string does not follow. Once again, it cannot jump back into the
-recursion to try other alternatives, so the entire match fails.
-.P
-The second way in which PCRE2 and Perl differ in their recursion processing is
-in the handling of captured values. In Perl, when a subpattern is called
-recursively or as a subpattern (see the next section), it has no access to any
-values that were captured outside the recursion, whereas in PCRE2 these values
-can be referenced. Consider this pattern:
+Another way in which PCRE2 and Perl used to differ in their recursion
+processing is in the handling of captured values. Formerly in Perl, when a
+subpattern was called recursively or as a subpattern (see the next section), it
+had no access to any values that were captured outside the recursion, whereas
+in PCRE2 these values can be referenced. Consider this pattern:
 .sp
   ^(.)(\e1|a(?2))
 .sp
-In PCRE2, this pattern matches "bab". The first capturing parentheses match "b",
-then in the second group, when the back reference \e1 fails to match "b", the
-second alternative matches "a" and then recurses. In the recursion, \e1 does
-now match "b" and so the whole match succeeds. In Perl, the pattern fails to
-match because inside the recursive call \e1 cannot access the externally set
-value.
+This pattern matches "bab". The first capturing parentheses match "b", then in
+the second group, when the back reference \e1 fails to match "b", the second
+alternative matches "a" and then recurses. In the recursion, \e1 does now match
+"b" and so the whole match succeeds. This match used to fail in Perl, but in
+later versions (I tried 5.024) it now works.
 .
 .
 .\" HTML <a name="subpatternsassubroutines"></a>
@@ -2863,11 +2933,10 @@
 is used, it does match "sense and responsibility" as well as the other two
 strings. Another example is given in the discussion of DEFINE above.
 .P
-All subroutine calls, whether recursive or not, are always treated as atomic
-groups. That is, once a subroutine has matched some of the subject string, it
-is never re-entered, even if it contains untried alternatives and there is a
-subsequent matching failure. Any capturing parentheses that are set during the
-subroutine call revert to their previous values afterwards.
+Like recursions, subroutine calls used to be treated as atomic, but this
+changed at PCRE2 release 10.30, so backtracking into subroutine calls can now
+occur. However, any capturing parentheses that are set during the subroutine
+call revert to their previous values afterwards.
 .P
 Processing options such as case-independence are fixed when a subpattern is
 defined, so if it is used as a subroutine, such options cannot be changed for
@@ -2980,26 +3049,28 @@
 .SH "BACKTRACKING CONTROL"
 .rs
 .sp
-Perl 5.10 introduced a number of "Special Backtracking Control Verbs", which
-are still described in the Perl documentation as "experimental and subject to
-change or removal in a future version of Perl". It goes on to say: "Their usage
-in production code should be noted to avoid problems during upgrades." The same
-remarks apply to the PCRE2 features described in this section.
-.P
-The new verbs make use of what was previously invalid syntax: an opening
-parenthesis followed by an asterisk. They are generally of the form (*VERB) or
-(*VERB:NAME). Some verbs take either form, possibly behaving differently
-depending on whether or not a name is present.
+There are a number of special "Backtracking Control Verbs" (to use Perl's
+terminology) that modify the behaviour of backtracking during matching. They
+are generally of the form (*VERB) or (*VERB:NAME). Some verbs take either form,
+possibly behaving differently depending on whether or not a name is present.
 .P
 By default, for compatibility with Perl, a name is any sequence of characters
 that does not include a closing parenthesis. The name is not processed in
 any way, and it is not possible to include a closing parenthesis in the name.
-However, if the PCRE2_ALT_VERBNAMES option is set, normal backslash processing
-is applied to verb names and only an unescaped closing parenthesis terminates
-the name. A closing parenthesis can be included in a name either as \e) or
-between \eQ and \eE. If the PCRE2_EXTENDED option is set, unescaped whitespace
-in verb names is skipped and #-comments are recognized, exactly as in the rest
-of the pattern.
+This can be changed by setting the PCRE2_ALT_VERBNAMES option, but the result
+is no longer Perl-compatible.
+.P
+When PCRE2_ALT_VERBNAMES is set, backslash processing is applied to verb names
+and only an unescaped closing parenthesis terminates the name. However, the
+only backslash items that are permitted are \eQ, \eE, and sequences such as
+\ex{100} that define character code points. Character type escapes such as \ed
+are faulted.
+.P
+A closing parenthesis can be included in a name either as \e) or between \eQ
+and \eE. In addition to backslash processing, if the PCRE2_EXTENDED option is
+also set, unescaped whitespace in verb names is skipped, and #-comments are
+recognized, exactly as in the rest of the pattern. PCRE2_EXTENDED does not
+affect verb names unless PCRE2_ALT_VERBNAMES is also set.
 .P
 The maximum length of a name is 255 in the 8-bit library and 65535 in the
 16-bit and 32-bit libraries. If the name is empty, that is, if the closing
@@ -3008,7 +3079,7 @@
 .P
 Since these verbs are specifically related to backtracking, most of them can be
 used only when the pattern is to be matched using the traditional matching
-function, because these use a backtracking algorithm. With the exception of
+function, because that uses a backtracking algorithm. With the exception of
 (*FAIL), which behaves like a failing negative assertion, the backtracking
 control verbs cause an error if encountered by the DFA matching function.
 .P
@@ -3162,11 +3233,11 @@
 The following verbs do nothing when they are encountered. Matching continues
 with what follows, but if there is no subsequent match, causing a backtrack to
 the verb, a failure is forced. That is, backtracking cannot pass to the left of
-the verb. However, when one of these verbs appears inside an atomic group
-(which includes any group that is called as a subroutine) or in an assertion
-that is true, its effect is confined to that group, because once the group has
-been matched, there is never any backtracking into it. In this situation,
-backtracking has to jump to the left of the entire atomic group or assertion.
+the verb. However, when one of these verbs appears inside an atomic group or in
+an assertion that is true, its effect is confined to that group, because once
+the group has been matched, there is never any backtracking into it. In this
+situation, backtracking has to jump to the left of the entire atomic group or
+assertion.
 .P
 These verbs differ in exactly what kind of failure occurs when backtracking
 reaches them. The behaviour described below is what happens when the verb is
@@ -3226,8 +3297,8 @@
 expressed in any other way. In an anchored pattern (*PRUNE) has the same effect
 as (*COMMIT).
 .P
-The behaviour of (*PRUNE:NAME) is the not the same as (*MARK:NAME)(*PRUNE).
-It is like (*MARK:NAME) in that the name is remembered for passing back to the
+The behaviour of (*PRUNE:NAME) is not the same as (*MARK:NAME)(*PRUNE). It is
+like (*MARK:NAME) in that the name is remembered for passing back to the
 caller. However, (*SKIP:NAME) searches only for names set with (*MARK),
 ignoring those set by (*PRUNE) or (*THEN).
 .sp
@@ -3365,25 +3436,30 @@
 .SS "Backtracking verbs in assertions"
 .rs
 .sp
-(*FAIL) in an assertion has its normal effect: it forces an immediate
-backtrack.
+(*FAIL) in any assertion has its normal effect: it forces an immediate
+backtrack. The behaviour of the other backtracking verbs depends on whether or
+not the assertion is standalone or acting as the condition in a conditional
+subpattern.
 .P
-(*ACCEPT) in a positive assertion causes the assertion to succeed without any
-further processing. In a negative assertion, (*ACCEPT) causes the assertion to
-fail without any further processing.
+(*ACCEPT) in a standalone positive assertion causes the assertion to succeed
+without any further processing; captured strings are retained. In a standalone
+negative assertion, (*ACCEPT) causes the assertion to fail without any further
+processing; captured substrings are discarded.
+.P
+If the assertion is a condition, (*ACCEPT) causes the condition to be true for
+a positive assertion and false for a negative one; captured substrings are
+retained in both cases.
+.P
+The effect of (*THEN) is not allowed to escape beyond an assertion. If there
+are no more branches to try, (*THEN) causes a positive assertion to be false,
+and a negative assertion to be true.
 .P
 The other backtracking verbs are not treated specially if they appear in a
-positive assertion. In particular, (*THEN) skips to the next alternative in the
-innermost enclosing group that has alternations, whether or not this is within
-the assertion.
-.P
-Negative assertions are, however, different, in order to ensure that changing a
-positive assertion into a negative assertion changes its result. Backtracking
-into (*COMMIT), (*SKIP), or (*PRUNE) causes a negative assertion to be true,
-without considering any further alternative branches in the assertion.
-Backtracking into (*THEN) causes it to skip to the next enclosing alternative
-within the assertion (the normal behaviour), but if the assertion does not have
-such an alternative, (*THEN) behaves like (*PRUNE).
+standalone positive assertion. In a conditional positive assertion,
+backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes the condition to be
+false. However, for both standalone and conditional negative assertions,
+backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes the assertion to be
+true, without considering any further alternative branches.
 .
 .
 .\" HTML <a name="btsub"></a>
@@ -3429,6 +3505,6 @@
 .rs
 .sp
 .nf
-Last updated: 20 June 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 12 September 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2perform.3 b/dist2/doc/pcre2perform.3
index ec86fe7..8b49a2a 100644
--- a/dist2/doc/pcre2perform.3
+++ b/dist2/doc/pcre2perform.3
@@ -1,4 +1,4 @@
-.TH PCRE2PERFORM 3 "02 January 2015" "PCRE2 10.00"
+.TH PCRE2PERFORM 3 "08 April 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 PERFORMANCE"
@@ -12,11 +12,11 @@
 .rs
 .sp
 Patterns are compiled by PCRE2 into a reasonably efficient interpretive code,
-so that most simple patterns do not use much memory. However, there is one case
-where the memory usage of a compiled pattern can be unexpectedly large. If a
-parenthesized subpattern has a quantifier with a minimum greater than 1 and/or
-a limited maximum, the whole subpattern is repeated in the compiled code. For
-example, the pattern
+so that most simple patterns do not use much memory for storing the compiled
+version. However, there is one case where the memory usage of a compiled
+pattern can be unexpectedly large. If a parenthesized subpattern has a
+quantifier with a minimum greater than 1 and/or a limited maximum, the whole
+subpattern is repeated in the compiled code. For example, the pattern
 .sp
   (abc|def){2,4}
 .sp
@@ -34,13 +34,13 @@
 .sp
   ((ab){1,1000}c){1,3}
 .sp
-uses 51K bytes when compiled using the 8-bit library. When PCRE2 is compiled
-with its default internal pointer size of two bytes, the size limit on a
-compiled pattern is 64K code units in the 8-bit and 16-bit libraries, and this
-is reached with the above pattern if the outer repetition is increased from 3
-to 4. PCRE2 can be compiled to use larger internal pointers and thus handle
-larger compiled patterns, but it is better to try to rewrite your pattern to
-use less memory if you can.
+uses over 50K bytes when compiled using the 8-bit library. When PCRE2 is
+compiled with its default internal pointer size of two bytes, the size limit on
+a compiled pattern is 64K code units in the 8-bit and 16-bit libraries, and
+this is reached with the above pattern if the outer repetition is increased
+from 3 to 4. PCRE2 can be compiled to use larger internal pointers and thus
+handle larger compiled patterns, but it is better to try to rewrite your
+pattern to use less memory if you can.
 .P
 One way of reducing the memory usage for such patterns is to make use of
 PCRE2's
@@ -52,32 +52,35 @@
 .sp
   ((ab)(?2){0,999}c)(?1){0,2}
 .sp
-reduces the memory requirements to 18K, and indeed it remains under 20K even
-with the outer repetition increased to 100. However, this pattern is not
-exactly equivalent, because the "subroutine" calls are treated as
-.\" HTML <a href="pcre2pattern.html#atomicgroup">
-.\" </a>
-atomic groups
-.\"
-into which there can be no backtracking if there is a subsequent matching
-failure. Therefore, PCRE2 cannot do this kind of rewriting automatically.
-Furthermore, there is a noticeable loss of speed when executing the modified
-pattern. Nevertheless, if the atomic grouping is not a problem and the loss of
-speed is acceptable, this kind of rewriting will allow you to process patterns
-that PCRE2 cannot otherwise handle.
+reduces the memory requirements to around 16K, and indeed it remains under 20K
+even with the outer repetition increased to 100. However, this kind of pattern
+is not always exactly equivalent, because any captures within subroutine calls
+are lost when the subroutine completes. If this is not a problem, this kind of
+rewriting will allow you to process patterns that PCRE2 cannot otherwise
+handle. The matching performance of the two different versions of the pattern
+are roughly the same. (This applies from release 10.30 - things were different
+in earlier releases.)
 .
 .
-.SH "STACK USAGE AT RUN TIME"
+.SH "STACK AND HEAP USAGE AT RUN TIME"
 .rs
 .sp
-When \fBpcre2_match()\fP is used for matching, certain kinds of pattern can
-cause it to use large amounts of the process stack. In some environments the
-default process stack is quite small, and if it runs out the result is often
-SIGSEGV. Rewriting your pattern can often help. The
-.\" HREF
-\fBpcre2stack\fP
-.\"
-documentation discusses this issue in detail.
+From release 10.30, the interpretive (non-JIT) version of \fBpcre2_match()\fP
+uses very little system stack at run time. In earlier releases recursive
+function calls could use a great deal of stack, and this could cause problems,
+but this usage has been eliminated. Backtracking positions are now explicitly
+remembered in memory frames controlled by the code. An initial 20K vector of
+frames is allocated on the system stack (enough for about 100 frames for small
+patterns), but if this is insufficient, heap memory is used. The amount of heap
+memory can be limited; if the limit is set to zero, only the initial stack
+vector is used. Rewriting patterns to be time-efficient, as described below,
+may also reduce the memory requirements.
+.P
+In contrast to \fBpcre2_match()\fP, \fBpcre2_dfa_match()\fP does use recursive
+function calls, but only for processing atomic groups, lookaround assertions,
+and recursion within the pattern. Too much nested recursion may cause stack
+issues. The "match depth" parameter can be used to limit the depth of function
+recursion in \fBpcre2_dfa_match()\fP.
 .
 .
 .SH "PROCESSING TIME"
@@ -160,7 +163,59 @@
 appreciable time with strings longer than about 20 characters.
 .P
 In many cases, the solution to this kind of performance issue is to use an
-atomic group or a possessive quantifier.
+atomic group or a possessive quantifier. This can often reduce memory
+requirements as well. As another example, consider this pattern:
+.sp
+  ([^<]|<(?!inet))+
+.sp
+It matches from wherever it starts until it encounters "<inet" or the end of
+the data, and is the kind of pattern that might be used when processing an XML
+file. Each iteration of the outer parentheses matches either one character that
+is not "<" or a "<" that is not followed by "inet". However, each time a
+parenthesis is processed, a backtracking position is passed, so this
+formulation uses a memory frame for each matched character. For a long string,
+a lot of memory is required. Consider now this rewritten pattern, which matches
+exactly the same strings:
+.sp
+  ([^<]++|<(?!inet))+
+.sp
+This runs much faster, because sequences of characters that do not contain "<"
+are "swallowed" in one item inside the parentheses, and a possessive quantifier
+is used to stop any backtracking into the runs of non-"<" characters. This
+version also uses a lot less memory because entry to a new set of parentheses
+happens only when a "<" character that is not followed by "inet" is encountered
+(and we assume this is relatively rare).
+.P
+This example shows that one way of optimizing performance when matching long
+subject strings is to write repeated parenthesized subpatterns to match more
+than one character whenever possible.
+.
+.
+.SS "SETTING RESOURCE LIMITS"
+.rs
+.sp
+You can set limits on the amount of processing that takes place when matching,
+and on the amount of heap memory that is used. The default values of the limits
+are very large, and unlikely ever to operate. They can be changed when PCRE2 is
+built, and they can also be set when \fBpcre2_match()\fP or
+\fBpcre2_dfa_match()\fP is called. For details of these interfaces, see the
+.\" HREF
+\fBpcre2build\fP
+.\"
+documentation and the section entitled
+.\" HTML <a href="pcre2api.html#matchcontext">
+.\" </a>
+"The match context"
+.\"
+in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+documentation.
+.P
+The \fBpcre2test\fP test program has a modifier called "find_limits" which, if
+applied to a subject line, causes it to find the smallest limits that allow a
+pattern to match. This is done by repeatedly matching with different limits.
 .
 .
 .SH AUTHOR
@@ -177,6 +232,6 @@
 .rs
 .sp
 .nf
-Last updated: 02 January 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 08 April 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2posix.3 b/dist2/doc/pcre2posix.3
index 70a86d8..399e2a8 100644
--- a/dist2/doc/pcre2posix.3
+++ b/dist2/doc/pcre2posix.3
@@ -1,4 +1,4 @@
-.TH PCRE2POSIX 3 "31 January 2016" "PCRE2 10.22"
+.TH PCRE2POSIX 3 "15 June 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "SYNOPSIS"
@@ -46,7 +46,7 @@
 .P
 There are also some options that are not defined by POSIX. These have been
 added at the request of users who want to make use of certain PCRE2-specific
-features via the POSIX calling interface.
+features via the POSIX calling interface or to add BSD or GNU functionality.
 .P
 When PCRE2 is called via these functions, it is only the API that is POSIX-like
 in style. The syntax and semantics of the regular expressions themselves are
@@ -68,10 +68,11 @@
 .rs
 .sp
 The function \fBregcomp()\fP is called to compile a pattern into an
-internal form. The pattern is a C string terminated by a binary zero, and
-is passed in the argument \fIpattern\fP. The \fIpreg\fP argument is a pointer
-to a \fBregex_t\fP structure that is used as a base for storing information
-about the compiled regular expression.
+internal form. By default, the pattern is a C string terminated by a binary
+zero (but see REG_PEND below). The \fIpreg\fP argument is a pointer to a
+\fBregex_t\fP structure that is used as a base for storing information about
+the compiled regular expression. (It is also used for input when REG_PEND is
+set.)
 .P
 The argument \fIcflags\fP is either zero, or contains one or more of the bits
 defined by the following macros:
@@ -93,6 +94,14 @@
 compilation to the native function. Note that this does \fInot\fP mimic the
 defined POSIX behaviour for REG_NEWLINE (see the following section).
 .sp
+  REG_NOSPEC
+.sp
+The PCRE2_LITERAL option is set when the regular expression is passed for
+compilation to the native function. This disables all meta characters in the
+pattern, causing it to be treated as a literal string. The only other options
+that are allowed with REG_NOSPEC are REG_ICASE, REG_NOSUB, REG_PEND, and
+REG_UTF. Note that REG_NOSPEC is not part of the POSIX standard.
+.sp
   REG_NOSUB
 .sp
 When a pattern that is compiled with this flag is passed to \fBregexec()\fP for
@@ -101,6 +110,16 @@
 to set the PCRE2_NO_AUTO_CAPTURE compile option, but this no longer happens
 because it disables the use of back references.
 .sp
+  REG_PEND
+.sp
+If this option is set, the \fBreg_endp\fP field in the \fIpreg\fP structure
+(which has the type const char *) must be set to point to the character beyond
+the end of the pattern before calling \fBregcomp()\fP. The pattern itself may
+now contain binary zeroes, which are treated as data characters. Without
+REG_PEND, a binary zero terminates the pattern and the \fBre_endp\fP field is
+ignored. This is a GNU extension to the POSIX standard and should be used with
+caution in software intended to be portable to other systems.
+.sp
   REG_UCP
 .sp
 The PCRE2_UCP option is set when the regular expression is passed for
@@ -130,9 +149,10 @@
 class such as [^a] (they are).
 .P
 The yield of \fBregcomp()\fP is zero on success, and non-zero otherwise. The
-\fIpreg\fP structure is filled in on success, and one member of the structure
-is public: \fIre_nsub\fP contains the number of capturing subpatterns in
-the regular expression. Various error codes are defined in the header file.
+\fIpreg\fP structure is filled in on success, and one other member of the
+structure (as well as \fIre_endp\fP) is public: \fIre_nsub\fP contains the
+number of capturing subpatterns in the regular expression. Various error codes
+are defined in the header file.
 .P
 NOTE: If the yield of \fBregcomp()\fP is non-zero, you must not attempt to
 use the contents of the \fIpreg\fP structure. If, for example, you pass it to
@@ -204,15 +224,24 @@
 .sp
   REG_STARTEND
 .sp
-The string is considered to start at \fIstring\fP + \fIpmatch[0].rm_so\fP and
-to have a terminating NUL located at \fIstring\fP + \fIpmatch[0].rm_eo\fP
-(there need not actually be a NUL at that location), regardless of the value of
-\fInmatch\fP. This is a BSD extension, compatible with but not specified by
-IEEE Standard 1003.2 (POSIX.2), and should be used with caution in software
-intended to be portable to other systems. Note that a non-zero \fIrm_so\fP does
-not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not
-how it is matched. Setting REG_STARTEND and passing \fIpmatch\fP as NULL are
-mutually exclusive; the error REG_INVARG is returned.
+When this option is set, the subject string is starts at \fIstring\fP +
+\fIpmatch[0].rm_so\fP and ends at \fIstring\fP + \fIpmatch[0].rm_eo\fP, which
+should point to the first character beyond the string. There may be binary
+zeroes within the subject string, and indeed, using REG_STARTEND is the only
+way to pass a subject string that contains a binary zero.
+.P
+Whatever the value of \fIpmatch[0].rm_so\fP, the offsets of the matched string
+and any captured substrings are still given relative to the start of
+\fIstring\fP itself. (Before PCRE2 release 10.30 these were given relative to
+\fIstring\fP + \fIpmatch[0].rm_so\fP, but this differs from other
+implementations.)
+.P
+This is a BSD extension, compatible with but not specified by IEEE Standard
+1003.2 (POSIX.2), and should be used with caution in software intended to be
+portable to other systems. Note that a non-zero \fIrm_so\fP does not imply
+REG_NOTBOL; REG_STARTEND affects only the location and length of the string,
+not how it is matched. Setting REG_STARTEND and passing \fIpmatch\fP as NULL
+are mutually exclusive; the error REG_INVARG is returned.
 .P
 If the pattern was compiled with the REG_NOSUB flag, no data about any matched
 strings is returned. The \fInmatch\fP and \fIpmatch\fP arguments of
@@ -271,6 +300,6 @@
 .rs
 .sp
 .nf
-Last updated: 31 January 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 15 June 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2serialize.3 b/dist2/doc/pcre2serialize.3
index 664c1db..5a87cec 100644
--- a/dist2/doc/pcre2serialize.3
+++ b/dist2/doc/pcre2serialize.3
@@ -1,4 +1,4 @@
-.TH PCRE2SERIALIZE 3 "24 May 2016" "PCRE2 10.22"
+.TH PCRE2SERIALIZE 3 "21 March 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "SAVING AND RE-USING PRECOMPILED PCRE2 PATTERNS"
@@ -37,7 +37,10 @@
 within individual applications. As such, the data supplied to
 \fBpcre2_serialize_decode()\fP is expected to be trusted data, not data from
 arbitrary external sources. There is only some simple consistency checking, not
-complete validation of what is being re-loaded.
+complete validation of what is being re-loaded. Corrupted data may cause
+undefined results. For example, if the length field of a pattern in the
+serialized data is corrupted, the deserializing code may read beyond the end of
+the byte stream that is passed to it.
 .
 .
 .SH "SAVING COMPILED PATTERNS"
@@ -181,6 +184,6 @@
 .rs
 .sp
 .nf
-Last updated: 24 May 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 21 March 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2stack.3 b/dist2/doc/pcre2stack.3
deleted file mode 100644
index 8711263..0000000
--- a/dist2/doc/pcre2stack.3
+++ /dev/null
@@ -1,202 +0,0 @@
-.TH PCRE2STACK 3 "21 November 2014" "PCRE2 10.00"
-.SH NAME
-PCRE2 - Perl-compatible regular expressions (revised API)
-.SH "PCRE2 DISCUSSION OF STACK USAGE"
-.rs
-.sp
-When you call \fBpcre2_match()\fP, it makes use of an internal function called
-\fBmatch()\fP. This calls itself recursively at branch points in the pattern,
-in order to remember the state of the match so that it can back up and try a
-different alternative after a failure. As matching proceeds deeper and deeper
-into the tree of possibilities, the recursion depth increases. The
-\fBmatch()\fP function is also called in other circumstances, for example,
-whenever a parenthesized sub-pattern is entered, and in certain cases of
-repetition.
-.P
-Not all calls of \fBmatch()\fP increase the recursion depth; for an item such
-as a* it may be called several times at the same level, after matching
-different numbers of a's. Furthermore, in a number of cases where the result of
-the recursive call would immediately be passed back as the result of the
-current call (a "tail recursion"), the function is just restarted instead.
-.P
-Each time the internal \fBmatch()\fP function is called recursively, it uses
-memory from the process stack. For certain kinds of pattern and data, very
-large amounts of stack may be needed, despite the recognition of "tail
-recursion". Note that if PCRE2 is compiled with the -fsanitize=address option
-of the GCC compiler, the stack requirements are greatly increased.
-.P
-The above comments apply when \fBpcre2_match()\fP is run in its normal
-interpretive manner. If the compiled pattern was processed by
-\fBpcre2_jit_compile()\fP, and just-in-time compiling was successful, and the
-options passed to \fBpcre2_match()\fP were not incompatible, the matching
-process uses the JIT-compiled code instead of the \fBmatch()\fP function. In
-this case, the memory requirements are handled entirely differently. See the
-.\" HREF
-\fBpcre2jit\fP
-.\"
-documentation for details.
-.P
-The \fBpcre2_dfa_match()\fP function operates in a different way to
-\fBpcre2_match()\fP, and uses recursion only when there is a regular expression
-recursion or subroutine call in the pattern. This includes the processing of
-assertion and "once-only" subpatterns, which are handled like subroutine calls.
-Normally, these are never very deep, and the limit on the complexity of
-\fBpcre2_dfa_match()\fP is controlled by the amount of workspace it is given.
-However, it is possible to write patterns with runaway infinite recursions;
-such patterns will cause \fBpcre2_dfa_match()\fP to run out of stack. At
-present, there is no protection against this.
-.P
-The comments that follow do NOT apply to \fBpcre2_dfa_match()\fP; they are
-relevant only for \fBpcre2_match()\fP without the JIT optimization.
-.
-.
-.SS "Reducing \fBpcre2_match()\fP's stack usage"
-.rs
-.sp
-You can often reduce the amount of recursion, and therefore the
-amount of stack used, by modifying the pattern that is being matched. Consider,
-for example, this pattern:
-.sp
-  ([^<]|<(?!inet))+
-.sp
-It matches from wherever it starts until it encounters "<inet" or the end of
-the data, and is the kind of pattern that might be used when processing an XML
-file. Each iteration of the outer parentheses matches either one character that
-is not "<" or a "<" that is not followed by "inet". However, each time a
-parenthesis is processed, a recursion occurs, so this formulation uses a stack
-frame for each matched character. For a long string, a lot of stack is
-required. Consider now this rewritten pattern, which matches exactly the same
-strings:
-.sp
-  ([^<]++|<(?!inet))+
-.sp
-This uses very much less stack, because runs of characters that do not contain
-"<" are "swallowed" in one item inside the parentheses. Recursion happens only
-when a "<" character that is not followed by "inet" is encountered (and we
-assume this is relatively rare). A possessive quantifier is used to stop any
-backtracking into the runs of non-"<" characters, but that is not related to
-stack usage.
-.P
-This example shows that one way of avoiding stack problems when matching long
-subject strings is to write repeated parenthesized subpatterns to match more
-than one character whenever possible.
-.
-.
-.SS "Compiling PCRE2 to use heap instead of stack for \fBpcre2_match()\fP"
-.rs
-.sp
-In environments where stack memory is constrained, you might want to compile
-PCRE2 to use heap memory instead of stack for remembering back-up points when
-\fBpcre2_match()\fP is running. This makes it run more slowly, however. Details
-of how to do this are given in the
-.\" HREF
-\fBpcre2build\fP
-.\"
-documentation. When built in this way, instead of using the stack, PCRE2
-gets memory for remembering backup points from the heap. By default, the memory
-is obtained by calling the system \fBmalloc()\fP function, but you can arrange
-to supply your own memory management function. For details, see the section
-entitled
-.\" HTML <a href="pcre2api.html#matchcontext">
-.\" </a>
-"The match context"
-.\"
-in the
-.\" HREF
-\fBpcre2api\fP
-.\"
-documentation. Since the block sizes are always the same, it may be possible to
-implement customized a memory handler that is more efficient than the standard
-function. The memory blocks obtained for this purpose are retained and re-used
-if possible while \fBpcre2_match()\fP is running. They are all freed just
-before it exits.
-.
-.
-.SS "Limiting \fBpcre2_match()\fP's stack usage"
-.rs
-.sp
-You can set limits on the number of times the internal \fBmatch()\fP function
-is called, both in total and recursively. If a limit is exceeded,
-\fBpcre2_match()\fP returns an error code. Setting suitable limits should
-prevent it from running out of stack. The default values of the limits are very
-large, and unlikely ever to operate. They can be changed when PCRE2 is built,
-and they can also be set when \fBpcre2_match()\fP is called. For details of
-these interfaces, see the
-.\" HREF
-\fBpcre2build\fP
-.\"
-documentation and the section entitled
-.\" HTML <a href="pcre2api.html#matchcontext">
-.\" </a>
-"The match context"
-.\"
-in the
-.\" HREF
-\fBpcre2api\fP
-.\"
-documentation.
-.P
-As a very rough rule of thumb, you should reckon on about 500 bytes per
-recursion. Thus, if you want to limit your stack usage to 8Mb, you should set
-the limit at 16000 recursions. A 64Mb stack, on the other hand, can support
-around 128000 recursions.
-.P
-The \fBpcre2test\fP test program has a modifier called "find_limits" which, if
-applied to a subject line, causes it to find the smallest limits that allow a a
-pattern to match. This is done by calling \fBpcre2_match()\fP repeatedly with
-different limits.
-.
-.
-.SS "Changing stack size in Unix-like systems"
-.rs
-.sp
-In Unix-like environments, there is not often a problem with the stack unless
-very long strings are involved, though the default limit on stack size varies
-from system to system. Values from 8Mb to 64Mb are common. You can find your
-default limit by running the command:
-.sp
-  ulimit -s
-.sp
-Unfortunately, the effect of running out of stack is often SIGSEGV, though
-sometimes a more explicit error message is given. You can normally increase the
-limit on stack size by code such as this:
-.sp
-  struct rlimit rlim;
-  getrlimit(RLIMIT_STACK, &rlim);
-  rlim.rlim_cur = 100*1024*1024;
-  setrlimit(RLIMIT_STACK, &rlim);
-.sp
-This reads the current limits (soft and hard) using \fBgetrlimit()\fP, then
-attempts to increase the soft limit to 100Mb using \fBsetrlimit()\fP. You must
-do this before calling \fBpcre2_match()\fP.
-.
-.
-.SS "Changing stack size in Mac OS X"
-.rs
-.sp
-Using \fBsetrlimit()\fP, as described above, should also work on Mac OS X. It
-is also possible to set a stack size when linking a program. There is a
-discussion about stack sizes in Mac OS X at this web site:
-.\" HTML <a href="http://developer.apple.com/qa/qa2005/qa1419.html">
-.\" </a>
-http://developer.apple.com/qa/qa2005/qa1419.html.
-.\"
-.
-.
-.SH AUTHOR
-.rs
-.sp
-.nf
-Philip Hazel
-University Computing Service
-Cambridge, England.
-.fi
-.
-.
-.SH REVISION
-.rs
-.sp
-.nf
-Last updated: 21 November 2014
-Copyright (c) 1997-2014 University of Cambridge.
-.fi
diff --git a/dist2/doc/pcre2syntax.3 b/dist2/doc/pcre2syntax.3
index 8be8b92..6eb0235 100644
--- a/dist2/doc/pcre2syntax.3
+++ b/dist2/doc/pcre2syntax.3
@@ -1,4 +1,4 @@
-.TH PCRE2SYNTAX 3 "16 October 2015" "PCRE2 10.21"
+.TH PCRE2SYNTAX 3 "17 June 2017" "PCRE2 10.30"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 REGULAR EXPRESSION SYNTAX SUMMARY"
@@ -407,18 +407,21 @@
   (?i)            caseless
   (?J)            allow duplicate names
   (?m)            multiline
+  (?n)            no auto capture
   (?s)            single line (dotall)
   (?U)            default ungreedy (lazy)
-  (?x)            extended (ignore white space)
+  (?x)            extended: ignore white space except in classes
+  (?xx)           as (?x) but also ignore space and tab in classes
   (?-...)         unset option(s)
 .sp
 The following are recognized only at the very start of a pattern or after one
 of the newline or \eR options with similar syntax. More than one of them may
-appear.
+appear. For the first three, d is a decimal number.
 .sp
-  (*LIMIT_MATCH=d) set the match limit to d (decimal number)
-  (*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
-  (*NOTEMPTY)     set PCRE2_NOTEMPTY when matching
+  (*LIMIT_DEPTH=d) set the backtracking limit to d
+  (*LIMIT_HEAP=d)  set the heap size limit to d kilobytes
+  (*LIMIT_MATCH=d) set the match limit to d
+  (*NOTEMPTY)      set PCRE2_NOTEMPTY when matching
   (*NOTEMPTY_ATSTART) set PCRE2_NOTEMPTY_ATSTART when matching
   (*NO_AUTO_POSSESS) no auto-possessification (PCRE2_NO_AUTO_POSSESS)
   (*NO_DOTSTAR_ANCHOR) no .* anchoring (PCRE2_NO_DOTSTAR_ANCHOR)
@@ -427,10 +430,11 @@
   (*UTF)          set appropriate UTF mode for the library in use
   (*UCP)          set PCRE2_UCP (use Unicode properties for \ed etc)
 .sp
-Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of the
-limits set by the caller of pcre2_match(), not increase them. The application
-can lock out the use of (*UTF) and (*UCP) by setting the PCRE2_NEVER_UTF or
-PCRE2_NEVER_UCP options, respectively, at compile time.
+Note that LIMIT_DEPTH, LIMIT_HEAP, and LIMIT_MATCH can only reduce the value of
+the limits set by the caller of \fBpcre2_match()\fP or \fBpcre2_dfa_match()\fP,
+not increase them. LIMIT_RECURSION is an obsolete synonym for LIMIT_DEPTH. The
+application can lock out the use of (*UTF) and (*UCP) by setting the
+PCRE2_NEVER_UTF or PCRE2_NEVER_UCP options, respectively, at compile time.
 .
 .
 .SH "NEWLINE CONVENTION"
@@ -444,6 +448,7 @@
   (*CRLF)         carriage return followed by linefeed
   (*ANYCRLF)      all three of the above
   (*ANY)          any Unicode newline sequence
+  (*NUL)          the NUL character (binary zero)
 .
 .
 .SH "WHAT \eR MATCHES"
@@ -473,6 +478,9 @@
   \en              reference by number (can be ambiguous)
   \egn             reference by number
   \eg{n}           reference by number
+  \eg+n            relative reference by number (PCRE2 extension)
+  \eg-n            relative reference by number
+  \eg{+n}          relative reference by number (PCRE2 extension)
   \eg{-n}          relative reference by number
   \ek<name>        reference by name (Perl)
   \ek'name'        reference by name (Perl)
@@ -511,13 +519,17 @@
   (?(-n)              relative reference condition
   (?(<name>)          named reference condition (Perl)
   (?('name')          named reference condition (Perl)
-  (?(name)            named reference condition (PCRE2)
+  (?(name)            named reference condition (PCRE2, deprecated)
   (?(R)               overall recursion condition
-  (?(Rn)              specific group recursion condition
-  (?(R&name)          specific recursion condition
+  (?(Rn)              specific numbered group recursion condition
+  (?(R&name)          specific named group recursion condition
   (?(DEFINE)          define subpattern for reference
   (?(VERSION[>]=n.m)  test PCRE2 version
   (?(assert)          assertion condition
+.sp
+Note the ambiguity of (?(R) and (?(Rn) which might be named reference
+conditions or recursion tests. Such a condition is interpreted as a reference
+condition if the relevant named group exists.
 .
 .
 .SH "BACKTRACKING CONTROL"
@@ -577,6 +589,6 @@
 .rs
 .sp
 .nf
-Last updated: 16 October 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 17 June 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2test.1 b/dist2/doc/pcre2test.1
index 2fbf794..ee78792 100644
--- a/dist2/doc/pcre2test.1
+++ b/dist2/doc/pcre2test.1
@@ -1,4 +1,4 @@
-.TH PCRE2TEST 1 "06 July 2016" "PCRE 10.22"
+.TH PCRE2TEST 1 "21 Decbmber 2017" "PCRE 10.31"
 .SH NAME
 pcre2test - a program for testing Perl-compatible regular expressions.
 .SH SYNOPSIS
@@ -29,7 +29,7 @@
 .P
 As the original fairly simple PCRE library evolved, it acquired many different
 features, and as a result, the original \fBpcretest\fP program ended up with a
-lot of options in a messy, arcane syntax, for testing all the features. The
+lot of options in a messy, arcane syntax for testing all the features. The
 move to the new PCRE2 API provided an opportunity to re-implement the test
 program as \fBpcre2test\fP, with a cleaner modifier syntax. Nevertheless, there
 are still many obscure modifiers, some of which are specifically designed for
@@ -47,32 +47,64 @@
 all three of these libraries may be simultaneously installed. The
 \fBpcre2test\fP program can be used to test all the libraries. However, its own
 input and output are always in 8-bit format. When testing the 16-bit or 32-bit
-libraries, patterns and subject strings are converted to 16- or 32-bit format
-before being passed to the library functions. Results are converted back to
-8-bit code units for output.
+libraries, patterns and subject strings are converted to 16-bit or 32-bit
+format before being passed to the library functions. Results are converted back
+to 8-bit code units for output.
 .P
 In the rest of this document, the names of library functions and structures
 are given in generic form, for example, \fBpcre_compile()\fP. The actual
 names used in the libraries have a suffix _8, _16, or _32, as appropriate.
 .
 .
+.\" HTML <a name="inputencoding"></a>
 .SH "INPUT ENCODING"
 .rs
 .sp
 Input to \fBpcre2test\fP is processed line by line, either by calling the C
-library's \fBfgets()\fP function, or via the \fBlibreadline\fP library (see
-below). The input is processed using using C's string functions, so must not
-contain binary zeroes, even though in Unix-like environments, \fBfgets()\fP
-treats any bytes other than newline as data characters. In some Windows
-environments character 26 (hex 1A) causes an immediate end of file, and no
-further data is read.
+library's \fBfgets()\fP function, or via the \fBlibreadline\fP library. In some
+Windows environments character 26 (hex 1A) causes an immediate end of file, and
+no further data is read, so this character should be avoided unless you really
+want that action.
 .P
-For maximum portability, therefore, it is safest to avoid non-printing
-characters in \fBpcre2test\fP input files. There is a facility for specifying
-some or all of a pattern's characters as hexadecimal pairs, thus making it
-possible to include binary zeroes in a pattern for testing purposes. Subject
-lines are processed for backslash escapes, which makes it possible to include
-any data value.
+The input is processed using using C's string functions, so must not
+contain binary zeros, even though in Unix-like environments, \fBfgets()\fP
+treats any bytes other than newline as data characters. An error is generated
+if a binary zero is encountered. By default subject lines are processed for
+backslash escapes, which makes it possible to include any data value in strings
+that are passed to the library for matching. For patterns, there is a facility
+for specifying some or all of the 8-bit input characters as hexadecimal pairs,
+which makes it possible to include binary zeros.
+.
+.
+.SS "Input for the 16-bit and 32-bit libraries"
+.rs
+.sp
+When testing the 16-bit or 32-bit libraries, there is a need to be able to
+generate character code points greater than 255 in the strings that are passed
+to the library. For subject lines, backslash escapes can be used. In addition,
+when the \fButf\fP modifier (see
+.\" HTML <a href="#optionmodifiers">
+.\" </a>
+"Setting compilation options"
+.\"
+below) is set, the pattern and any following subject lines are interpreted as
+UTF-8 strings and translated to UTF-16 or UTF-32 as appropriate.
+.P
+For non-UTF testing of wide characters, the \fButf8_input\fP modifier can be
+used. This is mutually exclusive with \fButf\fP, and is allowed only in 16-bit
+or 32-bit mode. It causes the pattern and following subject lines to be treated
+as UTF-8 according to the original definition (RFC 2279), which allows for
+character values up to 0x7fffffff. Each character is placed in one 16-bit or
+32-bit code unit (in the 16-bit case, values greater than 0xffff cause an error
+to occur).
+.P
+UTF-8 (in its original definition) is not capable of encoding values greater
+than 0x7fffffff, but such values can be handled by the 32-bit library. When
+testing this library in non-UTF mode with \fButf8_input\fP set, if any
+character is preceded by the byte 0xff (which is an illegal byte in UTF-8)
+0x80000000 is added to the character's value. This is the only way of passing
+such code points in a pattern string. For subject strings, using an escape
+sequence is preferable.
 .
 .
 .SH "COMMAND LINE OPTIONS"
@@ -93,14 +125,24 @@
 the 32-bit library has been built, this is the default. If the 32-bit library
 has not been built, this option causes an error.
 .TP 10
+\fB-ac\fP
+Behave as if each pattern has the \fBauto_callout\fP modifier, that is, insert
+automatic callouts into every pattern that is compiled.
+.TP 10
+\fB-AC\fP
+As for \fB-ac\fP, but in addition behave as if each subject line has the
+\fBcallout_extra\fP modifier, that is, show additional information from
+callouts.
+.TP 10
 \fB-b\fP
-Behave as if each pattern has the \fB/fullbincode\fP modifier; the full
+Behave as if each pattern has the \fBfullbincode\fP modifier; the full
 internal binary form of the pattern is output after compilation.
 .TP 10
 \fB-C\fP
 Output the version number of the PCRE2 library, and all available information
 about the optional features that are included, and then exit with zero exit
-code. All other options are ignored.
+code. All other options are ignored. If both -C and -LM are present, whichever
+is first is recognized.
 .TP 10
 \fB-C\fP \fIoption\fP
 Output information about a specific build-time option, then exit. This
@@ -114,7 +156,7 @@
   linksize   the configured internal link size (2, 3, or 4)
                exit code is set to the link size
   newline    the default newline setting:
-               CR, LF, CRLF, ANYCRLF, or ANY
+               CR, LF, CRLF, ANYCRLF, ANY, or NUL
                exit code is always 0
   bsr        the default setting for what \eR matches:
                ANYCRLF or ANY
@@ -153,13 +195,23 @@
 Output a brief summary these options and then exit.
 .TP 10
 \fB-i\fP
-Behave as if each pattern has the \fB/info\fP modifier; information about the
+Behave as if each pattern has the \fBinfo\fP modifier; information about the
 compiled pattern is given after compilation.
 .TP 10
 \fB-jit\fP
 Behave as if each pattern line has the \fBjit\fP modifier; after successful
 compilation, each pattern is passed to the just-in-time compiler, if available.
 .TP 10
+\fB-jitverify\fP
+Behave as if each pattern line has the \fBjitverify\fP modifier; after
+successful compilation, each pattern is passed to the just-in-time compiler, if
+available, and the use of JIT is verified.
+.TP 10
+\fB-LM\fP
+List modifiers: write a list of available pattern and subject modifiers to the
+standard output, then exit with zero exit code. All other options are ignored.
+If both -C and -LM are present, whichever is first is recognized.
+.TP 10
 \fB-pattern\fB \fImodifier-list\fP
 Behave as if each pattern line contains the given modifiers.
 .TP 10
@@ -279,8 +331,8 @@
 when PCRE2 is compiled with either CR or CRLF as the default newline.
 .P
 The #newline_default command specifies a list of newline types that are
-acceptable as the default. The types must be one of CR, LF, CRLF, ANYCRLF, or
-ANY (in upper or lower case), for example:
+acceptable as the default. The types must be one of CR, LF, CRLF, ANYCRLF,
+ANY, or NUL (in upper or lower case), for example:
 .sp
   #newline_default LF Any anyCRLF
 .sp
@@ -293,8 +345,9 @@
 .P
 When the POSIX API is being tested there is no way to override the default
 newline convention, though it is possible to set the newline convention from
-within the pattern. A warning is given if the \fBposix\fP modifier is used when
-\fB#newline_default\fP would set a default for the non-POSIX API.
+within the pattern. A warning is given if the \fBposix\fP or \fBposix_nosub\fP
+modifier is used when \fB#newline_default\fP would set a default for the
+non-POSIX API.
 .sp
   #pattern <modifier-list>
 .sp
@@ -400,8 +453,9 @@
 .sp
 Before each subject line is passed to \fBpcre2_match()\fP or
 \fBpcre2_dfa_match()\fP, leading and trailing white space is removed, and the
-line is scanned for backslash escapes. The following provide a means of
-encoding non-printing characters in a visible way:
+line is scanned for backslash escapes, unless the \fBsubject_literal\fP
+modifier was set for the pattern. The following provide a means of encoding
+non-printing characters in a visible way:
 .sp
   \ea         alarm (BEL, \ex07)
   \eb         backspace (\ex08)
@@ -463,6 +517,11 @@
 the very last character in the line is a backslash (and there is no modifier
 list), it is ignored. This gives a way of passing an empty line as data, since
 a real empty line terminates the data input.
+.P
+If the \fBsubject_literal\fP modifier is set for a pattern, all subject lines
+that follow are treated as literals, with no special treatment of backslashes.
+No replication is possible, and any subject modifiers must be set as defaults
+by a \fB#subject\fP command.
 .
 .
 .SH "PATTERN MODIFIERS"
@@ -478,31 +537,44 @@
 .SS "Setting compilation options"
 .rs
 .sp
-The following modifiers set options for \fBpcre2_compile()\fP. The most common
-ones have single-letter abbreviations. See
+The following modifiers set options for \fBpcre2_compile()\fP. Most of them set
+bits in the options argument of that function, but those whose names start with
+PCRE2_EXTRA are additional options that are set in the compile context. For the
+main options, there are some single-letter abbreviations that are the same as
+Perl options. There is special handling for /x: if a second x is present,
+PCRE2_EXTENDED is converted into PCRE2_EXTENDED_MORE as in Perl. A third
+appearance adds PCRE2_EXTENDED as well, though this makes no difference to the
+way \fBpcre2_compile()\fP behaves. See
 .\" HREF
 \fBpcre2api\fP
 .\"
-for a description of their effects.
+for a description of the effects of these options.
 .sp
       allow_empty_class         set PCRE2_ALLOW_EMPTY_CLASS
+      allow_surrogate_escapes   set PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES
       alt_bsux                  set PCRE2_ALT_BSUX
       alt_circumflex            set PCRE2_ALT_CIRCUMFLEX
       alt_verbnames             set PCRE2_ALT_VERBNAMES
       anchored                  set PCRE2_ANCHORED
       auto_callout              set PCRE2_AUTO_CALLOUT
+      bad_escape_is_literal     set PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
   /i  caseless                  set PCRE2_CASELESS
       dollar_endonly            set PCRE2_DOLLAR_ENDONLY
   /s  dotall                    set PCRE2_DOTALL
       dupnames                  set PCRE2_DUPNAMES
+      endanchored               set PCRE2_ENDANCHORED
   /x  extended                  set PCRE2_EXTENDED
+  /xx extended_more             set PCRE2_EXTENDED_MORE
       firstline                 set PCRE2_FIRSTLINE
+      literal                   set PCRE2_LITERAL
+      match_line                set PCRE2_EXTRA_MATCH_LINE
       match_unset_backref       set PCRE2_MATCH_UNSET_BACKREF
+      match_word                set PCRE2_EXTRA_MATCH_WORD
   /m  multiline                 set PCRE2_MULTILINE
       never_backslash_c         set PCRE2_NEVER_BACKSLASH_C
       never_ucp                 set PCRE2_NEVER_UCP
       never_utf                 set PCRE2_NEVER_UTF
-      no_auto_capture           set PCRE2_NO_AUTO_CAPTURE
+  /n  no_auto_capture           set PCRE2_NO_AUTO_CAPTURE
       no_auto_possess           set PCRE2_NO_AUTO_POSSESS
       no_dotstar_anchor         set PCRE2_NO_DOTSTAR_ANCHOR
       no_start_optimize         set PCRE2_NO_START_OPTIMIZE
@@ -515,7 +587,9 @@
 As well as turning on the PCRE2_UTF option, the \fButf\fP modifier causes all
 non-printing characters in output strings to be printed using the \ex{hh...}
 notation. Otherwise, those less than 0x100 are output in hex without the curly
-brackets.
+brackets. Setting \fButf\fP in 16-bit or 32-bit mode also causes pattern and
+subject strings to be translated to UTF-16 or UTF-32, respectively, before
+being passed to library functions.
 .
 .
 .\" HTML <a name="controlmodifiers"></a>
@@ -523,12 +597,18 @@
 .rs
 .sp
 The following modifiers affect the compilation process or request information
-about the pattern:
+about the pattern. There are single-letter abbreviations for some that are
+heavily used in the test files.
 .sp
       bsr=[anycrlf|unicode]     specify \eR handling
   /B  bincode                   show binary code without lengths
       callout_info              show callout information
+      convert=<options>         request foreign pattern conversion
+      convert_glob_escape=c     set glob escape character
+      convert_glob_separator=c  set glob separator character
+      convert_length            set convert buffer length
       debug                     same as info,fullbincode
+      framesize                 show matching frame size
       fullbincode               show binary code with lengths
   /I  info                      show info about compiled pattern
       hex                       unquoted characters are hexadecimal
@@ -546,7 +626,10 @@
       push                      push compiled pattern onto the stack
       pushcopy                  push a copy onto the stack
       stackguard=<number>       test the stackguard feature
+      subject_literal           treat all subject lines as literal
       tables=[0|1|2]            select internal tables
+      use_length                do not zero-terminate the pattern
+      utf8_input                treat input as UTF-8
 .sp
 The effects of these modifiers are described in the following sections.
 .
@@ -561,7 +644,7 @@
 .P
 The \fBnewline\fP modifier specifies which characters are to be interpreted as
 newlines, both in the pattern and in subject lines. The type must be one of CR,
-LF, CRLF, ANYCRLF, or ANY (in upper or lower case).
+LF, CRLF, ANYCRLF, ANY, or NUL (in upper or lower case).
 .
 .
 .SS "Information about a pattern"
@@ -609,6 +692,10 @@
 not necessarily the last character. These lines are omitted if no starting or
 ending code units are recorded.
 .P
+The \fBframesize\fP modifier shows the size, in bytes, of the storage frames
+used by \fBpcre2_match()\fP for handling backtracking. The size depends on the
+number of capturing parentheses in the pattern.
+.P
 The \fBcallout_info\fP modifier requests information about all the callouts in
 the pattern. A list of them is output at the end of any other information that
 is requested. For each callout, either its number or string is given, followed
@@ -642,12 +729,41 @@
   /ab "literal" 32/hex
 .sp
 Either single or double quotes may be used. There is no way of including
-the delimiter within a substring.
+the delimiter within a substring. The \fBhex\fP and \fBexpand\fP modifiers are
+mutually exclusive.
+.
+.
+.SS "Specifying the pattern's length"
+.rs
+.sp
+By default, patterns are passed to the compiling functions as zero-terminated
+strings but can be passed by length instead of being zero-terminated. The
+\fBuse_length\fP modifier causes this to happen. Using a length happens
+automatically (whether or not \fBuse_length\fP is set) when \fBhex\fP is set,
+because patterns specified in hexadecimal may contain binary zeros.
 .P
-By default, \fBpcre2test\fP passes patterns as zero-terminated strings to
-\fBpcre2_compile()\fP, giving the length as PCRE2_ZERO_TERMINATED. However, for
-patterns specified with the \fBhex\fP modifier, the actual length of the
-pattern is passed.
+If \fBhex\fP or \fBuse_length\fP is used with the POSIX wrapper API (see
+.\" HTML <a href="#posixwrapper">
+.\" </a>
+"Using the POSIX wrapper API"
+.\"
+below), the REG_PEND extension is used to pass the pattern's length.
+.
+.
+.SS "Specifying wide characters in 16-bit and 32-bit modes"
+.rs
+.sp
+In 16-bit and 32-bit modes, all input is automatically treated as UTF-8 and
+translated to UTF-16 or UTF-32 when the \fButf\fP modifier is set. For testing
+the 16-bit and 32-bit libraries in non-UTF mode, the \fButf8_input\fP modifier
+can be used. It is mutually exclusive with \fButf\fP. Input lines are
+interpreted as UTF-8 as a means of specifying wide characters. More details are
+given in
+.\" HTML <a href="#inputencoding">
+.\" </a>
+"Input encoding"
+.\"
+above.
 .
 .
 .SS "Generating long repetitive patterns"
@@ -665,7 +781,8 @@
 example, \e[AB]{6000} is expanded to "ABAB..." 6000 times. This construction
 cannot be nested. An initial "\e[" sequence is recognized only if "]{" followed
 by decimal digits and "}" is found later in the pattern. If not, the characters
-remain in the pattern unaltered.
+remain in the pattern unaltered. The \fBexpand\fP and \fBhex\fP modifiers are
+mutually exclusive.
 .P
 If part of an expanded pattern looks like an expansion, but is really part of
 the actual pattern, unwanted expansion can be avoided by giving two values in
@@ -696,7 +813,7 @@
 .\"
 for details of how these options are specified for each match attempt.
 .P
-JIT compilation is requested by the \fB/jit\fP pattern modifier, which may
+JIT compilation is requested by the \fBjit\fP pattern modifier, which may
 optionally be followed by an equals sign and a number in the range 0 to 7.
 The three bits that make up the number specify which of the three JIT operating
 modes are to be compiled:
@@ -705,7 +822,7 @@
   2  compile JIT code for soft partial matching
   4  compile JIT code for hard partial matching
 .sp
-The possible values for the \fB/jit\fP modifier are therefore:
+The possible values for the \fBjit\fP modifier are therefore:
 .sp
   0  disable JIT
   1  normal matching only
@@ -720,7 +837,7 @@
 PCRE2_PARTIAL_HARD option set. Note that such a call may return a complete
 match; the options enable the possibility of a partial match, but do not
 require it. Note also that if you request JIT compilation only for partial
-matching (for example, /jit=2) but do not set the \fBpartial\fP modifier on a
+matching (for example, jit=2) but do not set the \fBpartial\fP modifier on a
 subject line, that match will not use JIT code because none was compiled for
 non-partial matching.
 .P
@@ -750,14 +867,14 @@
 .SS "Setting a locale"
 .rs
 .sp
-The \fB/locale\fP modifier must specify the name of a locale, for example:
+The \fBlocale\fP modifier must specify the name of a locale, for example:
 .sp
   /pattern/locale=fr_FR
 .sp
 The given locale is set, \fBpcre2_maketables()\fP is called to build a set of
 character tables for the locale, and this is then passed to
 \fBpcre2_compile()\fP when compiling the regular expression. The same tables
-are used when matching the following subject lines. The \fB/locale\fP modifier
+are used when matching the following subject lines. The \fBlocale\fP modifier
 applies only to the pattern on which it appears, but can be given in a
 \fB#pattern\fP command if a default is needed. Setting a locale and alternate
 character tables are mutually exclusive.
@@ -766,7 +883,7 @@
 .SS "Showing pattern memory"
 .rs
 .sp
-The \fB/memory\fP modifier causes the size in bytes of the memory used to hold
+The \fBmemory\fP modifier causes the size in bytes of the memory used to hold
 the compiled pattern to be output. This does not include the size of the
 \fBpcre2_code\fP block; it is just the actual compiled data. If the pattern is
 subsequently passed to the JIT compiler, the size of the JIT compiled code is
@@ -797,10 +914,11 @@
 variable can hold (essentially unlimited).
 .
 .
+.\" HTML <a name="posixwrapper"></a>
 .SS "Using the POSIX wrapper API"
 .rs
 .sp
-The \fB/posix\fP and \fBposix_nosub\fP modifiers cause \fBpcre2test\fP to call
+The \fBposix\fP and \fBposix_nosub\fP modifiers cause \fBpcre2test\fP to call
 PCRE2 via the POSIX wrapper API rather than its native API. When
 \fBposix_nosub\fP is used, the POSIX option REG_NOSUB is passed to
 \fBregcomp()\fP. The POSIX wrapper supports only the 8-bit library. Note that
@@ -830,12 +948,16 @@
 The \fBaftertext\fP and \fBallaftertext\fP subject modifiers work as described
 below. All other modifiers are either ignored, with a warning message, or cause
 an error.
+.P
+The pattern is passed to \fBregcomp()\fP as a zero-terminated string by
+default, but if the \fBuse_length\fP or \fBhex\fP modifiers are set, the
+REG_PEND extension is used to pass it by length.
 .
 .
 .SS "Testing the stack guard feature"
 .rs
 .sp
-The \fB/stackguard\fP modifier is used to test the use of
+The \fBstackguard\fP modifier is used to test the use of
 \fBpcre2_set_compile_recursion_guard()\fP, a function that is provided to
 enable stack availability to be checked during compilation (see the
 .\" HREF
@@ -852,7 +974,7 @@
 .SS "Using alternative character tables"
 .rs
 .sp
-The value specified for the \fB/tables\fP modifier must be one of the digits 0,
+The value specified for the \fBtables\fP modifier must be one of the digits 0,
 1, or 2. It causes a specific set of built-in character tables to be passed to
 \fBpcre2_compile()\fP. This is used in the PCRE2 tests to check behaviour with
 different character tables. The digit specifies the tables as follows:
@@ -870,17 +992,19 @@
 .SS "Setting certain match controls"
 .rs
 .sp
-The following modifiers are really subject modifiers, and are described below.
-However, they may be included in a pattern's modifier list, in which case they
-are applied to every subject line that is processed with that pattern. They may
-not appear in \fB#pattern\fP commands. These modifiers do not affect the
-compilation process.
+The following modifiers are really subject modifiers, and are described under
+"Subject Modifiers" below. However, they may be included in a pattern's
+modifier list, in which case they are applied to every subject line that is
+processed with that pattern. These modifiers do not affect the compilation
+process.
 .sp
       aftertext                  show text after match
       allaftertext               show text after captures
       allcaptures                show all captures
       allusedtext                show all consulted text
+      altglobal                  alternative global matching
   /g  global                     global matching
+      jitstack=<n>               set size of JIT stack
       mark                       show mark values
       replace=<string>           specify a replacement string
       startchar                  show starting character when relevant
@@ -893,6 +1017,15 @@
 defaults, set them in a \fB#subject\fP command.
 .
 .
+.SS "Specifying literal subject lines"
+.rs
+.sp
+If the \fBsubject_literal\fP modifier is present on a pattern, all the subject
+lines that it matches are taken as literal strings, with no interpretation of
+backslashes. It is not possible to set subject modifiers on such lines, but any
+that are set as defaults by a \fB#subject\fP command are recognized.
+.
+.
 .SS "Saving a compiled pattern"
 .rs
 .sp
@@ -903,7 +1036,9 @@
 section entitled "Saving and restoring compiled patterns"
 .\" HTML <a href="#saverestore">
 .\" </a>
-below. If \fBpushcopy\fP is used instead of \fBpush\fP, a copy of the compiled
+below.
+.\"
+If \fBpushcopy\fP is used instead of \fBpush\fP, a copy of the compiled
 pattern is stacked, leaving the original as current, ready to match the
 following input lines. This provides a way of testing the
 \fBpcre2_code_copy()\fP function.
@@ -916,6 +1051,39 @@
 pattern.
 .
 .
+.SS "Testing foreign pattern conversion"
+.rs
+.sp
+The experimental foreign pattern conversion functions in PCRE2 can be tested by
+setting the \fBconvert\fP modifier. Its argument is a colon-separated list of
+options, which set the equivalent option for the \fBpcre2_pattern_convert()\fP
+function:
+.sp
+  glob                    PCRE2_CONVERT_GLOB
+  glob_no_starstar        PCRE2_CONVERT_GLOB_NO_STARSTAR
+  glob_no_wild_separator  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR
+  posix_basic             PCRE2_CONVERT_POSIX_BASIC
+  posix_extended          PCRE2_CONVERT_POSIX_EXTENDED
+  unset                   Unset all options
+.sp
+The "unset" value is useful for turning off a default that has been set by a
+\fB#pattern\fP command. When one of these options is set, the input pattern is
+passed to \fBpcre2_pattern_convert()\fP. If the conversion is successful, the
+result is reflected in the output and then passed to \fBpcre2_compile()\fP. The
+normal \fButf\fP and \fBno_utf_check\fP options, if set, cause the
+PCRE2_CONVERT_UTF and PCRE2_CONVERT_NO_UTF_CHECK options to be passed to
+\fBpcre2_pattern_convert()\fP.
+.P
+By default, the conversion function is allowed to allocate a buffer for its
+output. However, if the \fBconvert_length\fP modifier is set to a value greater
+than zero, \fBpcre2test\fP passes a buffer of the given length. This makes it
+possible to test the length check.
+.P
+The \fBconvert_glob_escape\fP and \fBconvert_glob_separator\fP modifiers can be
+used to specify the escape and separator characters for glob processing,
+overriding the defaults, which are operating-system dependent.
+.
+.
 .\" HTML <a name="subjectmodifiers"></a>
 .SH "SUBJECT MODIFIERS"
 .rs
@@ -935,6 +1103,7 @@
 for a description of their effects.
 .sp
       anchored                  set PCRE2_ANCHORED
+      endanchored               set PCRE2_ENDANCHORED
       dfa_restart               set PCRE2_DFA_RESTART
       dfa_shortest              set PCRE2_DFA_SHORTEST
       no_jit                    set PCRE2_NO_JIT
@@ -949,11 +1118,27 @@
 The partial matching modifiers are provided with abbreviations because they
 appear frequently in tests.
 .P
-If the \fB/posix\fP modifier was present on the pattern, causing the POSIX
-wrapper API to be used, the only option-setting modifiers that have any effect
-are \fBnotbol\fP, \fBnotempty\fP, and \fBnoteol\fP, causing REG_NOTBOL,
-REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to \fBregexec()\fP.
-The other modifiers are ignored, with a warning message.
+If the \fBposix\fP or \fBposix_nosub\fP modifier was present on the pattern,
+causing the POSIX wrapper API to be used, the only option-setting modifiers
+that have any effect are \fBnotbol\fP, \fBnotempty\fP, and \fBnoteol\fP,
+causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to
+\fBregexec()\fP. The other modifiers are ignored, with a warning message.
+.P
+There is one additional modifier that can be used with the POSIX wrapper. It is
+ignored (with a warning) if used for non-POSIX matching.
+.sp
+      posix_startend=<n>[:<m>]
+.sp
+This causes the subject string to be passed to \fBregexec()\fP using the
+REG_STARTEND option, which uses offsets to specify which part of the string is
+searched. If only one number is given, the end offset is passed as the end of
+the subject string. For more detail of REG_STARTEND, see the
+.\" HREF
+\fBpcre2posix\fP
+.\"
+documentation. If the subject string contains binary zeros (coded as escapes
+such as \ex{00} because \fBpcre2test\fP does not support actual binary zeros in
+its input), you must use \fBposix_startend\fP to specify its length.
 .
 .
 .SS "Setting match controls"
@@ -971,23 +1156,28 @@
       altglobal                  alternative global matching
       callout_capture            show captures at callout time
       callout_data=<n>           set a value to pass via callouts
+      callout_error=<n>[:<m>]    control callout error
+      callout_extra              show extra callout information
       callout_fail=<n>[:<m>]     control callout failure
+      callout_no_where           do not show position of a callout
       callout_none               do not supply a callout function
       copy=<number or name>      copy captured substring
+      depth_limit=<n>            set a depth limit
       dfa                        use \fBpcre2_dfa_match()\fP
-      find_limits                find match and recursion limits
+      find_limits                find match and depth limits
       get=<number or name>       extract captured substring
       getall                     extract all captured substrings
   /g  global                     global matching
+      heap_limit=<n>             set a limit on heap memory
       jitstack=<n>               set size of JIT stack
       mark                       show mark values
       match_limit=<n>            set a match limit
-      memory                     show memory usage
+      memory                     show heap memory usage
       null_context               match with a NULL context
       offset=<n>                 set starting offset
       offset_limit=<n>           set offset limit
       ovector=<n>                set size of output vector
-      recursion_limit=<n>        set a recursion limit
+      recursion_limit=<n>        obsolete synonym for depth_limit
       replace=<string>           specify a replacement string
       startchar                  show startchar when relevant
       startoffset=<n>            same as offset=<n>
@@ -1063,27 +1253,20 @@
 .rs
 .sp
 A callout function is supplied when \fBpcre2test\fP calls the library matching
-functions, unless \fBcallout_none\fP is specified. If \fBcallout_capture\fP is
-set, the current captured groups are output when a callout occurs.
-.P
-The \fBcallout_fail\fP modifier can be given one or two numbers. If there is
-only one number, 1 is returned instead of 0 when a callout of that number is
-reached. If two numbers are given, 1 is returned when callout <n> is reached
-for the <m>th time. Note that callouts with string arguments are always given
-the number zero. See "Callouts" below for a description of the output when a
-callout it taken.
-.P
-The \fBcallout_data\fP modifier can be given an unsigned or a negative number.
-This is set as the "user data" that is passed to the matching function, and
-passed back when the callout function is invoked. Any value other than zero is
-used as a return from \fBpcre2test\fP's callout function.
+functions, unless \fBcallout_none\fP is specified. Its behaviour can be
+controlled by various modifiers listed above whose names begin with
+\fBcallout_\fP. Details are given in the section entitled "Callouts"
+.\" HTML <a href="#callouts">
+.\" </a>
+below.
+.\"
 .
 .
 .SS "Finding all matches in a string"
 .rs
 .sp
 Searching for all possible matches within a subject can be requested by the
-\fBglobal\fP or \fB/altglobal\fP modifier. After finding a match, the matching
+\fBglobal\fP or \fBaltglobal\fP modifier. After finding a match, the matching
 function is called again to search the remainder of the subject. The difference
 between \fBglobal\fP and \fBaltglobal\fP is that the former uses the
 \fIstart_offset\fP argument to \fBpcre2_match()\fP or \fBpcre2_dfa_match()\fP
@@ -1198,39 +1381,44 @@
 .sp
 The \fBjitstack\fP modifier provides a way of setting the maximum stack size
 that is used by the just-in-time optimization code. It is ignored if JIT
-optimization is not being used. The value is a number of kilobytes. Providing a
-stack that is larger than the default 32K is necessary only for very
-complicated patterns.
+optimization is not being used. The value is a number of kilobytes. Setting
+zero reverts to the default of 32K. Providing a stack that is larger than the
+default is necessary only for very complicated patterns. If \fBjitstack\fP is
+set non-zero on a subject line it overrides any value that was set on the
+pattern.
 .
 .
-.SS "Setting match and recursion limits"
+.SS "Setting heap, match, and depth limits"
 .rs
 .sp
-The \fBmatch_limit\fP and \fBrecursion_limit\fP modifiers set the appropriate
-limits in the match context. These values are ignored when the
+The \fBheap_limit\fP, \fBmatch_limit\fP, and \fBdepth_limit\fP modifiers set
+the appropriate limits in the match context. These values are ignored when the
 \fBfind_limits\fP modifier is specified.
 .
 .
 .SS "Finding minimum limits"
 .rs
 .sp
-If the \fBfind_limits\fP modifier is present, \fBpcre2test\fP calls
-\fBpcre2_match()\fP several times, setting different values in the match
-context via \fBpcre2_set_match_limit()\fP and \fBpcre2_set_recursion_limit()\fP
-until it finds the minimum values for each parameter that allow
-\fBpcre2_match()\fP to complete without error.
+If the \fBfind_limits\fP modifier is present on a subject line, \fBpcre2test\fP
+calls the relevant matching function several times, setting different values in
+the match context via \fBpcre2_set_heap_limit(), \fBpcre2_set_match_limit()\fP,
+or \fBpcre2_set_depth_limit()\fP until it finds the minimum values for each
+parameter that allows the match to complete without error.
 .P
 If JIT is being used, only the match limit is relevant. If DFA matching is
-being used, neither limit is relevant, and this modifier is ignored (with a
-warning message).
+being used, only the depth limit is relevant.
 .P
 The \fImatch_limit\fP number is a measure of the amount of backtracking
 that takes place, and learning the minimum value can be instructive. For most
 simple matches, the number is quite small, but for patterns with very large
 numbers of matching possibilities, it can become large very quickly with
-increasing length of subject string. The \fImatch_limit_recursion\fP number is
-a measure of how much stack (or, if PCRE2 is compiled with NO_RECURSE, how much
-heap) memory is needed to complete the match attempt.
+increasing length of subject string.
+.P
+For non-DFA matching, the minimum \fIdepth_limit\fP number is a measure of how
+much nested backtracking happens (that is, how deeply the pattern's tree is
+searched). In the case of DFA matching, \fIdepth_limit\fP controls the depth of
+recursive calls of the internal function that is used for handling pattern
+recursion, lookaround assertions, and atomic groups.
 .
 .
 .SS "Showing MARK names"
@@ -1247,8 +1435,15 @@
 .SS "Showing memory usage"
 .rs
 .sp
-The \fBmemory\fP modifier causes \fBpcre2test\fP to log all memory allocation
-and freeing calls that occur during a match operation.
+The \fBmemory\fP modifier causes \fBpcre2test\fP to log the sizes of all heap
+memory allocation and freeing calls that occur during a call to
+\fBpcre2_match()\fP. These occur only when a match requires a bigger vector
+than the default for remembering backtracking points. In many cases there will
+be no heap memory used and therefore no additional output. No heap memory is
+allocated during matching with \fBpcre2_dfa_match\fP or with JIT, so in those
+cases the \fBmemory\fP modifier never has any effect. For this modifier to
+work, the \fBnull_context\fP modifier must not be set on both the pattern and
+the subject, though it can be set on one or the other.
 .
 .
 .SS "Setting a starting offset"
@@ -1291,8 +1486,8 @@
 By default, the subject string is passed to a native API matching function with
 its correct length. In order to test the facility for passing a zero-terminated
 string, the \fBzero_terminate\fP modifier is provided. It causes the length to
-be passed as PCRE2_ZERO_TERMINATED. (When matching via the POSIX interface,
-this modifier has no effect, as there is no facility for passing a length.)
+be passed as PCRE2_ZERO_TERMINATED. When matching via the POSIX interface,
+this modifier is ignored, with a warning.
 .P
 When testing \fBpcre2_substitute()\fP, this modifier also has the effect of
 passing the replacement string as zero-terminated.
@@ -1349,7 +1544,7 @@
 an example of an interactive \fBpcre2test\fP run.
 .sp
   $ pcre2test
-  PCRE2 version 9.00 2014-05-10
+  PCRE2 version 10.22 2016-07-29
 .sp
     re> /^abc(\ed+)/
   data> abc123
@@ -1376,7 +1571,7 @@
 If the strings contain any non-printing characters, they are output as \exhh
 escapes if the value is less than 256 and UTF mode is not set. Otherwise they
 are output as \ex{hh...} escapes. See below for the definition of non-printing
-characters. If the \fB/aftertext\fP modifier is set, the output for substring
+characters. If the \fBaftertext\fP modifier is set, the output for substring
 0 is followed by the the rest of the subject string, identified by "0+" like
 this:
 .sp
@@ -1470,27 +1665,15 @@
 documentation.
 .
 .
+.\" HTML <a name="callouts"></a>
 .SH CALLOUTS
 .rs
 .sp
 If the pattern contains any callout requests, \fBpcre2test\fP's callout
-function is called during matching unless \fBcallout_none\fP is specified.
-This works with both matching functions.
-.P
-The callout function in \fBpcre2test\fP returns zero (carry on matching) by
-default, but you can use a \fBcallout_fail\fP modifier in a subject line (as
-described above) to change this and other parameters of the callout.
-.P
-Inserting callouts can be helpful when using \fBpcre2test\fP to check
-complicated regular expressions. For further information about callouts, see
-the
-.\" HREF
-\fBpcre2callout\fP
-.\"
-documentation.
-.P
-The output for callouts with numerical arguments and those with string
-arguments is slightly different.
+function is called during matching unless \fBcallout_none\fP is specified. This
+works with both matching functions, and with JIT, though there are some
+differences in behaviour. The output for callouts with numerical arguments and
+those with string arguments is slightly different.
 .
 .
 .SS "Callouts with numerical arguments"
@@ -1511,7 +1694,7 @@
 callout is in a lookbehind assertion.
 .P
 Callouts numbered 255 are assumed to be automatic callouts, inserted as a
-result of the \fB/auto_callout\fP pattern modifier. In this case, instead of
+result of the \fBauto_callout\fP pattern modifier. In this case, instead of
 showing the callout number, the offset in the pattern, preceded by a plus, is
 output. For example:
 .sp
@@ -1564,6 +1747,103 @@
 .sp
 .
 .
+.SS "Callout modifiers"
+.rs
+.sp
+The callout function in \fBpcre2test\fP returns zero (carry on matching) by
+default, but you can use a \fBcallout_fail\fP modifier in a subject line to
+change this and other parameters of the callout (see below).
+.P
+If the \fBcallout_capture\fP modifier is set, the current captured groups are
+output when a callout occurs. This is useful only for non-DFA matching, as
+\fBpcre2_dfa_match()\fP does not support capturing, so no captures are ever
+shown.
+.P
+The normal callout output, showing the callout number or pattern offset (as
+described above) is suppressed if the \fBcallout_no_where\fP modifier is set.
+.P
+When using the interpretive matching function \fBpcre2_match()\fP without JIT,
+setting the \fBcallout_extra\fP modifier causes additional output from
+\fBpcre2test\fP's callout function to be generated. For the first callout in a
+match attempt at a new starting position in the subject, "New match attempt" is
+output. If there has been a backtrack since the last callout (or start of
+matching if this is the first callout), "Backtrack" is output, followed by "No
+other matching paths" if the backtrack ended the previous match attempt. For
+example:
+.sp
+   re> /(a+)b/auto_callout,no_start_optimize,no_auto_possess
+  data> aac\e=callout_extra
+  New match attempt
+  --->aac
+   +0 ^       (
+   +1 ^       a+
+   +3 ^ ^     )
+   +4 ^ ^     b
+  Backtrack
+  --->aac
+   +3 ^^      )
+   +4 ^^      b
+  Backtrack
+  No other matching paths
+  New match attempt
+  --->aac
+   +0  ^      (
+   +1  ^      a+
+   +3  ^^     )
+   +4  ^^     b
+  Backtrack
+  No other matching paths
+  New match attempt
+  --->aac
+   +0   ^     (
+   +1   ^     a+
+  Backtrack
+  No other matching paths
+  New match attempt
+  --->aac
+   +0    ^    (
+   +1    ^    a+
+  No match
+.sp
+Notice that various optimizations must be turned off if you want all possible
+matching paths to be scanned. If \fBno_start_optimize\fP is not used, there is
+an immediate "no match", without any callouts, because the starting
+optimization fails to find "b" in the subject, which it knows must be present
+for any match. If \fBno_auto_possess\fP is not used, the "a+" item is turned
+into "a++", which reduces the number of backtracks.
+.P
+The \fBcallout_extra\fP modifier has no effect if used with the DFA matching
+function, or with JIT.
+.
+.
+.SS "Return values from callouts"
+.rs
+.sp
+The default return from the callout function is zero, which allows matching to
+continue. The \fBcallout_fail\fP modifier can be given one or two numbers. If
+there is only one number, 1 is returned instead of 0 (causing matching to
+backtrack) when a callout of that number is reached. If two numbers (<n>:<m>)
+are given, 1 is returned when callout <n> is reached and there have been at
+least <m> callouts. The \fBcallout_error\fP modifier is similar, except that
+PCRE2_ERROR_CALLOUT is returned, causing the entire matching process to be
+aborted. If both these modifiers are set for the same callout number,
+\fBcallout_error\fP takes precedence. Note that callouts with string arguments
+are always given the number zero.
+.P
+The \fBcallout_data\fP modifier can be given an unsigned or a negative number.
+This is set as the "user data" that is passed to the matching function, and
+passed back when the callout function is invoked. Any value other than zero is
+used as a return from \fBpcre2test\fP's callout function.
+.P
+Inserting callouts can be helpful when using \fBpcre2test\fP to check
+complicated regular expressions. For further information about callouts, see
+the
+.\" HREF
+\fBpcre2callout\fP
+.\"
+documentation.
+.
+.
 .
 .SH "NON-PRINTING CHARACTERS"
 .rs
@@ -1574,7 +1854,7 @@
 .P
 When \fBpcre2test\fP is outputting text that is a matched part of a subject
 string, it behaves in the same way, unless a different locale has been set for
-the pattern (using the \fB/locale\fP modifier). In this case, the
+the pattern (using the \fBlocale\fP modifier). In this case, the
 \fBisprint()\fP function is used to distinguish printing and non-printing
 characters.
 .
@@ -1682,6 +1962,6 @@
 .rs
 .sp
 .nf
-Last updated: 06 July 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 21 December 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/doc/pcre2test.txt b/dist2/doc/pcre2test.txt
index cfa0baa..93efd24 100644
--- a/dist2/doc/pcre2test.txt
+++ b/dist2/doc/pcre2test.txt
@@ -26,7 +26,7 @@
 
        As the original fairly simple PCRE library evolved,  it  acquired  many
        different  features,  and  as  a  result, the original pcretest program
-       ended up with a lot of options in a messy, arcane syntax,  for  testing
+       ended up with a lot of options in a messy, arcane  syntax  for  testing
        all the features. The move to the new PCRE2 API provided an opportunity
        to re-implement the test program as pcre2test, with a cleaner  modifier
        syntax.  Nevertheless,  there are still many obscure modifiers, some of
@@ -45,7 +45,7 @@
        installed. The pcre2test program can be used to test all the libraries.
        However, its own input and output are  always  in  8-bit  format.  When
        testing  the  16-bit  or 32-bit libraries, patterns and subject strings
-       are converted to 16- or  32-bit  format  before  being  passed  to  the
+       are converted to 16-bit or 32-bit format before  being  passed  to  the
        library  functions.  Results are converted back to 8-bit code units for
        output.
 
@@ -58,45 +58,81 @@
 INPUT ENCODING
 
        Input  to  pcre2test is processed line by line, either by calling the C
-       library's fgets() function, or via the libreadline library (see below).
-       The  input  is  processed using using C's string functions, so must not
-       contain binary zeroes, even though in Unix-like  environments,  fgets()
-       treats any bytes other than newline as data characters. In some Windows
-       environments character 26 (hex 1A) causes an immediate end of file, and
-       no further data is read.
+       library's fgets() function, or via the  libreadline  library.  In  some
+       Windows  environments  character 26 (hex 1A) causes an immediate end of
+       file, and no further data is read, so this character should be  avoided
+       unless you really want that action.
 
-       For  maximum portability, therefore, it is safest to avoid non-printing
-       characters in pcre2test input files. There is a facility for specifying
-       some or all of a pattern's characters as hexadecimal pairs, thus making
-       it possible to include binary zeroes in a pattern for testing purposes.
-       Subject  lines are processed for backslash escapes, which makes it pos-
-       sible to include any data value.
+       The  input  is  processed using using C's string functions, so must not
+       contain binary zeros, even though in  Unix-like  environments,  fgets()
+       treats  any  bytes  other  than newline as data characters. An error is
+       generated if a binary zero is encountered. By default subject lines are
+       processed for backslash escapes, which makes it possible to include any
+       data value in strings that are passed to the library for matching.  For
+       patterns,  there  is a facility for specifying some or all of the 8-bit
+       input characters as hexadecimal  pairs,  which  makes  it  possible  to
+       include binary zeros.
+
+   Input for the 16-bit and 32-bit libraries
+
+       When testing the 16-bit or 32-bit libraries, there is a need to be able
+       to generate character code points greater than 255 in the strings  that
+       are  passed to the library. For subject lines, backslash escapes can be
+       used. In addition, when the  utf  modifier  (see  "Setting  compilation
+       options" below) is set, the pattern and any following subject lines are
+       interpreted as UTF-8 strings and translated  to  UTF-16  or  UTF-32  as
+       appropriate.
+
+       For  non-UTF testing of wide characters, the utf8_input modifier can be
+       used. This is mutually exclusive with  utf,  and  is  allowed  only  in
+       16-bit  or  32-bit  mode.  It  causes the pattern and following subject
+       lines to be treated as UTF-8 according to the original definition  (RFC
+       2279), which allows for character values up to 0x7fffffff. Each charac-
+       ter is placed in one 16-bit or 32-bit code unit (in  the  16-bit  case,
+       values greater than 0xffff cause an error to occur).
+
+       UTF-8  (in  its  original definition) is not capable of encoding values
+       greater than 0x7fffffff, but such values can be handled by  the  32-bit
+       library. When testing this library in non-UTF mode with utf8_input set,
+       if any character is preceded by the byte 0xff (which is an illegal byte
+       in  UTF-8)  0x80000000  is  added to the character's value. This is the
+       only way of passing such code points in a pattern string.  For  subject
+       strings, using an escape sequence is preferable.
 
 
 COMMAND LINE OPTIONS
 
        -8        If the 8-bit library has been built, this option causes it to
-                 be  used  (this is the default). If the 8-bit library has not
+                 be used (this is the default). If the 8-bit library  has  not
                  been built, this option causes an error.
 
-       -16       If the 16-bit library has been built, this option  causes  it
-                 to  be  used. If only the 16-bit library has been built, this
-                 is the default. If the 16-bit library  has  not  been  built,
+       -16       If  the  16-bit library has been built, this option causes it
+                 to be used. If only the 16-bit library has been  built,  this
+                 is  the  default.  If  the 16-bit library has not been built,
                  this option causes an error.
 
-       -32       If  the  32-bit library has been built, this option causes it
-                 to be used. If only the 32-bit library has been  built,  this
-                 is  the  default.  If  the 32-bit library has not been built,
+       -32       If the 32-bit library has been built, this option  causes  it
+                 to  be  used. If only the 32-bit library has been built, this
+                 is the default. If the 32-bit library  has  not  been  built,
                  this option causes an error.
 
-       -b        Behave as if each pattern has the /fullbincode modifier;  the
+       -ac       Behave as if each pattern has the auto_callout modifier, that
+                 is, insert automatic callouts into every pattern that is com-
+                 piled.
+
+       -AC       As  for  -ac,  but in addition behave as if each subject line
+                 has the callout_extra  modifier,  that  is,  show  additional
+                 information from callouts.
+
+       -b        Behave  as  if each pattern has the fullbincode modifier; the
                  full internal binary form of the pattern is output after com-
                  pilation.
 
-       -C        Output the version number  of  the  PCRE2  library,  and  all
-                 available  information  about  the optional features that are
-                 included, and then  exit  with  zero  exit  code.  All  other
-                 options are ignored.
+       -C        Output  the  version  number  of  the  PCRE2 library, and all
+                 available information about the optional  features  that  are
+                 included,  and  then  exit  with  zero  exit  code. All other
+                 options are ignored. If both -C and -LM are  present,  which-
+                 ever is first is recognized.
 
        -C option Output  information  about a specific build-time option, then
                  exit. This functionality is intended for use in scripts  such
@@ -110,7 +146,7 @@
                    linksize   the configured internal link size (2, 3, or 4)
                                 exit code is set to the link size
                    newline    the default newline setting:
-                                CR, LF, CRLF, ANYCRLF, or ANY
+                                CR, LF, CRLF, ANYCRLF, ANY, or NUL
                                 exit code is always 0
                    bsr        the default setting for what \R matches:
                                 ANYCRLF or ANY
@@ -147,13 +183,24 @@
 
        -help     Output a brief summary these options and then exit.
 
-       -i        Behave as if each pattern has the /info modifier; information
+       -i        Behave as if each pattern has the info modifier;  information
                  about the compiled pattern is given after compilation.
 
        -jit      Behave  as  if  each pattern line has the jit modifier; after
                  successful compilation, each pattern is passed to  the  just-
                  in-time compiler, if available.
 
+       -jitverify
+                 Behave  as  if  each pattern line has the jitverify modifier;
+                 after successful compilation, each pattern is passed  to  the
+                 just-in-time  compiler,  if  available, and the use of JIT is
+                 verified.
+
+       -LM       List modifiers: write a list of available pattern and subject
+                 modifiers  to  the  standard output, then exit with zero exit
+                 code. All other options are ignored.  If both -C and -LM  are
+                 present, whichever is first is recognized.
+
        -pattern modifier-list
                  Behave as if each pattern line contains the given modifiers.
 
@@ -269,7 +316,7 @@
 
        The #newline_default command specifies a list of newline types that are
        acceptable  as the default. The types must be one of CR, LF, CRLF, ANY-
-       CRLF, or ANY (in upper or lower case), for example:
+       CRLF, ANY, or NUL (in upper or lower case), for example:
 
          #newline_default LF Any anyCRLF
 
@@ -282,9 +329,9 @@
 
        When  the  POSIX  API  is  being tested there is no way to override the
        default newline convention, though it is possible to  set  the  newline
-       convention  from  within  the  pattern. A warning is given if the posix
-       modifier is used when #newline_default would set a default for the non-
-       POSIX API.
+       convention  from within the pattern. A warning is given if the posix or
+       posix_nosub modifier is used when #newline_default would set a  default
+       for the non-POSIX API.
 
          #pattern <modifier-list>
 
@@ -387,8 +434,9 @@
 
        Before   each   subject   line   is   passed   to   pcre2_match()    or
        pcre2_dfa_match(), leading and trailing white space is removed, and the
-       line is scanned for backslash escapes. The following provide a means of
-       encoding non-printing characters in a visible way:
+       line is scanned for backslash escapes, unless the subject_literal modi-
+       fier was set for the pattern. The following provide a means of encoding
+       non-printing characters in a visible way:
 
          \a         alarm (BEL, \x07)
          \b         backspace (\x08)
@@ -405,23 +453,23 @@
          \x{hh...}  hexadecimal character (any number of hex digits)
 
        The use of \x{hh...} is not dependent on the use of the utf modifier on
-       the pattern. It is recognized always. There may be any number of  hexa-
-       decimal  digits  inside  the  braces; invalid values provoke error mes-
+       the  pattern. It is recognized always. There may be any number of hexa-
+       decimal digits inside the braces; invalid  values  provoke  error  mes-
        sages.
 
-       Note that \xhh specifies one byte rather than one  character  in  UTF-8
-       mode;  this  makes it possible to construct invalid UTF-8 sequences for
-       testing purposes. On the other hand, \x{hh} is interpreted as  a  UTF-8
-       character  in UTF-8 mode, generating more than one byte if the value is
-       greater than 127.  When testing the 8-bit library not  in  UTF-8  mode,
+       Note  that  \xhh  specifies one byte rather than one character in UTF-8
+       mode; this makes it possible to construct invalid UTF-8  sequences  for
+       testing  purposes.  On the other hand, \x{hh} is interpreted as a UTF-8
+       character in UTF-8 mode, generating more than one byte if the value  is
+       greater  than  127.   When testing the 8-bit library not in UTF-8 mode,
        \x{hh} generates one byte for values less than 256, and causes an error
        for greater values.
 
        In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it
        possible to construct invalid UTF-16 sequences for testing purposes.
 
-       In  UTF-32  mode,  all  4- to 8-digit \x{...} values are accepted. This
-       makes it possible to construct invalid  UTF-32  sequences  for  testing
+       In UTF-32 mode, all 4- to 8-digit \x{...}  values  are  accepted.  This
+       makes  it  possible  to  construct invalid UTF-32 sequences for testing
        purposes.
 
        There is a special backslash sequence that specifies replication of one
@@ -429,33 +477,38 @@
 
          \[<characters>]{<count>}
 
-       This makes it possible to test long strings without having  to  provide
+       This  makes  it possible to test long strings without having to provide
        them as part of the file. For example:
 
          \[abc]{4}
 
-       is  converted to "abcabcabcabc". This feature does not support nesting.
+       is converted to "abcabcabcabc". This feature does not support  nesting.
        To include a closing square bracket in the characters, code it as \x5D.
 
-       A backslash followed by an equals sign marks the  end  of  the  subject
+       A  backslash  followed  by  an equals sign marks the end of the subject
        string and the start of a modifier list. For example:
 
          abc\=notbol,notempty
 
-       If  the  subject  string is empty and \= is followed by whitespace, the
-       line is treated as a comment line, and is not used  for  matching.  For
+       If the subject string is empty and \= is followed  by  whitespace,  the
+       line  is  treated  as a comment line, and is not used for matching. For
        example:
 
          \= This is a comment.
          abc\= This is an invalid modifier list.
 
-       A  backslash  followed  by  any  other  non-alphanumeric character just
+       A backslash followed  by  any  other  non-alphanumeric  character  just
        escapes that character. A backslash followed by anything else causes an
-       error.  However,  if the very last character in the line is a backslash
-       (and there is no modifier list), it is ignored. This  gives  a  way  of
-       passing  an  empty line as data, since a real empty line terminates the
+       error. However, if the very last character in the line is  a  backslash
+       (and  there  is  no  modifier list), it is ignored. This gives a way of
+       passing an empty line as data, since a real empty line  terminates  the
        data input.
 
+       If the subject_literal modifier is set for a pattern, all subject lines
+       that follow are treated as literals, with no special treatment of back-
+       slashes.  No replication is possible, and any subject modifiers must be
+       set as defaults by a #subject command.
+
 
 PATTERN MODIFIERS
 
@@ -466,28 +519,42 @@
 
    Setting compilation options
 
-       The  following modifiers set options for pcre2_compile(). The most com-
-       mon ones have single-letter abbreviations. See pcre2api for a  descrip-
-       tion of their effects.
+       The  following  modifiers set options for pcre2_compile(). Most of them
+       set bits in the options argument of  that  function,  but  those  whose
+       names start with PCRE2_EXTRA are additional options that are set in the
+       compile context. For the main options,  there  are  some  single-letter
+       abbreviations  that are the same as Perl options. There is special han-
+       dling for /x: if a second x is  present,  PCRE2_EXTENDED  is  converted
+       into   PCRE2_EXTENDED_MORE   as   in  Perl.  A  third  appearance  adds
+       PCRE2_EXTENDED as well, though this makes  no  difference  to  the  way
+       pcre2_compile()  behaves. See pcre2api for a description of the effects
+       of these options.
 
              allow_empty_class         set PCRE2_ALLOW_EMPTY_CLASS
+             allow_surrogate_escapes   set PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES
              alt_bsux                  set PCRE2_ALT_BSUX
              alt_circumflex            set PCRE2_ALT_CIRCUMFLEX
              alt_verbnames             set PCRE2_ALT_VERBNAMES
              anchored                  set PCRE2_ANCHORED
              auto_callout              set PCRE2_AUTO_CALLOUT
+             bad_escape_is_literal     set PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL
          /i  caseless                  set PCRE2_CASELESS
              dollar_endonly            set PCRE2_DOLLAR_ENDONLY
          /s  dotall                    set PCRE2_DOTALL
              dupnames                  set PCRE2_DUPNAMES
+             endanchored               set PCRE2_ENDANCHORED
          /x  extended                  set PCRE2_EXTENDED
+         /xx extended_more             set PCRE2_EXTENDED_MORE
              firstline                 set PCRE2_FIRSTLINE
+             literal                   set PCRE2_LITERAL
+             match_line                set PCRE2_EXTRA_MATCH_LINE
              match_unset_backref       set PCRE2_MATCH_UNSET_BACKREF
+             match_word                set PCRE2_EXTRA_MATCH_WORD
          /m  multiline                 set PCRE2_MULTILINE
              never_backslash_c         set PCRE2_NEVER_BACKSLASH_C
              never_ucp                 set PCRE2_NEVER_UCP
              never_utf                 set PCRE2_NEVER_UTF
-             no_auto_capture           set PCRE2_NO_AUTO_CAPTURE
+         /n  no_auto_capture           set PCRE2_NO_AUTO_CAPTURE
              no_auto_possess           set PCRE2_NO_AUTO_POSSESS
              no_dotstar_anchor         set PCRE2_NO_DOTSTAR_ANCHOR
              no_start_optimize         set PCRE2_NO_START_OPTIMIZE
@@ -498,19 +565,27 @@
              utf                       set PCRE2_UTF
 
        As well as turning on the PCRE2_UTF option, the utf modifier causes all
-       non-printing characters in output  strings  to  be  printed  using  the
-       \x{hh...}  notation. Otherwise, those less than 0x100 are output in hex
-       without the curly brackets.
+       non-printing  characters  in  output  strings  to  be printed using the
+       \x{hh...} notation. Otherwise, those less than 0x100 are output in  hex
+       without  the  curly brackets. Setting utf in 16-bit or 32-bit mode also
+       causes pattern and subject  strings  to  be  translated  to  UTF-16  or
+       UTF-32, respectively, before being passed to library functions.
 
    Setting compilation controls
 
-       The following modifiers  affect  the  compilation  process  or  request
-       information about the pattern:
+       The  following  modifiers  affect  the  compilation  process or request
+       information about the pattern. There  are  single-letter  abbreviations
+       for some that are heavily used in the test files.
 
              bsr=[anycrlf|unicode]     specify \R handling
          /B  bincode                   show binary code without lengths
              callout_info              show callout information
+             convert=<options>         request foreign pattern conversion
+             convert_glob_escape=c     set glob escape character
+             convert_glob_separator=c  set glob separator character
+             convert_length            set convert buffer length
              debug                     same as info,fullbincode
+             framesize                 show matching frame size
              fullbincode               show binary code with lengths
          /I  info                      show info about compiled pattern
              hex                       unquoted characters are hexadecimal
@@ -528,7 +603,10 @@
              push                      push compiled pattern onto the stack
              pushcopy                  push a copy onto the stack
              stackguard=<number>       test the stackguard feature
+             subject_literal           treat all subject lines as literal
              tables=[0|1|2]            select internal tables
+             use_length                do not zero-terminate the pattern
+             utf8_input                treat input as UTF-8
 
        The effects of these modifiers are described in the following sections.
 
@@ -541,7 +619,7 @@
 
        The newline modifier specifies which characters are to  be  interpreted
        as newlines, both in the pattern and in subject lines. The type must be
-       one of CR, LF, CRLF, ANYCRLF, or ANY (in upper or lower case).
+       one of CR, LF, CRLF, ANYCRLF, ANY, or NUL (in upper or lower case).
 
    Information about a pattern
 
@@ -589,6 +667,10 @@
        last character. These lines are omitted if no starting or  ending  code
        units are recorded.
 
+       The  framesize modifier shows the size, in bytes, of the storage frames
+       used by pcre2_match() for handling backtracking. The  size  depends  on
+       the number of capturing parentheses in the pattern.
+
        The  callout_info  modifier requests information about all the callouts
        in the pattern. A list of them is output at the end of any other infor-
        mation that is requested. For each callout, either its number or string
@@ -619,12 +701,30 @@
          /ab "literal" 32/hex
 
        Either single or double quotes may be used. There is no way of  includ-
-       ing the delimiter within a substring.
+       ing  the delimiter within a substring. The hex and expand modifiers are
+       mutually exclusive.
 
-       By  default,  pcre2test  passes  patterns as zero-terminated strings to
-       pcre2_compile(), giving the length as  PCRE2_ZERO_TERMINATED.  However,
-       for  patterns specified with the hex modifier, the actual length of the
-       pattern is passed.
+   Specifying the pattern's length
+
+       By default, patterns are passed to the compiling functions as zero-ter-
+       minated  strings but can be passed by length instead of being zero-ter-
+       minated. The use_length modifier causes this to happen. Using a  length
+       happens  automatically  (whether  or not use_length is set) when hex is
+       set, because patterns  specified  in  hexadecimal  may  contain  binary
+       zeros.
+
+       If hex or use_length is used with the POSIX wrapper API (see "Using the
+       POSIX wrapper API" below), the REG_PEND extension is used to  pass  the
+       pattern's length.
+
+   Specifying wide characters in 16-bit and 32-bit modes
+
+       In 16-bit and 32-bit modes, all input is automatically treated as UTF-8
+       and translated to UTF-16 or UTF-32 when the utf modifier  is  set.  For
+       testing the 16-bit and 32-bit libraries in non-UTF mode, the utf8_input
+       modifier can be used. It is mutually exclusive with  utf.  Input  lines
+       are interpreted as UTF-8 as a means of specifying wide characters. More
+       details are given in "Input encoding" above.
 
    Generating long repetitive patterns
 
@@ -640,38 +740,39 @@
        ple, \[AB]{6000} is expanded to "ABAB..." 6000 times. This construction
        cannot be nested. An initial "\[" sequence is recognized only  if  "]{"
        followed  by  decimal  digits and "}" is found later in the pattern. If
-       not, the characters remain in the pattern unaltered.
+       not, the characters remain in the pattern unaltered. The expand and hex
+       modifiers are mutually exclusive.
 
-       If part of an expanded pattern looks like an expansion, but  is  really
+       If  part  of an expanded pattern looks like an expansion, but is really
        part of the actual pattern, unwanted expansion can be avoided by giving
        two values in the quantifier. For example, \[AB]{6000,6000} is not rec-
        ognized as an expansion item.
 
-       If  the  info modifier is set on an expanded pattern, the result of the
+       If the info modifier is set on an expanded pattern, the result  of  the
        expansion is included in the information that is output.
 
    JIT compilation
 
-       Just-in-time (JIT) compiling is a  heavyweight  optimization  that  can
-       greatly  speed  up pattern matching. See the pcre2jit documentation for
-       details. JIT compiling happens, optionally, after a  pattern  has  been
-       successfully  compiled into an internal form. The JIT compiler converts
+       Just-in-time  (JIT)  compiling  is  a heavyweight optimization that can
+       greatly speed up pattern matching. See the pcre2jit  documentation  for
+       details.  JIT  compiling  happens, optionally, after a pattern has been
+       successfully compiled into an internal form. The JIT compiler  converts
        this to optimized machine code. It needs to know whether the match-time
        options PCRE2_PARTIAL_HARD and PCRE2_PARTIAL_SOFT are going to be used,
-       because different code is generated for the different  cases.  See  the
-       partial  modifier in "Subject Modifiers" below for details of how these
+       because  different  code  is generated for the different cases. See the
+       partial modifier in "Subject Modifiers" below for details of how  these
        options are specified for each match attempt.
 
-       JIT compilation is requested by the /jit pattern  modifier,  which  may
+       JIT  compilation  is  requested  by the jit pattern modifier, which may
        optionally be followed by an equals sign and a number in the range 0 to
-       7.  The three bits that make up the number specify which of  the  three
+       7.   The  three bits that make up the number specify which of the three
        JIT operating modes are to be compiled:
 
          1  compile JIT code for non-partial matching
          2  compile JIT code for soft partial matching
          4  compile JIT code for hard partial matching
 
-       The possible values for the /jit modifier are therefore:
+       The possible values for the jit modifier are therefore:
 
          0  disable JIT
          1  normal matching only
@@ -681,54 +782,54 @@
          6  soft and hard partial matching only
          7  all three modes
 
-       If  no  number  is  given,  7 is assumed. The phrase "partial matching"
+       If no number is given, 7 is  assumed.  The  phrase  "partial  matching"
        means a call to pcre2_match() with either the PCRE2_PARTIAL_SOFT or the
-       PCRE2_PARTIAL_HARD  option set. Note that such a call may return a com-
+       PCRE2_PARTIAL_HARD option set. Note that such a call may return a  com-
        plete match; the options enable the possibility of a partial match, but
-       do  not  require it. Note also that if you request JIT compilation only
-       for partial matching (for example, /jit=2) but do not set  the  partial
-       modifier  on  a  subject line, that match will not use JIT code because
+       do not require it. Note also that if you request JIT  compilation  only
+       for  partial  matching  (for example, jit=2) but do not set the partial
+       modifier on a subject line, that match will not use  JIT  code  because
        none was compiled for non-partial matching.
 
-       If JIT compilation is successful, the compiled JIT code will  automati-
-       cally  be  used  when  an appropriate type of match is run, except when
-       incompatible run-time options are specified. For more details, see  the
-       pcre2jit  documentation. See also the jitstack modifier below for a way
+       If  JIT compilation is successful, the compiled JIT code will automati-
+       cally be used when an appropriate type of match  is  run,  except  when
+       incompatible  run-time options are specified. For more details, see the
+       pcre2jit documentation. See also the jitstack modifier below for a  way
        of setting the size of the JIT stack.
 
-       If the jitfast modifier is specified, matching is done  using  the  JIT
-       "fast  path" interface, pcre2_jit_match(), which skips some of the san-
-       ity checks that are done by pcre2_match(), and of course does not  work
-       when  JIT  is not supported. If jitfast is specified without jit, jit=7
+       If  the  jitfast  modifier is specified, matching is done using the JIT
+       "fast path" interface, pcre2_jit_match(), which skips some of the  san-
+       ity  checks that are done by pcre2_match(), and of course does not work
+       when JIT is not supported. If jitfast is specified without  jit,  jit=7
        is assumed.
 
-       If the jitverify modifier is specified, information about the  compiled
-       pattern  shows  whether  JIT  compilation was or was not successful. If
-       jitverify is specified without jit, jit=7 is assumed. If  JIT  compila-
-       tion  is successful when jitverify is set, the text "(JIT)" is added to
+       If  the jitverify modifier is specified, information about the compiled
+       pattern shows whether JIT compilation was or  was  not  successful.  If
+       jitverify  is  specified without jit, jit=7 is assumed. If JIT compila-
+       tion is successful when jitverify is set, the text "(JIT)" is added  to
        the first output line after a match or non match when JIT-compiled code
        was actually used in the match.
 
    Setting a locale
 
-       The /locale modifier must specify the name of a locale, for example:
+       The locale modifier must specify the name of a locale, for example:
 
          /pattern/locale=fr_FR
 
        The given locale is set, pcre2_maketables() is called to build a set of
-       character tables for the locale, and this is then passed to  pcre2_com-
-       pile()  when compiling the regular expression. The same tables are used
-       when matching the following subject lines. The /locale modifier applies
+       character  tables for the locale, and this is then passed to pcre2_com-
+       pile() when compiling the regular expression. The same tables are  used
+       when  matching the following subject lines. The locale modifier applies
        only to the pattern on which it appears, but can be given in a #pattern
-       command if a default is needed. Setting a locale and alternate  charac-
+       command  if a default is needed. Setting a locale and alternate charac-
        ter tables are mutually exclusive.
 
    Showing pattern memory
 
-       The  /memory  modifier  causes  the size in bytes of the memory used to
-       hold the compiled pattern to be output. This does not include the  size
-       of  the  pcre2_code  block; it is just the actual compiled data. If the
-       pattern is subsequently passed to the JIT compiler, the size of the JIT
+       The memory modifier causes the size in bytes of the memory used to hold
+       the  compiled  pattern  to be output. This does not include the size of
+       the pcre2_code block; it is just the actual compiled data. If the  pat-
+       tern  is  subsequently  passed to the JIT compiler, the size of the JIT
        compiled code is also output. Here is an example:
 
            re> /a(b)c/jit,memory
@@ -738,27 +839,27 @@
 
    Limiting nested parentheses
 
-       The  parens_nest_limit  modifier  sets  a  limit on the depth of nested
-       parentheses in a pattern. Breaching  the  limit  causes  a  compilation
-       error.   The  default  for  the library is set when PCRE2 is built, but
-       pcre2test sets its own default of 220, which is  required  for  running
+       The parens_nest_limit modifier sets a limit  on  the  depth  of  nested
+       parentheses  in  a  pattern.  Breaching  the limit causes a compilation
+       error.  The default for the library is set when  PCRE2  is  built,  but
+       pcre2test  sets  its  own default of 220, which is required for running
        the standard test suite.
 
    Limiting the pattern length
 
-       The  max_pattern_length  modifier  sets  a limit, in code units, to the
+       The max_pattern_length modifier sets a limit, in  code  units,  to  the
        length of pattern that pcre2_compile() will accept. Breaching the limit
-       causes  a  compilation  error.  The  default  is  the  largest number a
+       causes a compilation  error.  The  default  is  the  largest  number  a
        PCRE2_SIZE variable can hold (essentially unlimited).
 
    Using the POSIX wrapper API
 
-       The /posix and posix_nosub modifiers cause pcre2test to call PCRE2  via
-       the  POSIX  wrapper API rather than its native API. When posix_nosub is
-       used, the POSIX option REG_NOSUB is  passed  to  regcomp().  The  POSIX
-       wrapper  supports  only  the 8-bit library. Note that it does not imply
+       The  posix  and posix_nosub modifiers cause pcre2test to call PCRE2 via
+       the POSIX wrapper API rather than its native API. When  posix_nosub  is
+       used,  the  POSIX  option  REG_NOSUB  is passed to regcomp(). The POSIX
+       wrapper supports only the 8-bit library. Note that it  does  not  imply
        POSIX matching semantics; for more detail see the pcre2posix documenta-
-       tion.  The  following  pattern  modifiers set options for the regcomp()
+       tion. The following pattern modifiers set  options  for  the  regcomp()
        function:
 
          caseless           REG_ICASE
@@ -768,35 +869,39 @@
          ucp                REG_UCP        )   the POSIX standard
          utf                REG_UTF8       )
 
-       The regerror_buffsize modifier specifies a size for  the  error  buffer
-       that  is  passed to regerror() in the event of a compilation error. For
+       The  regerror_buffsize  modifier  specifies a size for the error buffer
+       that is passed to regerror() in the event of a compilation  error.  For
        example:
 
          /abc/posix,regerror_buffsize=20
 
-       This provides a means of testing the behaviour of regerror()  when  the
-       buffer  is  too  small  for the error message. If this modifier has not
+       This  provides  a means of testing the behaviour of regerror() when the
+       buffer is too small for the error message. If  this  modifier  has  not
        been set, a large buffer is used.
 
-       The aftertext and allaftertext  subject  modifiers  work  as  described
-       below.  All other modifiers are either ignored, with a warning message,
+       The  aftertext  and  allaftertext  subject  modifiers work as described
+       below. All other modifiers are either ignored, with a warning  message,
        or cause an error.
 
+       The  pattern  is  passed  to  regcomp()  as a zero-terminated string by
+       default, but if the use_length or hex modifiers are set,  the  REG_PEND
+       extension is used to pass it by length.
+
    Testing the stack guard feature
 
-       The /stackguard modifier is used to  test  the  use  of  pcre2_set_com-
-       pile_recursion_guard(),  a  function  that  is provided to enable stack
-       availability to be checked during compilation (see the  pcre2api  docu-
-       mentation  for  details).  If  the  number specified by the modifier is
+       The  stackguard  modifier  is  used  to  test the use of pcre2_set_com-
+       pile_recursion_guard(), a function that is  provided  to  enable  stack
+       availability  to  be checked during compilation (see the pcre2api docu-
+       mentation for details). If the number  specified  by  the  modifier  is
        greater than zero, pcre2_set_compile_recursion_guard() is called to set
-       up  callback  from pcre2_compile() to a local function. The argument it
-       receives is the current nesting parenthesis depth; if this  is  greater
+       up callback from pcre2_compile() to a local function. The  argument  it
+       receives  is  the current nesting parenthesis depth; if this is greater
        than the value given by the modifier, non-zero is returned, causing the
        compilation to be aborted.
 
    Using alternative character tables
 
-       The value specified for the /tables modifier must be one of the  digits
+       The  value  specified for the tables modifier must be one of the digits
        0, 1, or 2. It causes a specific set of built-in character tables to be
        passed to pcre2_compile(). This is used in the PCRE2 tests to check be-
        haviour with different character tables. The digit specifies the tables
@@ -807,23 +912,25 @@
                pcre2_chartables.c.dist
          2   a set of tables defining ISO 8859 characters
 
-       In table 2, some characters whose codes are greater than 128 are  iden-
-       tified  as  letters,  digits,  spaces, etc. Setting alternate character
+       In  table 2, some characters whose codes are greater than 128 are iden-
+       tified as letters, digits, spaces,  etc.  Setting  alternate  character
        tables and a locale are mutually exclusive.
 
    Setting certain match controls
 
        The following modifiers are really subject modifiers, and are described
-       below.   However, they may be included in a pattern's modifier list, in
-       which case they are applied to every subject  line  that  is  processed
-       with that pattern. They may not appear in #pattern commands. These mod-
-       ifiers do not affect the compilation process.
+       under "Subject Modifiers" below. However, they may  be  included  in  a
+       pattern's  modifier  list, in which case they are applied to every sub-
+       ject line that is processed with that pattern. These modifiers  do  not
+       affect the compilation process.
 
              aftertext                  show text after match
              allaftertext               show text after captures
              allcaptures                show all captures
              allusedtext                show all consulted text
+             altglobal                  alternative global matching
          /g  global                     global matching
+             jitstack=<n>               set size of JIT stack
              mark                       show mark values
              replace=<string>           specify a replacement string
              startchar                  show starting character when relevant
@@ -832,26 +939,65 @@
              substitute_unknown_unset   use PCRE2_SUBSTITUTE_UNKNOWN_UNSET
              substitute_unset_empty     use PCRE2_SUBSTITUTE_UNSET_EMPTY
 
-       These modifiers may not appear in a #pattern command. If you want  them
+       These  modifiers may not appear in a #pattern command. If you want them
        as defaults, set them in a #subject command.
 
+   Specifying literal subject lines
+
+       If the subject_literal modifier is present on a pattern, all  the  sub-
+       ject lines that it matches are taken as literal strings, with no inter-
+       pretation of backslashes. It is not possible to set  subject  modifiers
+       on  such  lines, but any that are set as defaults by a #subject command
+       are recognized.
+
    Saving a compiled pattern
 
-       When  a  pattern with the push modifier is successfully compiled, it is
-       pushed onto a stack of compiled patterns,  and  pcre2test  expects  the
-       next  line to contain a new pattern (or a command) instead of a subject
+       When a pattern with the push modifier is successfully compiled,  it  is
+       pushed  onto  a  stack  of compiled patterns, and pcre2test expects the
+       next line to contain a new pattern (or a command) instead of a  subject
        line. This facility is used when saving compiled patterns to a file, as
-       described  in  the section entitled "Saving and restoring compiled pat-
-       terns" below. If pushcopy is used instead of push, a copy of  the  com-
-       piled  pattern  is  stacked,  leaving the original as current, ready to
-       match the following input lines. This provides a  way  of  testing  the
-       pcre2_code_copy()  function.   The  push  and  pushcopy   modifiers are
-       incompatible with compilation modifiers such  as  global  that  act  at
-       match  time. Any that are specified are ignored (for the stacked copy),
+       described in the section entitled "Saving and restoring  compiled  pat-
+       terns"  below.  If pushcopy is used instead of push, a copy of the com-
+       piled pattern is stacked, leaving the original  as  current,  ready  to
+       match  the  following  input  lines. This provides a way of testing the
+       pcre2_code_copy() function.   The  push  and  pushcopy   modifiers  are
+       incompatible  with  compilation  modifiers  such  as global that act at
+       match time. Any that are specified are ignored (for the stacked  copy),
        with a warning message, except for replace, which causes an error. Note
-       that  jitverify, which is allowed, does not carry through to any subse-
+       that jitverify, which is allowed, does not carry through to any  subse-
        quent matching that uses a stacked pattern.
 
+   Testing foreign pattern conversion
+
+       The  experimental  foreign pattern conversion functions in PCRE2 can be
+       tested by setting the convert modifier. Its argument is  a  colon-sepa-
+       rated  list  of  options,  which  set  the  equivalent  option  for the
+       pcre2_pattern_convert() function:
+
+         glob                    PCRE2_CONVERT_GLOB
+         glob_no_starstar        PCRE2_CONVERT_GLOB_NO_STARSTAR
+         glob_no_wild_separator  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR
+         posix_basic             PCRE2_CONVERT_POSIX_BASIC
+         posix_extended          PCRE2_CONVERT_POSIX_EXTENDED
+         unset                   Unset all options
+
+       The "unset" value is useful for turning off a default that has been set
+       by a #pattern command. When one of these options is set, the input pat-
+       tern is passed to pcre2_pattern_convert(). If the  conversion  is  suc-
+       cessful,  the  result  is  reflected  in  the output and then passed to
+       pcre2_compile(). The normal utf and no_utf_check options, if set, cause
+       the  PCRE2_CONVERT_UTF  and  PCRE2_CONVERT_NO_UTF_CHECK  options  to be
+       passed to pcre2_pattern_convert().
+
+       By default, the conversion function is allowed to allocate a buffer for
+       its  output.  However, if the convert_length modifier is set to a value
+       greater than zero, pcre2test passes a buffer of the given length.  This
+       makes it possible to test the length check.
+
+       The  convert_glob_escape  and  convert_glob_separator  modifiers can be
+       used to specify the escape and separator characters for  glob  process-
+       ing, overriding the defaults, which are operating-system dependent.
+
 
 SUBJECT MODIFIERS
 
@@ -860,10 +1006,11 @@
 
    Setting match options
 
-       The    following   modifiers   set   options   for   pcre2_match()   or
+       The   following   modifiers   set   options   for   pcre2_match()    or
        pcre2_dfa_match(). See pcreapi for a description of their effects.
 
              anchored                  set PCRE2_ANCHORED
+             endanchored               set PCRE2_ENDANCHORED
              dfa_restart               set PCRE2_DFA_RESTART
              dfa_shortest              set PCRE2_DFA_SHORTEST
              no_jit                    set PCRE2_NO_JIT
@@ -875,20 +1022,34 @@
              partial_hard (or ph)      set PCRE2_PARTIAL_HARD
              partial_soft (or ps)      set PCRE2_PARTIAL_SOFT
 
-       The partial matching modifiers are provided with abbreviations  because
+       The  partial matching modifiers are provided with abbreviations because
        they appear frequently in tests.
 
-       If  the  /posix  modifier was present on the pattern, causing the POSIX
-       wrapper API to be used, the only option-setting modifiers that have any
-       effect   are   notbol,   notempty,   and  noteol,  causing  REG_NOTBOL,
-       REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to  regexec().
-       The other modifiers are ignored, with a warning message.
+       If the posix or posix_nosub modifier was present on the pattern,  caus-
+       ing the POSIX wrapper API to be used, the only option-setting modifiers
+       that have any effect are notbol, notempty, and noteol, causing REG_NOT-
+       BOL,  REG_NOTEMPTY,  and  REG_NOTEOL,  respectively,  to  be  passed to
+       regexec(). The other modifiers are ignored, with a warning message.
+
+       There is one additional modifier that can be used with the POSIX  wrap-
+       per. It is ignored (with a warning) if used for non-POSIX matching.
+
+             posix_startend=<n>[:<m>]
+
+       This  causes  the  subject  string  to be passed to regexec() using the
+       REG_STARTEND option, which uses offsets to specify which  part  of  the
+       string  is  searched.  If  only  one number is given, the end offset is
+       passed as the end of the subject string. For more detail  of  REG_STAR-
+       TEND,  see the pcre2posix documentation. If the subject string contains
+       binary zeros (coded as escapes such as \x{00}  because  pcre2test  does
+       not support actual binary zeros in its input), you must use posix_star-
+       tend to specify its length.
 
    Setting match controls
 
-       The  following  modifiers  affect the matching process or request addi-
-       tional information. Some of them may also be  specified  on  a  pattern
-       line  (see  above), in which case they apply to every subject line that
+       The following modifiers affect the matching process  or  request  addi-
+       tional  information.  Some  of  them may also be specified on a pattern
+       line (see above), in which case they apply to every subject  line  that
        is matched against that pattern.
 
              aftertext                  show text after match
@@ -898,23 +1059,28 @@
              altglobal                  alternative global matching
              callout_capture            show captures at callout time
              callout_data=<n>           set a value to pass via callouts
+             callout_error=<n>[:<m>]    control callout error
+             callout_extra              show extra callout information
              callout_fail=<n>[:<m>]     control callout failure
+             callout_no_where           do not show position of a callout
              callout_none               do not supply a callout function
              copy=<number or name>      copy captured substring
+             depth_limit=<n>            set a depth limit
              dfa                        use pcre2_dfa_match()
-             find_limits                find match and recursion limits
+             find_limits                find match and depth limits
              get=<number or name>       extract captured substring
              getall                     extract all captured substrings
          /g  global                     global matching
+             heap_limit=<n>             set a limit on heap memory
              jitstack=<n>               set size of JIT stack
              mark                       show mark values
              match_limit=<n>            set a match limit
-             memory                     show memory usage
+             memory                     show heap memory usage
              null_context               match with a NULL context
              offset=<n>                 set starting offset
              offset_limit=<n>           set offset limit
              ovector=<n>                set size of output vector
-             recursion_limit=<n>        set a recursion limit
+             recursion_limit=<n>        obsolete synonym for depth_limit
              replace=<string>           specify a replacement string
              startchar                  show startchar when relevant
              startoffset=<n>            same as offset=<n>
@@ -925,29 +1091,29 @@
              zero_terminate             pass the subject as zero-terminated
 
        The effects of these modifiers are described in the following sections.
-       When  matching  via the POSIX wrapper API, the aftertext, allaftertext,
-       and ovector subject modifiers work as described below. All other  modi-
+       When matching via the POSIX wrapper API, the  aftertext,  allaftertext,
+       and  ovector subject modifiers work as described below. All other modi-
        fiers are either ignored, with a warning message, or cause an error.
 
    Showing more text
 
-       The  aftertext modifier requests that as well as outputting the part of
+       The aftertext modifier requests that as well as outputting the part  of
        the subject string that matched the entire pattern, pcre2test should in
        addition output the remainder of the subject string. This is useful for
        tests where the subject contains multiple copies of the same substring.
-       The  allaftertext  modifier  requests the same action for captured sub-
+       The allaftertext modifier requests the same action  for  captured  sub-
        strings as well as the main matched substring. In each case the remain-
        der is output on the following line with a plus character following the
        capture number.
 
-       The allusedtext modifier requests that all the text that was  consulted
-       during  a  successful pattern match by the interpreter should be shown.
-       This feature is not supported for JIT matching, and if  requested  with
-       JIT  it  is  ignored  (with  a  warning message). Setting this modifier
+       The  allusedtext modifier requests that all the text that was consulted
+       during a successful pattern match by the interpreter should  be  shown.
+       This  feature  is not supported for JIT matching, and if requested with
+       JIT it is ignored (with  a  warning  message).  Setting  this  modifier
        affects the output if there is a lookbehind at the start of a match, or
-       a  lookahead  at  the  end, or if \K is used in the pattern. Characters
-       that precede or follow the start and end of the actual match are  indi-
-       cated  in  the output by '<' or '>' characters underneath them. Here is
+       a lookahead at the end, or if \K is used  in  the  pattern.  Characters
+       that  precede or follow the start and end of the actual match are indi-
+       cated in the output by '<' or '>' characters underneath them.  Here  is
        an example:
 
            re> /(?<=pqr)abc(?=xyz)/
@@ -955,16 +1121,16 @@
           0: pqrabcxyz
              <<<   >>>
 
-       This shows that the matched string is "abc",  with  the  preceding  and
-       following  strings  "pqr"  and  "xyz"  having been consulted during the
+       This  shows  that  the  matched string is "abc", with the preceding and
+       following strings "pqr" and "xyz"  having  been  consulted  during  the
        match (when processing the assertions).
 
-       The startchar modifier requests that the  starting  character  for  the
-       match  be  indicated,  if  it  is different to the start of the matched
+       The  startchar  modifier  requests  that the starting character for the
+       match be indicated, if it is different to  the  start  of  the  matched
        string. The only time when this occurs is when \K has been processed as
        part of the match. In this situation, the output for the matched string
-       is displayed from the starting character  instead  of  from  the  match
-       point,  with  circumflex  characters  under the earlier characters. For
+       is  displayed  from  the  starting  character instead of from the match
+       point, with circumflex characters under  the  earlier  characters.  For
        example:
 
            re> /abc\Kxyz/
@@ -972,7 +1138,7 @@
           0: abcxyz
              ^^^
 
-       Unlike allusedtext, the startchar modifier can be used with JIT.   How-
+       Unlike  allusedtext, the startchar modifier can be used with JIT.  How-
        ever, these two modifiers are mutually exclusive.
 
    Showing the value of all capture groups
@@ -980,90 +1146,78 @@
        The allcaptures modifier requests that the values of all potential cap-
        tured parentheses be output after a match. By default, only those up to
        the highest one actually used in the match are output (corresponding to
-       the return code from pcre2_match()). Groups that did not take  part  in
-       the  match  are  output as "<unset>". This modifier is not relevant for
-       DFA matching (which does no capturing); it is ignored, with  a  warning
+       the  return  code from pcre2_match()). Groups that did not take part in
+       the match are output as "<unset>". This modifier is  not  relevant  for
+       DFA  matching  (which does no capturing); it is ignored, with a warning
        message, if present.
 
    Testing callouts
 
-       A  callout function is supplied when pcre2test calls the library match-
-       ing functions, unless callout_none is specified. If callout_capture  is
-       set, the current captured groups are output when a callout occurs.
-
-       The  callout_fail modifier can be given one or two numbers. If there is
-       only one number, 1 is returned instead of 0 when a callout of that num-
-       ber  is  reached.  If two numbers are given, 1 is returned when callout
-       <n> is reached for the <m>th time. Note that callouts with string argu-
-       ments  are  always  given  the  number zero. See "Callouts" below for a
-       description of the output when a callout it taken.
-
-       The callout_data modifier can be given an unsigned or a  negative  num-
-       ber.   This  is  set  as the "user data" that is passed to the matching
-       function, and passed back when the callout  function  is  invoked.  Any
-       value  other  than  zero  is  used as a return from pcre2test's callout
-       function.
+       A callout function is supplied when pcre2test calls the library  match-
+       ing  functions,  unless callout_none is specified. Its behaviour can be
+       controlled by various modifiers listed above  whose  names  begin  with
+       callout_. Details are given in the section entitled "Callouts" below.
 
    Finding all matches in a string
 
        Searching for all possible matches within a subject can be requested by
-       the  global or /altglobal modifier. After finding a match, the matching
-       function is called again to search the remainder of  the  subject.  The
-       difference  between  global  and  altglobal is that the former uses the
-       start_offset argument to pcre2_match() or  pcre2_dfa_match()  to  start
-       searching  at  a new point within the entire string (which is what Perl
+       the global or altglobal modifier. After finding a match,  the  matching
+       function  is  called  again to search the remainder of the subject. The
+       difference between global and altglobal is that  the  former  uses  the
+       start_offset  argument  to  pcre2_match() or pcre2_dfa_match() to start
+       searching at a new point within the entire string (which is  what  Perl
        does), whereas the latter passes over a shortened subject. This makes a
        difference to the matching process if the pattern begins with a lookbe-
        hind assertion (including \b or \B).
 
-       If an empty string  is  matched,  the  next  match  is  done  with  the
+       If  an  empty  string  is  matched,  the  next  match  is done with the
        PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED flags set, in order to search
        for another, non-empty, match at the same point in the subject. If this
-       match  fails,  the  start  offset  is advanced, and the normal match is
-       retried. This imitates the way Perl handles such cases when  using  the
-       /g  modifier  or  the  split()  function. Normally, the start offset is
-       advanced by one character, but if  the  newline  convention  recognizes
-       CRLF  as  a newline, and the current character is CR followed by LF, an
+       match fails, the start offset is advanced,  and  the  normal  match  is
+       retried.  This  imitates the way Perl handles such cases when using the
+       /g modifier or the split() function.  Normally,  the  start  offset  is
+       advanced  by  one  character,  but if the newline convention recognizes
+       CRLF as a newline, and the current character is CR followed by  LF,  an
        advance of two characters occurs.
 
    Testing substring extraction functions
 
-       The copy  and  get  modifiers  can  be  used  to  test  the  pcre2_sub-
+       The  copy  and  get  modifiers  can  be  used  to  test  the pcre2_sub-
        string_copy_xxx() and pcre2_substring_get_xxx() functions.  They can be
-       given more than once, and each can specify a group name or number,  for
+       given  more than once, and each can specify a group name or number, for
        example:
 
           abcd\=copy=1,copy=3,get=G1
 
-       If  the  #subject command is used to set default copy and/or get lists,
-       these can be unset by specifying a negative number to cancel  all  num-
+       If the #subject command is used to set default copy and/or  get  lists,
+       these  can  be unset by specifying a negative number to cancel all num-
        bered groups and an empty name to cancel all named groups.
 
-       The  getall  modifier  tests pcre2_substring_list_get(), which extracts
+       The getall modifier tests  pcre2_substring_list_get(),  which  extracts
        all captured substrings.
 
-       If the subject line is successfully matched, the  substrings  extracted
-       by  the  convenience  functions  are  output  with C, G, or L after the
-       string number instead of a colon. This is in  addition  to  the  normal
-       full  list.  The string length (that is, the return from the extraction
+       If  the  subject line is successfully matched, the substrings extracted
+       by the convenience functions are output with  C,  G,  or  L  after  the
+       string  number  instead  of  a colon. This is in addition to the normal
+       full list. The string length (that is, the return from  the  extraction
        function) is given in parentheses after each substring, followed by the
        name when the extraction was by name.
 
    Testing the substitution function
 
-       If  the  replace  modifier  is  set, the pcre2_substitute() function is
-       called instead of one of the matching functions. Note that  replacement
-       strings  cannot  contain commas, because a comma signifies the end of a
+       If the replace modifier is  set,  the  pcre2_substitute()  function  is
+       called  instead of one of the matching functions. Note that replacement
+       strings cannot contain commas, because a comma signifies the end  of  a
        modifier. This is not thought to be an issue in a test program.
 
-       Unlike subject strings, pcre2test does not process replacement  strings
-       for  escape  sequences. In UTF mode, a replacement string is checked to
-       see if it is a valid UTF-8 string. If so, it is correctly converted  to
-       a  UTF  string of the appropriate code unit width. If it is not a valid
-       UTF-8 string, the individual code units are copied directly. This  pro-
+       Unlike  subject strings, pcre2test does not process replacement strings
+       for escape sequences. In UTF mode, a replacement string is  checked  to
+       see  if it is a valid UTF-8 string. If so, it is correctly converted to
+       a UTF string of the appropriate code unit width. If it is not  a  valid
+       UTF-8  string, the individual code units are copied directly. This pro-
        vides a means of passing an invalid UTF-8 string for testing purposes.
 
-       The  following modifiers set options (in additional to the normal match
+       The following modifiers set options (in additional to the normal  match
        options) for pcre2_substitute():
 
          global                      PCRE2_SUBSTITUTE_GLOBAL
@@ -1073,8 +1227,8 @@
          substitute_unset_empty      PCRE2_SUBSTITUTE_UNSET_EMPTY
 
 
-       After a successful substitution, the modified string  is  output,  pre-
-       ceded  by the number of replacements. This may be zero if there were no
+       After  a  successful  substitution, the modified string is output, pre-
+       ceded by the number of replacements. This may be zero if there were  no
        matches. Here is a simple example of a substitution test:
 
          /abc/replace=xxx
@@ -1083,12 +1237,12 @@
              =abc=abc=\=global
           2: =xxx=xxx=
 
-       Subject and replacement strings should be kept relatively short  (fewer
-       than  256 characters) for substitution tests, as fixed-size buffers are
-       used. To make it easy to test for buffer overflow, if  the  replacement
-       string  starts  with a number in square brackets, that number is passed
-       to pcre2_substitute() as the  size  of  the  output  buffer,  with  the
-       replacement  string  starting at the next character. Here is an example
+       Subject  and replacement strings should be kept relatively short (fewer
+       than 256 characters) for substitution tests, as fixed-size buffers  are
+       used.  To  make it easy to test for buffer overflow, if the replacement
+       string starts with a number in square brackets, that number  is  passed
+       to  pcre2_substitute()  as  the  size  of  the  output buffer, with the
+       replacement string starting at the next character. Here is  an  example
        that tests the edge case:
 
          /abc/
@@ -1097,11 +1251,11 @@
              123abc123\=replace=[9]XYZ
          Failed: error -47: no more memory
 
-       The   default   action   of    pcre2_substitute()    is    to    return
-       PCRE2_ERROR_NOMEMORY  when  the output buffer is too small. However, if
-       the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH option is set (by using  the  sub-
-       stitute_overflow_length  modifier),  pcre2_substitute() continues to go
-       through the motions of matching and substituting, in order  to  compute
+       The    default    action    of    pcre2_substitute()   is   to   return
+       PCRE2_ERROR_NOMEMORY when the output buffer is too small.  However,  if
+       the  PCRE2_SUBSTITUTE_OVERFLOW_LENGTH  option is set (by using the sub-
+       stitute_overflow_length modifier), pcre2_substitute() continues  to  go
+       through  the  motions of matching and substituting, in order to compute
        the size of buffer that is required. When this happens, pcre2test shows
        the required buffer length (which includes space for the trailing zero)
        as part of the error message. For example:
@@ -1111,43 +1265,48 @@
          Failed: error -47: no more memory: 10 code units are needed
 
        A replacement string is ignored with POSIX and DFA matching. Specifying
-       partial matching provokes an error return  ("bad  option  value")  from
+       partial  matching  provokes  an  error return ("bad option value") from
        pcre2_substitute().
 
    Setting the JIT stack size
 
-       The  jitstack modifier provides a way of setting the maximum stack size
-       that is used by the just-in-time optimization code. It  is  ignored  if
+       The jitstack modifier provides a way of setting the maximum stack  size
+       that  is  used  by the just-in-time optimization code. It is ignored if
        JIT optimization is not being used. The value is a number of kilobytes.
-       Providing a stack that is larger than the default 32K is necessary only
-       for very complicated patterns.
+       Setting  zero  reverts to the default of 32K. Providing a stack that is
+       larger than the default is necessary only  for  very  complicated  pat-
+       terns.  If  jitstack is set non-zero on a subject line it overrides any
+       value that was set on the pattern.
 
-   Setting match and recursion limits
+   Setting heap, match, and depth limits
 
-       The  match_limit and recursion_limit modifiers set the appropriate lim-
-       its in the match context. These values are ignored when the find_limits
-       modifier is specified.
+       The heap_limit, match_limit, and depth_limit modifiers set  the  appro-
+       priate  limits  in the match context. These values are ignored when the
+       find_limits modifier is specified.
 
    Finding minimum limits
 
-       If  the  find_limits modifier is present, pcre2test calls pcre2_match()
-       several times, setting  different  values  in  the  match  context  via
-       pcre2_set_match_limit()  and pcre2_set_recursion_limit() until it finds
-       the minimum values for each parameter that allow pcre2_match() to  com-
-       plete without error.
+       If the find_limits modifier is present on  a  subject  line,  pcre2test
+       calls  the  relevant matching function several times, setting different
+       values   in   the    match    context    via    pcre2_set_heap_limit(),
+       pcre2_set_match_limit(),  or pcre2_set_depth_limit() until it finds the
+       minimum values for each parameter that allows  the  match  to  complete
+       without error.
 
        If JIT is being used, only the match limit is relevant. If DFA matching
-       is being used, neither limit is relevant, and this modifier is  ignored
-       (with a warning message).
+       is being used, only the depth limit is relevant.
 
-       The  match_limit number is a measure of the amount of backtracking that
-       takes place, and learning the minimum value  can  be  instructive.  For
-       most  simple  matches, the number is quite small, but for patterns with
-       very large numbers of matching possibilities, it can become large  very
-       quickly    with    increasing    length    of   subject   string.   The
-       match_limit_recursion number is a measure of how  much  stack  (or,  if
-       PCRE2  is  compiled with NO_RECURSE, how much heap) memory is needed to
-       complete the match attempt.
+       The match_limit number is a measure of the amount of backtracking  that
+       takes  place,  and  learning  the minimum value can be instructive. For
+       most simple matches, the number is quite small, but for  patterns  with
+       very  large numbers of matching possibilities, it can become large very
+       quickly with increasing length of subject string.
+
+       For non-DFA matching, the minimum depth_limit number is  a  measure  of
+       how much nested backtracking happens (that is, how deeply the pattern's
+       tree is searched). In the case of DFA  matching,  depth_limit  controls
+       the  depth of recursive calls of the internal function that is used for
+       handling pattern recursion, lookaround assertions, and atomic groups.
 
    Showing MARK names
 
@@ -1160,8 +1319,16 @@
 
    Showing memory usage
 
-       The memory modifier causes pcre2test to log all memory  allocation  and
-       freeing calls that occur during a match operation.
+       The memory modifier causes pcre2test to log the sizes of all heap  mem-
+       ory   allocation  and  freeing  calls  that  occur  during  a  call  to
+       pcre2_match(). These occur only when a match requires a  bigger  vector
+       than  the  default  for  remembering backtracking points. In many cases
+       there will be no heap memory used and therefore no  additional  output.
+       No  heap  memory  is  allocated during matching with pcre2_dfa_match or
+       with JIT, so in those cases the memory modifier never has  any  effect.
+       For this modifier to work, the null_context modifier must not be set on
+       both the pattern and the subject, though it can be set on  one  or  the
+       other.
 
    Setting a starting offset
 
@@ -1196,59 +1363,58 @@
        By default, the subject string is passed to a native API matching func-
        tion with its correct length. In order to test the facility for passing
        a  zero-terminated  string, the zero_terminate modifier is provided. It
-       causes the length to be passed as PCRE2_ZERO_TERMINATED. (When matching
-       via  the  POSIX  interface, this modifier has no effect, as there is no
-       facility for passing a length.)
+       causes the length to be passed as PCRE2_ZERO_TERMINATED. When  matching
+       via the POSIX interface, this modifier is ignored, with a warning.
 
-       When testing pcre2_substitute(), this modifier also has the  effect  of
+       When  testing  pcre2_substitute(), this modifier also has the effect of
        passing the replacement string as zero-terminated.
 
    Passing a NULL context
 
-       Normally,   pcre2test   passes   a   context  block  to  pcre2_match(),
+       Normally,  pcre2test  passes  a   context   block   to   pcre2_match(),
        pcre2_dfa_match() or pcre2_jit_match(). If the null_context modifier is
-       set,  however,  NULL  is  passed. This is for testing that the matching
+       set, however, NULL is passed. This is for  testing  that  the  matching
        functions behave correctly in this case (they use default values). This
-       modifier  cannot  be used with the find_limits modifier or when testing
+       modifier cannot be used with the find_limits modifier or  when  testing
        the substitution function.
 
 
 THE ALTERNATIVE MATCHING FUNCTION
 
-       By default,  pcre2test  uses  the  standard  PCRE2  matching  function,
+       By  default,  pcre2test  uses  the  standard  PCRE2  matching function,
        pcre2_match() to match each subject line. PCRE2 also supports an alter-
-       native matching function, pcre2_dfa_match(), which operates in  a  dif-
-       ferent  way, and has some restrictions. The differences between the two
+       native  matching  function, pcre2_dfa_match(), which operates in a dif-
+       ferent way, and has some restrictions. The differences between the  two
        functions are described in the pcre2matching documentation.
 
-       If the dfa modifier is set, the alternative matching function is  used.
-       This  function  finds all possible matches at a given point in the sub-
-       ject. If, however, the dfa_shortest modifier is set,  processing  stops
-       after  the  first  match is found. This is always the shortest possible
+       If  the dfa modifier is set, the alternative matching function is used.
+       This function finds all possible matches at a given point in  the  sub-
+       ject.  If,  however, the dfa_shortest modifier is set, processing stops
+       after the first match is found. This is always  the  shortest  possible
        match.
 
 
 DEFAULT OUTPUT FROM pcre2test
 
-       This section describes the output when the  normal  matching  function,
+       This  section  describes  the output when the normal matching function,
        pcre2_match(), is being used.
 
-       When  a  match  succeeds,  pcre2test  outputs the list of captured sub-
-       strings, starting with number 0 for the string that matched  the  whole
-       pattern.    Otherwise,  it  outputs  "No  match"  when  the  return  is
-       PCRE2_ERROR_NOMATCH, or "Partial  match:"  followed  by  the  partially
-       matching  substring  when the return is PCRE2_ERROR_PARTIAL. (Note that
-       this is the entire substring that  was  inspected  during  the  partial
-       match;  it  may  include  characters before the actual match start if a
+       When a match succeeds, pcre2test outputs  the  list  of  captured  sub-
+       strings,  starting  with number 0 for the string that matched the whole
+       pattern.   Otherwise,  it  outputs  "No  match"  when  the  return   is
+       PCRE2_ERROR_NOMATCH,  or  "Partial  match:"  followed  by the partially
+       matching substring when the return is PCRE2_ERROR_PARTIAL.  (Note  that
+       this  is  the  entire  substring  that was inspected during the partial
+       match; it may include characters before the actual  match  start  if  a
        lookbehind assertion, \K, \b, or \B was involved.)
 
        For any other return, pcre2test outputs the PCRE2 negative error number
-       and  a  short  descriptive  phrase. If the error is a failed UTF string
-       check, the code unit offset of the start of the  failing  character  is
+       and a short descriptive phrase. If the error is  a  failed  UTF  string
+       check,  the  code  unit offset of the start of the failing character is
        also output. Here is an example of an interactive pcre2test run.
 
          $ pcre2test
-         PCRE2 version 9.00 2014-05-10
+         PCRE2 version 10.22 2016-07-29
 
            re> /^abc(\d+)/
          data> abc123
@@ -1260,8 +1426,8 @@
        Unset capturing substrings that are not followed by one that is set are
        not shown by pcre2test unless the allcaptures modifier is specified. In
        the following example, there are two capturing substrings, but when the
-       first data line is matched, the second, unset substring is  not  shown.
-       An  "internal" unset substring is shown as "<unset>", as for the second
+       first  data  line is matched, the second, unset substring is not shown.
+       An "internal" unset substring is shown as "<unset>", as for the  second
        data line.
 
            re> /(a)|(b)/
@@ -1273,11 +1439,11 @@
           1: <unset>
           2: b
 
-       If the strings contain any non-printing characters, they are output  as
-       \xhh  escapes  if  the  value is less than 256 and UTF mode is not set.
+       If  the strings contain any non-printing characters, they are output as
+       \xhh escapes if the value is less than 256 and UTF  mode  is  not  set.
        Otherwise they are output as \x{hh...} escapes. See below for the defi-
-       nition  of  non-printing characters. If the /aftertext modifier is set,
-       the output for substring 0 is followed by the the rest of  the  subject
+       nition of non-printing characters. If the aftertext  modifier  is  set,
+       the  output  for substring 0 is followed by the the rest of the subject
        string, identified by "0+" like this:
 
            re> /cat/aftertext
@@ -1285,7 +1451,7 @@
           0: cat
           0+ aract
 
-       If  global  matching  is  requested, the results of successive matching
+       If global matching is requested, the  results  of  successive  matching
        attempts are output in sequence, like this:
 
            re> /\Bi(\w\w)/g
@@ -1297,8 +1463,8 @@
           0: ipp
           1: pp
 
-       "No match" is output only if the first match attempt fails. Here is  an
-       example  of  a  failure  message (the offset 4 that is specified by the
+       "No  match" is output only if the first match attempt fails. Here is an
+       example of a failure message (the offset 4 that  is  specified  by  the
        offset modifier is past the end of the subject string):
 
            re> /xyz/
@@ -1306,7 +1472,7 @@
          Error -24 (bad offset value)
 
        Note that whereas patterns can be continued over several lines (a plain
-       ">"  prompt  is used for continuations), subject lines may not. However
+       ">" prompt is used for continuations), subject lines may  not.  However
        newlines can be included in a subject by means of the \n escape (or \r,
        \r\n, etc., depending on the newline sequence setting).
 
@@ -1314,7 +1480,7 @@
 OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
 
        When the alternative matching function, pcre2_dfa_match(), is used, the
-       output consists of a list of all the matches that start  at  the  first
+       output  consists  of  a list of all the matches that start at the first
        point in the subject where there is at least one match. For example:
 
            re> /(tang|tangerine|tan)/
@@ -1323,11 +1489,11 @@
           1: tang
           2: tan
 
-       Using  the normal matching function on this data finds only "tang". The
-       longest matching string is always  given  first  (and  numbered  zero).
-       After  a  PCRE2_ERROR_PARTIAL  return,  the output is "Partial match:",
-       followed by the partially matching substring. Note  that  this  is  the
-       entire  substring  that  was inspected during the partial match; it may
+       Using the normal matching function on this data finds only "tang".  The
+       longest  matching  string  is  always  given first (and numbered zero).
+       After a PCRE2_ERROR_PARTIAL return, the  output  is  "Partial  match:",
+       followed  by  the  partially  matching substring. Note that this is the
+       entire substring that was inspected during the partial  match;  it  may
        include characters before the actual match start if a lookbehind asser-
        tion, \b, or \B was involved. (\K is not supported for DFA matching.)
 
@@ -1343,16 +1509,16 @@
           1: tan
           0: tan
 
-       The alternative matching function does not support  substring  capture,
-       so  the  modifiers  that are concerned with captured substrings are not
+       The  alternative  matching function does not support substring capture,
+       so the modifiers that are concerned with captured  substrings  are  not
        relevant.
 
 
 RESTARTING AFTER A PARTIAL MATCH
 
-       When the alternative matching function has given  the  PCRE2_ERROR_PAR-
+       When  the  alternative matching function has given the PCRE2_ERROR_PAR-
        TIAL return, indicating that the subject partially matched the pattern,
-       you can restart the match with additional subject data by means of  the
+       you  can restart the match with additional subject data by means of the
        dfa_restart modifier. For example:
 
            re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
@@ -1361,26 +1527,17 @@
          data> n05\=dfa,dfa_restart
           0: n05
 
-       For  further  information  about partial matching, see the pcre2partial
+       For further information about partial matching,  see  the  pcre2partial
        documentation.
 
 
 CALLOUTS
 
        If the pattern contains any callout requests, pcre2test's callout func-
-       tion  is called during matching unless callout_none is specified.  This
-       works with both matching functions.
-
-       The callout function in pcre2test returns zero (carry on  matching)  by
-       default,  but you can use a callout_fail modifier in a subject line (as
-       described above) to change this and other parameters of the callout.
-
-       Inserting callouts can be helpful when using pcre2test to check compli-
-       cated  regular expressions. For further information about callouts, see
-       the pcre2callout documentation.
-
-       The output for callouts with numerical arguments and those with  string
-       arguments is slightly different.
+       tion is called during matching unless callout_none is  specified.  This
+       works with both matching functions, and with JIT, though there are some
+       differences in behaviour. The output for callouts with numerical  argu-
+       ments and those with string arguments is slightly different.
 
    Callouts with numerical arguments
 
@@ -1399,8 +1556,8 @@
        position, which can happen if the callout is in a lookbehind assertion.
 
        Callouts numbered 255 are assumed to be automatic callouts, inserted as
-       a  result  of the /auto_callout pattern modifier. In this case, instead
-       of showing the callout number, the offset in the pattern, preceded by a
+       a result of the auto_callout pattern modifier. In this case, instead of
+       showing the callout number, the offset in the pattern,  preceded  by  a
        plus, is output. For example:
 
            re> /\d?[A-E]\*/auto_callout
@@ -1451,46 +1608,140 @@
           0: abcdef
 
 
+   Callout modifiers
+
+       The callout function in pcre2test returns zero (carry on  matching)  by
+       default,  but  you can use a callout_fail modifier in a subject line to
+       change this and other parameters of the callout (see below).
+
+       If the callout_capture modifier is set, the current captured groups are
+       output when a callout occurs. This is useful only for non-DFA matching,
+       as pcre2_dfa_match() does not support capturing,  so  no  captures  are
+       ever shown.
+
+       The normal callout output, showing the callout number or pattern offset
+       (as described above) is suppressed if the callout_no_where modifier  is
+       set.
+
+       When  using  the  interpretive  matching function pcre2_match() without
+       JIT, setting the callout_extra modifier causes additional  output  from
+       pcre2test's  callout function to be generated. For the first callout in
+       a match attempt at a new starting position in the subject,  "New  match
+       attempt"  is output. If there has been a backtrack since the last call-
+       out (or start of matching if this is the first callout), "Backtrack" is
+       output,  followed  by  "No other matching paths" if the backtrack ended
+       the previous match attempt. For example:
+
+          re> /(a+)b/auto_callout,no_start_optimize,no_auto_possess
+         data> aac\=callout_extra
+         New match attempt
+         --->aac
+          +0 ^       (
+          +1 ^       a+
+          +3 ^ ^     )
+          +4 ^ ^     b
+         Backtrack
+         --->aac
+          +3 ^^      )
+          +4 ^^      b
+         Backtrack
+         No other matching paths
+         New match attempt
+         --->aac
+          +0  ^      (
+          +1  ^      a+
+          +3  ^^     )
+          +4  ^^     b
+         Backtrack
+         No other matching paths
+         New match attempt
+         --->aac
+          +0   ^     (
+          +1   ^     a+
+         Backtrack
+         No other matching paths
+         New match attempt
+         --->aac
+          +0    ^    (
+          +1    ^    a+
+         No match
+
+       Notice that various optimizations must be turned off if  you  want  all
+       possible  matching  paths  to  be  scanned. If no_start_optimize is not
+       used, there is an immediate "no match", without any  callouts,  because
+       the  starting  optimization  fails to find "b" in the subject, which it
+       knows must be present for any match. If no_auto_possess  is  not  used,
+       the  "a+"  item is turned into "a++", which reduces the number of back-
+       tracks.
+
+       The callout_extra modifier has no effect if used with the DFA  matching
+       function, or with JIT.
+
+   Return values from callouts
+
+       The  default  return  from  the  callout function is zero, which allows
+       matching to continue. The callout_fail modifier can be given one or two
+       numbers. If there is only one number, 1 is returned instead of 0 (caus-
+       ing matching to backtrack) when a callout of that number is reached. If
+       two  numbers  (<n>:<m>)  are  given,  1 is returned when callout <n> is
+       reached and there have been at least <m>  callouts.  The  callout_error
+       modifier is similar, except that PCRE2_ERROR_CALLOUT is returned, caus-
+       ing the entire matching process to be aborted. If both these  modifiers
+       are  set  for  the same callout number, callout_error takes precedence.
+       Note that callouts with string arguments are always  given  the  number
+       zero.
+
+       The  callout_data  modifier can be given an unsigned or a negative num-
+       ber.  This is set as the "user data" that is  passed  to  the  matching
+       function,  and  passed  back  when the callout function is invoked. Any
+       value other than zero is used as  a  return  from  pcre2test's  callout
+       function.
+
+       Inserting callouts can be helpful when using pcre2test to check compli-
+       cated regular expressions. For further information about callouts,  see
+       the pcre2callout documentation.
+
+
 NON-PRINTING CHARACTERS
 
        When pcre2test is outputting text in the compiled version of a pattern,
-       bytes  other  than 32-126 are always treated as non-printing characters
+       bytes other than 32-126 are always treated as  non-printing  characters
        and are therefore shown as hex escapes.
 
-       When pcre2test is outputting text that is a matched part of  a  subject
-       string,  it behaves in the same way, unless a different locale has been
-       set for the pattern (using the /locale modifier).  In  this  case,  the
-       isprint()  function  is  used  to distinguish printing and non-printing
+       When  pcre2test  is outputting text that is a matched part of a subject
+       string, it behaves in the same way, unless a different locale has  been
+       set  for  the  pattern  (using  the locale modifier). In this case, the
+       isprint() function is used to  distinguish  printing  and  non-printing
        characters.
 
 
 SAVING AND RESTORING COMPILED PATTERNS
 
-       It is possible to save compiled patterns  on  disc  or  elsewhere,  and
+       It  is  possible  to  save  compiled patterns on disc or elsewhere, and
        reload them later, subject to a number of restrictions. JIT data cannot
-       be saved. The host on which the patterns are reloaded must  be  running
+       be  saved.  The host on which the patterns are reloaded must be running
        the same version of PCRE2, with the same code unit width, and must also
-       have the same endianness, pointer width  and  PCRE2_SIZE  type.  Before
-       compiled  patterns  can be saved they must be serialized, that is, con-
-       verted to a stream of bytes. A single byte stream may contain any  num-
-       ber  of  compiled  patterns,  but  they must all use the same character
+       have  the  same  endianness,  pointer width and PCRE2_SIZE type. Before
+       compiled patterns can be saved they must be serialized, that  is,  con-
+       verted  to a stream of bytes. A single byte stream may contain any num-
+       ber of compiled patterns, but they must  all  use  the  same  character
        tables. A single copy of the tables is included in the byte stream (its
        size is 1088 bytes).
 
-       The  functions  whose  names  begin  with pcre2_serialize_ are used for
-       serializing and de-serializing. They are described in the  pcre2serial-
+       The functions whose names begin  with  pcre2_serialize_  are  used  for
+       serializing  and de-serializing. They are described in the pcre2serial-
        ize  documentation.  In  this  section  we  describe  the  features  of
        pcre2test that can be used to test these functions.
 
-       When a pattern with push  modifier  is  successfully  compiled,  it  is
-       pushed  onto  a  stack  of compiled patterns, and pcre2test expects the
-       next line to contain a new pattern (or command) instead  of  a  subject
-       line.  By contrast, the pushcopy modifier causes a copy of the compiled
-       pattern to be stacked, leaving the  original  available  for  immediate
-       matching.  By  using  push and/or pushcopy, a number of patterns can be
+       When  a  pattern  with  push  modifier  is successfully compiled, it is
+       pushed onto a stack of compiled patterns,  and  pcre2test  expects  the
+       next  line  to  contain a new pattern (or command) instead of a subject
+       line. By contrast, the pushcopy modifier causes a copy of the  compiled
+       pattern  to  be  stacked,  leaving the original available for immediate
+       matching. By using push and/or pushcopy, a number of  patterns  can  be
        compiled and retained. These modifiers are incompatible with posix, and
-       control  modifiers  that act at match time are ignored (with a message)
-       for the stacked patterns. The jitverify modifier applies only  at  com-
+       control modifiers that act at match time are ignored (with  a  message)
+       for  the  stacked patterns. The jitverify modifier applies only at com-
        pile time.
 
        The command
@@ -1498,21 +1749,21 @@
          #save <filename>
 
        causes all the stacked patterns to be serialized and the result written
-       to the named file. Afterwards, all the stacked patterns are freed.  The
+       to  the named file. Afterwards, all the stacked patterns are freed. The
        command
 
          #load <filename>
 
-       reads  the  data in the file, and then arranges for it to be de-serial-
-       ized, with the resulting compiled patterns added to the pattern  stack.
-       The  pattern  on the top of the stack can be retrieved by the #pop com-
-       mand, which must be followed by  lines  of  subjects  that  are  to  be
-       matched  with  the pattern, terminated as usual by an empty line or end
-       of file. This command may be followed by  a  modifier  list  containing
-       only  control  modifiers that act after a pattern has been compiled. In
+       reads the data in the file, and then arranges for it to  be  de-serial-
+       ized,  with the resulting compiled patterns added to the pattern stack.
+       The pattern on the top of the stack can be retrieved by the  #pop  com-
+       mand,  which  must  be  followed  by  lines  of subjects that are to be
+       matched with the pattern, terminated as usual by an empty line  or  end
+       of  file.  This  command  may be followed by a modifier list containing
+       only control modifiers that act after a pattern has been  compiled.  In
        particular,  hex,  posix,  posix_nosub,  push,  and  pushcopy  are  not
-       allowed,  nor are any option-setting modifiers.  The JIT modifiers are,
-       however permitted. Here is an example that saves and reloads  two  pat-
+       allowed, nor are any option-setting modifiers.  The JIT modifiers  are,
+       however  permitted.  Here is an example that saves and reloads two pat-
        terns.
 
          /abc/push
@@ -1525,10 +1776,10 @@
          #pop jit,bincode
          abc
 
-       If  jitverify  is  used with #pop, it does not automatically imply jit,
+       If jitverify is used with #pop, it does not  automatically  imply  jit,
        which is different behaviour from when it is used on a pattern.
 
-       The #popcopy command is analagous to the pushcopy modifier in  that  it
+       The  #popcopy  command is analagous to the pushcopy modifier in that it
        makes current a copy of the topmost stack pattern, leaving the original
        still on the stack.
 
@@ -1548,5 +1799,5 @@
 
 REVISION
 
-       Last updated: 06 July 2016
-       Copyright (c) 1997-2016 University of Cambridge.
+       Last updated: 21 December 2017
+       Copyright (c) 1997-2017 University of Cambridge.
diff --git a/dist2/doc/pcre2unicode.3 b/dist2/doc/pcre2unicode.3
index 253d4b6..813fadf 100644
--- a/dist2/doc/pcre2unicode.3
+++ b/dist2/doc/pcre2unicode.3
@@ -1,4 +1,4 @@
-.TH PCRE2UNICODE 3 "03 July 2016" "PCRE2 10.22"
+.TH PCRE2UNICODE 3 "17 May 2017" "PCRE2 10.30"
 .SH NAME
 PCRE - Perl-compatible regular expressions (revised API)
 .SH "UNICODE AND UTF SUPPORT"
@@ -40,7 +40,7 @@
 documentation. Only the short names for properties are supported. For example,
 \ep{L} matches a letter. Its Perl synonym, \ep{Letter}, is not supported.
 Furthermore, in Perl, many properties may optionally be prefixed by "Is", for
-compatibility with Perl 5.6. PCRE does not support this.
+compatibility with Perl 5.6. PCRE2 does not support this.
 .
 .
 .SH "WIDE CHARACTERS AND UTF MODES"
@@ -101,10 +101,16 @@
 However, the special horizontal and vertical white space matching escapes (\eh,
 \eH, \ev, and \eV) do match all the appropriate Unicode characters, whether or
 not PCRE2_UCP is set.
-.P
-Case-insensitive matching in UTF mode makes use of Unicode properties. A few
-Unicode characters such as Greek sigma have more than two codepoints that are
-case-equivalent, and these are treated as such.
+.
+.
+.SH "CASE-EQUIVALENCE IN UTF MODES"
+.rs
+.sp
+Case-insensitive matching in a UTF mode makes use of Unicode properties except
+for characters whose code points are less than 128 and that have at most two
+case-equivalent values. For these, a direct table lookup is used for speed. A
+few Unicode characters such as Greek sigma have more than two codepoints that
+are case-equivalent, and these are treated as such.
 .
 .
 .SH "VALIDITY OF UTF STRINGS"
@@ -158,6 +164,14 @@
 .P
 If you pass an invalid UTF string when PCRE2_NO_UTF_CHECK is set, the result
 is undefined and your program may crash or loop indefinitely.
+.P
+Note that setting PCRE2_NO_UTF_CHECK at compile time does not disable the error
+that is given if an escape sequence for an invalid Unicode code point is
+encountered in the pattern. If you want to allow escape sequences such as
+\ex{d800} (a surrogate code point) you can set the
+PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES extra option. However, this is possible
+only in UTF-8 and UTF-32 modes, because these values are not representable in
+UTF-16.
 .
 .
 .\" HTML <a name="utf8strings"></a>
@@ -266,6 +280,6 @@
 .rs
 .sp
 .nf
-Last updated: 03 July 2016
-Copyright (c) 1997-2016 University of Cambridge.
+Last updated: 17 May 2017
+Copyright (c) 1997-2017 University of Cambridge.
 .fi
diff --git a/dist2/install-sh b/dist2/install-sh
index 0b0fdcb..0360b79 100755
--- a/dist2/install-sh
+++ b/dist2/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2013-12-25.23; # UTC
+scriptversion=2016-01-11.22; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -496,6 +496,6 @@
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/dist2/ltmain.sh b/dist2/ltmain.sh
index 0f0a2da..857338f 100644
--- a/dist2/ltmain.sh
+++ b/dist2/ltmain.sh
@@ -1,12 +1,12 @@
 #! /bin/sh
 ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-##               by inline-source v2014-01-03.01
+##               by inline-source v2016-02-21.11
 
-# libtool (GNU libtool) 2.4.6
+# libtool (GNU libtool) 2.4.6.40-6ca5-dirty
 # Provide generalized library-building support services.
 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -31,8 +31,8 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION=2.4.6
-package_revision=2.4.6
+VERSION=2.4.6.40-6ca5-dirty
+package_revision=2.4.6.40
 
 
 ## ------ ##
@@ -64,34 +64,25 @@
 # libraries, which are installed to $pkgauxdir.
 
 # Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2017-04-19.12; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
 
-# Copyright (C) 2004-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Copyright (C) 2004-2017 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# <https://opensource.org/license/MIT>, and GPL version 3 or later
+# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
 
 ## ------ ##
@@ -140,9 +131,6 @@
 	fi"
 done
 
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
 # Make sure IFS has a sensible default
 sp=' '
 nl='
@@ -159,6 +147,26 @@
 fi
 
 
+# func_unset VAR
+# --------------
+# Portably unset VAR.
+# In some shells, an 'unset VAR' statement leaves a non-zero return
+# status if VAR is already unset, which might be problematic if the
+# statement is used at the end of a function (thus poisoning its return
+# value) or when 'set -e' is active (causing even a spurious abort of
+# the script in this case).
+func_unset ()
+{
+    { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }
+}
+
+
+# Make sure CDPATH doesn't cause `cd` commands to output the target dir.
+func_unset CDPATH
+
+# Make sure ${,E,F}GREP behave sanely.
+func_unset GREP_OPTIONS
+
 
 ## ------------------------- ##
 ## Locate command utilities. ##
@@ -259,7 +267,7 @@
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+  func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"
   rm -f conftest.sed
   SED=$func_path_progs_result
 }
@@ -295,7 +303,7 @@
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+  func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"
   GREP=$func_path_progs_result
 }
 
@@ -580,16 +588,16 @@
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1+=\\ \$func_quote_arg_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1=\$$1\\ \$func_quote_arg_result"
   }
 fi
 
@@ -1091,85 +1099,199 @@
 }
 
 
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
+# func_quote_portable EVAL ARG
+# ----------------------------
+# Internal function to portably implement func_quote_arg.  Note that we still
+# keep attention to performance here so we as much as possible try to avoid
+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
+func_quote_portable ()
 {
     $debug_cmd
 
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
+    func_quote_portable_result=$2
+
+    # one-time-loop (easy break)
+    while true
+    do
+      if $1; then
+        func_quote_portable_result=`$ECHO "$2" | $SED \
+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
+        break
+      fi
+
+      # Quote for eval.
+      case $func_quote_portable_result in
         *[\\\`\"\$]*)
-	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
-      fi
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
+                  | $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
 
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
+          func_quote_portable_old_IFS=$IFS
+          for _G_char in '\' '`' '"' '$'
+          do
+            # STATE($1) PREV($2) SEPARATOR($3)
+            set start "" ""
+            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
+            IFS=$_G_char
+            for _G_part in $func_quote_portable_result
+            do
+              case $1 in
+              quote)
+                func_append func_quote_portable_result "$3$2"
+                set quote "$_G_part" "\\$_G_char"
+                ;;
+              start)
+                set first "" ""
+                func_quote_portable_result=
+                ;;
+              first)
+                set quote "$_G_part" ""
+                ;;
+              esac
+            done
+          done
+          IFS=$func_quote_portable_old_IFS
           ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-	  ;;
+        *) ;;
       esac
-
-      if test -n "$func_quote_for_eval_result"; then
-	func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
+      break
     done
+
+    func_quote_portable_unquoted_result=$func_quote_portable_result
+    case $func_quote_portable_result in
+      # double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and variable expansion
+      # for a subsequent eval.
+      # many bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_portable_result=\"$func_quote_portable_result\"
+        ;;
+    esac
 }
 
 
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
+# func_quotefast_eval ARG
+# -----------------------
+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
+# but optimized for speed.  Result is stored in $func_quotefast_eval.
+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
+  printf -v _GL_test_printf_tilde %q '~'
+  if test '\~' = "$_GL_test_printf_tilde"; then
+    func_quotefast_eval ()
+    {
+      printf -v func_quotefast_eval_result %q "$1"
+    }
+  else
+    # Broken older Bash implementations.  Make those faster too if possible.
+    func_quotefast_eval ()
+    {
+      case $1 in
+        '~'*)
+          func_quote_portable false "$1"
+          func_quotefast_eval_result=$func_quote_portable_result
+          ;;
+        *)
+          printf -v func_quotefast_eval_result %q "$1"
+          ;;
+      esac
+    }
+  fi
+else
+  func_quotefast_eval ()
+  {
+    func_quote_portable false "$1"
+    func_quotefast_eval_result=$func_quote_portable_result
+  }
+fi
+
+
+# func_quote_arg MODEs ARG
+# ------------------------
+# Quote one ARG to be evaled later.  MODEs argument may contain zero or more
+# specifiers listed below separated by ',' character.  This function returns two
+# values:
+#   i) func_quote_arg_result
+#      double-quoted (when needed), suitable for a subsequent eval
+#  ii) func_quote_arg_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.  Available only if 'unquoted' is specified.
+#
+# Available modes:
+# ----------------
+# 'eval' (default)
+#       - escape shell special characters
+# 'expand'
+#       - the same as 'eval';  but do not quote variable references
+# 'pretty'
+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
+#         be used later in func_quote to get output like: 'echo "a b"' instead
+#         of 'echo a\ b'.  This is slower than default on some shells.
+# 'unquoted'
+#       - produce also $func_quote_arg_unquoted_result which does not contain
+#         wrapping double-quotes.
+#
+# Examples for 'func_quote_arg pretty,unquoted string':
+#
+#   string      | *_result              | *_unquoted_result
+#   ------------+-----------------------+-------------------
+#   "           | \"                    | \"
+#   a b         | "a b"                 | a b
+#   "a b"       | "\"a b\""             | \"a b\"
+#   *           | "*"                   | *
+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
+#
+# Examples for 'func_quote_arg pretty,unquoted,expand string':
+#
+#   string        |   *_result          |  *_unquoted_result
+#   --------------+---------------------+--------------------
+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
+func_quote_arg ()
 {
-    $debug_cmd
-
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
-    esac
-
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-        _G_arg=\"$_G_arg\"
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
         ;;
     esac
 
-    func_quote_for_expand_result=$_G_arg
+    case ,$1, in
+      *,pretty,*|*,expand,*|*,unquoted,*)
+        func_quote_portable $_G_quote_expand "$2"
+        func_quote_arg_result=$func_quote_portable_result
+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
+        ;;
+      *)
+        # Faster quote-for-eval for some shells.
+        func_quotefast_eval "$2"
+        func_quote_arg_result=$func_quotefast_eval_result
+        ;;
+    esac
+}
+
+
+# func_quote MODEs ARGs...
+# ------------------------
+# Quote all ARGs to be evaled later and join them into single command.  See
+# func_quote_arg's description for more info.
+func_quote ()
+{
+    $debug_cmd
+    _G_func_quote_mode=$1 ; shift
+    func_quote_result=
+    while test 0 -lt $#; do
+      func_quote_arg "$_G_func_quote_mode" "$1"
+      if test -n "$func_quote_result"; then
+        func_append func_quote_result " $func_quote_arg_result"
+      else
+        func_append func_quote_result "$func_quote_arg_result"
+      fi
+      shift
+    done
 }
 
 
@@ -1215,8 +1337,8 @@
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
+    func_quote_arg pretty,expand "$_G_cmd"
+    eval "func_notquiet $func_quote_arg_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1241,8 +1363,8 @@
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
+      func_quote_arg expand,pretty "$_G_cmd"
+      eval "func_echo $func_quote_arg_result"
     }
 
     $opt_dry_run || {
@@ -1369,30 +1491,26 @@
 # End:
 #! /bin/sh
 
-# Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
-
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
 
-# Copyright (C) 2010-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Copyright (C) 2010-2017 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# <https://opensource.org/license/MIT>, and GPL version 3 or later
+# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
+# Set a version string for this script.
+scriptversion=2016-03-06.01; # UTC
 
 
 ## ------ ##
@@ -1415,7 +1533,7 @@
 #
 # In order for the '--version' option to work, you will need to have a
 # suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
+# starting with '# Written by ' and ending with '# Copyright'.
 #
 # For '-h' and '--help' to work, you will also need a one line
 # description of your script's purpose in a comment directly above the
@@ -1427,7 +1545,7 @@
 # to display verbose messages only when your user has specified
 # '--verbose'.
 #
-# After sourcing this file, you can plug processing for additional
+# After sourcing this file, you can plug in processing for additional
 # options by amending the variables from the 'Configuration' section
 # below, and following the instructions in the 'Option parsing'
 # section further down.
@@ -1476,8 +1594,8 @@
 ## ------------------------- ##
 
 # This section contains functions for adding, removing, and running hooks
-# to the main code.  A hook is just a named list of of function, that can
-# be run in order later on.
+# in the main code.  A hook is just a list of function names that can be
+# run in order later on.
 
 # func_hookable FUNC_NAME
 # -----------------------
@@ -1510,7 +1628,8 @@
 
 # func_remove_hook FUNC_NAME HOOK_FUNC
 # ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+# Remove HOOK_FUNC from the list of hook functions to be called by
+# FUNC_NAME.
 func_remove_hook ()
 {
     $debug_cmd
@@ -1519,10 +1638,28 @@
 }
 
 
+# func_propagate_result FUNC_NAME_A FUNC_NAME_B
+# ---------------------------------------------
+# If the *_result variable of FUNC_NAME_A _is set_, assign its value to
+# *_result variable of FUNC_NAME_B.
+func_propagate_result ()
+{
+    $debug_cmd
+
+    func_propagate_result_result=:
+    if eval "test \"\${${1}_result+set}\" = set"
+    then
+      eval "${2}_result=\$${1}_result"
+    else
+      func_propagate_result_result=false
+    fi
+}
+
+
 # func_run_hooks FUNC_NAME [ARG]...
 # ---------------------------------
 # Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
+# It's assumed that the list of hook functions contains nothing more
 # than a whitespace-delimited list of legal shell function names, and
 # no effort is wasted trying to catch shell meta-characters or preserve
 # whitespace.
@@ -1532,22 +1669,19 @@
 
     case " $hookable_fns " in
       *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+      *) func_fatal_error "'$1' does not support hook functions." ;;
     esac
 
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
+      func_unset "${_G_hook}_result"
+      eval $_G_hook '${1+"$@"}'
+      func_propagate_result $_G_hook func_run_hooks
+      if $func_propagate_result_result; then
+        eval set dummy "$func_run_hooks_result"; shift
+      fi
     done
-
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
 }
 
 
@@ -1557,10 +1691,18 @@
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
+# full positional parameter list from your hook function.  You may remove
+# or edit any options that you action, and then pass back the remaining
+# unprocessed options in '<hooked_function_name>_result', escaped
+# suitably for 'eval'.
+#
+# The '<hooked_function_name>_result' variable is automatically unset
+# before your hook gets called; for best performance, only set the
+# *_result variable when necessary (i.e. don't call the 'func_quote'
+# function unnecessarily because it can be an expensive operation on some
+# machines).
+#
+# Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1570,9 +1712,8 @@
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
+#        # No change in '$@' (ignored completely by this hook).  Leave
+#        # my_options_prep_result variable intact.
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1581,25 +1722,36 @@
 #    {
 #        $debug_cmd
 #
-#        # Note that for efficiency, we parse as many options as we can
+#        args_changed=false
+#
+#        # Note that, for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=: ;;
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
+#                         args_changed=:
 #                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@" in case we need it later,
+#                         # if $args_changed was set to 'true'.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
+#        # Only call 'func_quote' here if we processed at least one argument.
+#        if $args_changed; then
+#          func_quote eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_result
+#        fi
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1610,17 +1762,26 @@
 #
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll alse need to manually amend $usage_message to reflect the extra
+# You'll also need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    func_run_hooks func_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_options_finish
+}
+
+
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1630,17 +1791,27 @@
 {
     $debug_cmd
 
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
+    _G_options_quoted=false
 
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      func_unset func_${my_func}_result
+      func_unset func_run_hooks_result
+      eval func_$my_func '${1+"$@"}'
+      func_propagate_result func_$my_func func_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_options_result"; shift
+        _G_options_quoted=:
+      fi
+    done
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    $_G_options_quoted || {
+      # As we (func_options) are top-level options-parser function and
+      # nobody quoted "$@" for us yet, we need to do it explicitly for
+      # caller.
+      func_quote eval ${1+"$@"}
+      func_options_result=$func_quote_result
+    }
 }
 
 
@@ -1649,9 +1820,8 @@
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning.
+# needs to propagate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before returning.
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1662,9 +1832,7 @@
     opt_warning_types=
 
     func_run_hooks func_options_prep ${1+"$@"}
-
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    func_propagate_result func_run_hooks func_options_prep
 }
 
 
@@ -1676,25 +1844,32 @@
 {
     $debug_cmd
 
-    func_parse_options_result=
-
+    _G_parse_options_requote=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
       func_run_hooks func_parse_options ${1+"$@"}
-
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+      func_propagate_result func_run_hooks func_parse_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_parse_options_result"; shift
+        # Even though we may have changed "$@", we passed the "$@" array
+        # down into the hook and it quoted it for us (because we are in
+        # this if-branch).  No need to quote it again.
+        _G_parse_options_requote=false
+      fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      # We expect that one of the options parsed in this function matches
+      # and thus we remove _G_opt from "$@" and need to re-quote.
+      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
         --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
+                      func_echo "enabling shell trace mode" >&2
                       $debug_cmd
                       ;;
 
@@ -1704,7 +1879,10 @@
 		      ;;
 
         --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_parse_options_requote=:
+                        break
+                      fi
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1757,15 +1935,24 @@
                       shift
                       ;;
 
-        --)           break ;;
+        --)           _G_parse_options_requote=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
       esac
+
+      if $_G_match_parse_options; then
+        _G_parse_options_requote=:
+      fi
     done
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+    if $_G_parse_options_requote; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      func_parse_options_result=$func_quote_result
+    fi
 }
 
 
@@ -1782,12 +1969,10 @@
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
     func_run_hooks func_validate_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_validate_options
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
-
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
 }
 
 
@@ -1843,8 +2028,8 @@
 
 # func_split_equals STRING
 # ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables
+# after splitting STRING at the '=' sign.
 test -z "$_G_HAVE_XSI_OPS" \
     && (eval 'x=a/b/c;
       test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
@@ -1859,8 +2044,9 @@
 
       func_split_equals_lhs=${1%%=*}
       func_split_equals_rhs=${1#*=}
-      test "x$func_split_equals_lhs" = "x$1" \
-        && func_split_equals_rhs=
+      if test "x$func_split_equals_lhs" = "x$1"; then
+        func_split_equals_rhs=
+      fi
   }'
 else
   # ...otherwise fall back to using expr, which is often a shell builtin.
@@ -1938,31 +2124,44 @@
 # func_version
 # ------------
 # Echo version message to standard output and exit.
+# The version message is extracted from the calling file's header
+# comments, with leading '# ' stripped:
+#   1. First display the progname and version
+#   2. Followed by the header comment line matching  /^# Written by /
+#   3. Then a blank line followed by the first following line matching
+#      /^# Copyright /
+#   4. Immediately followed by any lines between the previous matches,
+#      except lines preceding the intervening completely blank line.
+# For example, see the header comments of this file.
 func_version ()
 {
     $debug_cmd
 
     printf '%s\n' "$progname $scriptversion"
     $SED -n '
-        /(C)/!b go
-        :more
-        /\./!{
-          N
-          s|\n# | |
-          b more
+        /^# Written by /!b
+        s|^# ||; p; n
+
+        :fwd2blnk
+        /./ {
+          n
+          b fwd2blnk
         }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
+        p; n
+
+        :holdwrnt
+        s|^# ||
+        s|^# *$||
+        /^Copyright /!{
+          /./H
+          n
+          b holdwrnt
         }
-        /^# Written by / {
-          s|^# ||
-          p
-        }
-        /^warranty; /q' < "$progpath"
+
+        s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+        G
+        s|\(\n\)\n*|\1|g
+        p; q' < "$progpath"
 
     exit $?
 }
@@ -1977,7 +2176,7 @@
 # End:
 
 # Set a version string.
-scriptversion='(GNU libtool) 2.4.6'
+scriptversion='(GNU libtool) 2.4.6.40-6ca5-dirty'
 
 
 # func_echo ARG...
@@ -2068,12 +2267,12 @@
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6
+       version:        $progname (GNU libtool) 2.4.6.40-6ca5-dirty
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
 Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+GNU libtool home page: <http://www.gnu.org/s/libtool/>.
 General help using GNU software: <http://www.gnu.org/gethelp/>."
     exit 0
 }
@@ -2124,7 +2323,7 @@
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
+    func_fatal_error ${1+"$@"} \
       "See the $PACKAGE documentation for more information." \
       "Fatal configuration error."
 }
@@ -2270,6 +2469,8 @@
     nonopt=
     preserve_args=
 
+    _G_rc_lt_options_prep=:
+
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -2293,11 +2494,16 @@
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
+    *)
+      _G_rc_lt_options_prep=false
+      ;;
     esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
+    if $_G_rc_lt_options_prep; then
+      # Pass back the list of options.
+      func_quote eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_result
+    fi
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2309,9 +2515,12 @@
 {
     $debug_cmd
 
+    _G_rc_lt_parse_options=false
+
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
+      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -2386,15 +2595,20 @@
                         func_append preserve_args " $_G_opt"
                         ;;
 
-	# An option not handled by this hook function:
-        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
+        # An option not handled by this hook function:
+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
+                        _G_match_lt_parse_options=false
+                        break
+                        ;;
       esac
+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
-
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
+    if $_G_rc_lt_parse_options; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_result
+    fi
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -2451,8 +2665,8 @@
     }
 
     # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options libtool_validate_options
 
@@ -3418,8 +3632,8 @@
       esac
     done
 
-    func_quote_for_eval "$libobj"
-    test "X$libobj" != "X$func_quote_for_eval_result" \
+    func_quote_arg pretty "$libobj"
+    test "X$libobj" != "X$func_quote_arg_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
       && func_warning "libobj name '$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
@@ -3492,8 +3706,8 @@
 
     func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
     srcfile=$func_to_tool_file_result
-    func_quote_for_eval "$srcfile"
-    qsrcfile=$func_quote_for_eval_result
+    func_quote_arg pretty "$srcfile"
+    qsrcfile=$func_quote_arg_result
 
     # Only build a PIC object if we are building libtool libraries.
     if test yes = "$build_libtool_libs"; then
@@ -4096,8 +4310,8 @@
        case $nonopt in *shtool*) :;; *) false;; esac
     then
       # Aesthetically quote it.
-      func_quote_for_eval "$nonopt"
-      install_prog="$func_quote_for_eval_result "
+      func_quote_arg pretty "$nonopt"
+      install_prog="$func_quote_arg_result "
       arg=$1
       shift
     else
@@ -4107,8 +4321,8 @@
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
-    func_quote_for_eval "$arg"
-    func_append install_prog "$func_quote_for_eval_result"
+    func_quote_arg pretty "$arg"
+    func_append install_prog "$func_quote_arg_result"
     install_shared_prog=$install_prog
     case " $install_prog " in
       *[\\\ /]cp\ *) install_cp=: ;;
@@ -4165,12 +4379,12 @@
       esac
 
       # Aesthetically quote the argument.
-      func_quote_for_eval "$arg"
-      func_append install_prog " $func_quote_for_eval_result"
+      func_quote_arg pretty "$arg"
+      func_append install_prog " $func_quote_arg_result"
       if test -n "$arg2"; then
-	func_quote_for_eval "$arg2"
+	func_quote_arg pretty "$arg2"
       fi
-      func_append install_shared_prog " $func_quote_for_eval_result"
+      func_append install_shared_prog " $func_quote_arg_result"
     done
 
     test -z "$install_prog" && \
@@ -4181,8 +4395,8 @@
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
-	func_quote_for_eval "$install_override_mode"
-	func_append install_shared_prog " -m $func_quote_for_eval_result"
+	func_quote_arg pretty "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_arg_result"
       fi
     fi
 
@@ -4478,8 +4692,8 @@
 	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
 	        $opt_quiet || {
-	          func_quote_for_expand "$relink_command"
-		  eval "func_echo $func_quote_for_expand_result"
+	          func_quote_arg expand,pretty "$relink_command"
+		  eval "func_echo $func_quote_arg_result"
 	        }
 	        if eval "$relink_command"; then :
 	          else
@@ -5258,7 +5472,8 @@
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
     file=\"\$0\""
 
-    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    func_quote_arg pretty "$ECHO"
+    qECHO=$func_quote_arg_result
     $ECHO "\
 
 # A function that is used when there is no print builtin or printf.
@@ -5268,7 +5483,7 @@
 \$1
 _LTECHO_EOF'
 }
-    ECHO=\"$qECHO\"
+    ECHO=$qECHO
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6611,9 +6826,9 @@
     while test "$#" -gt 0; do
       arg=$1
       shift
-      func_quote_for_eval "$arg"
-      qarg=$func_quote_for_eval_unquoted_result
-      func_append libtool_args " $func_quote_for_eval_result"
+      func_quote_arg pretty,unquoted "$arg"
+      qarg=$func_quote_arg_unquoted_result
+      func_append libtool_args " $func_quote_arg_result"
 
       # If the previous option needs an argument, assign it.
       if test -n "$prev"; then
@@ -7211,9 +7426,9 @@
 	save_ifs=$IFS; IFS=,
 	for flag in $args; do
 	  IFS=$save_ifs
-          func_quote_for_eval "$flag"
-	  func_append arg " $func_quote_for_eval_result"
-	  func_append compiler_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+	  func_append arg " $func_quote_arg_result"
+	  func_append compiler_flags " $func_quote_arg_result"
 	done
 	IFS=$save_ifs
 	func_stripname ' ' '' "$arg"
@@ -7227,10 +7442,10 @@
 	save_ifs=$IFS; IFS=,
 	for flag in $args; do
 	  IFS=$save_ifs
-          func_quote_for_eval "$flag"
-	  func_append arg " $wl$func_quote_for_eval_result"
-	  func_append compiler_flags " $wl$func_quote_for_eval_result"
-	  func_append linker_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+	  func_append arg " $wl$func_quote_arg_result"
+	  func_append compiler_flags " $wl$func_quote_arg_result"
+	  func_append linker_flags " $func_quote_arg_result"
 	done
 	IFS=$save_ifs
 	func_stripname ' ' '' "$arg"
@@ -7254,8 +7469,8 @@
 
       # -msg_* for osf cc
       -msg_*)
-	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7272,12 +7487,16 @@
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
+      # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -fuse-ld=*           Linker select flags for GCC
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
-        func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+      -specs=*|-fsanitize=*|-fuse-ld=*)
+        func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
@@ -7298,15 +7517,15 @@
 	  continue
         else
 	  # Otherwise treat like 'Some other compiler flag' below
-	  func_quote_for_eval "$arg"
-	  arg=$func_quote_for_eval_result
+	  func_quote_arg pretty "$arg"
+	  arg=$func_quote_arg_result
         fi
 	;;
 
       # Some other compiler flag.
       -* | +*)
-        func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+        func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
 
       *.$objext)
@@ -7426,8 +7645,8 @@
       *)
 	# Unknown arguments in both finalize_command and compile_command need
 	# to be aesthetically quoted because they are evaled later.
-	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
       esac # arg
 
@@ -9933,8 +10152,8 @@
 	    for cmd in $concat_cmds; do
 	      IFS=$save_ifs
 	      $opt_quiet || {
-		  func_quote_for_expand "$cmd"
-		  eval "func_echo $func_quote_for_expand_result"
+		  func_quote_arg expand,pretty "$cmd"
+		  eval "func_echo $func_quote_arg_result"
 	      }
 	      $opt_dry_run || eval "$cmd" || {
 		lt_exit=$?
@@ -10027,8 +10246,8 @@
 	  eval cmd=\"$cmd\"
 	  IFS=$save_ifs
 	  $opt_quiet || {
-	    func_quote_for_expand "$cmd"
-	    eval "func_echo $func_quote_for_expand_result"
+	    func_quote_arg expand,pretty "$cmd"
+	    eval "func_echo $func_quote_arg_result"
 	  }
 	  $opt_dry_run || eval "$cmd" || {
 	    lt_exit=$?
@@ -10502,12 +10721,13 @@
 	  elif eval var_value=\$$var; test -z "$var_value"; then
 	    relink_command="$var=; export $var; $relink_command"
 	  else
-	    func_quote_for_eval "$var_value"
-	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	    func_quote_arg pretty "$var_value"
+	    relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
 	  fi
 	done
-	relink_command="(cd `pwd`; $relink_command)"
-	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+	func_quote eval cd "`pwd`"
+	func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)"
+	relink_command=$func_quote_arg_unquoted_result
       fi
 
       # Only actually do things if not in dry run mode.
@@ -10747,13 +10967,15 @@
 	elif eval var_value=\$$var; test -z "$var_value"; then
 	  relink_command="$var=; export $var; $relink_command"
 	else
-	  func_quote_for_eval "$var_value"
-	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  func_quote_arg pretty,unquoted "$var_value"
+	  relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
 	fi
       done
       # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      func_quote eval cd "`pwd`"
+      relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      func_quote_arg pretty,unquoted "$relink_command"
+      relink_command=$func_quote_arg_unquoted_result
       if test yes = "$hardcode_automatic"; then
 	relink_command=
       fi
diff --git a/dist2/m4/libtool.m4 b/dist2/m4/libtool.m4
index a3bc337..597c604 100644
--- a/dist2/m4/libtool.m4
+++ b/dist2/m4/libtool.m4
@@ -1,6 +1,6 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1996-2001, 2003-2017 Free Software Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -1042,8 +1042,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
-      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
-      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
       echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
       $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
       cat > conftest.c << _LT_EOF
@@ -1493,9 +1493,22 @@
 m4_defun([_LT_PROG_AR],
 [AC_CHECK_TOOLS(AR, [ar], false)
 : ${AR=ar}
-: ${AR_FLAGS=cru}
 _LT_DECL([], [AR], [1], [The archiver])
-_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+# Use ARFLAGS variable as AR's operation code to sync the variable naming with
+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
+# higher priority because thats what people were doing historically (setting
+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
+# variable obsoleted/removed.
+
+test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
+lt_ar_flags=$AR_FLAGS
+_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
+
+# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
+_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
+         [Flags to create an archive])
 
 AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
   [lt_cv_ar_at_file=no
@@ -2207,26 +2220,35 @@
 striplib=
 old_striplib=
 AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  AC_MSG_RESULT([yes])
+if test -z "$STRIP"; then
+  AC_MSG_RESULT([no])
 else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-  darwin*)
-    if test -n "$STRIP"; then
+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+    old_striplib="$STRIP --strip-debug"
+    striplib="$STRIP --strip-unneeded"
+    AC_MSG_RESULT([yes])
+  else
+    case $host_os in
+    darwin*)
+      # FIXME - insert some real tests, host_os isn't really good enough
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       AC_MSG_RESULT([yes])
-    else
+      ;;
+    freebsd*)
+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
+        old_striplib="$STRIP --strip-debug"
+        striplib="$STRIP --strip-unneeded"
+        AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+      fi
+      ;;
+    *)
       AC_MSG_RESULT([no])
-    fi
-    ;;
-  *)
-    AC_MSG_RESULT([no])
-    ;;
-  esac
+      ;;
+    esac
+  fi
 fi
 _LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
 _LT_DECL([], [striplib], [1])
@@ -4919,7 +4941,7 @@
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
       _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
@@ -5156,6 +5178,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
 
     interix[[3-9]]*)
@@ -5373,7 +5396,7 @@
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
 	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
 	else
-	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
@@ -5861,6 +5884,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
 
     osf3*)
@@ -6730,6 +6754,7 @@
 	  emximp -o $lib $output_objdir/$libname.def'
 	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
 	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
 	;;
 
       dgux*)
diff --git a/dist2/m4/ltoptions.m4 b/dist2/m4/ltoptions.m4
index 94b0829..621bd18 100644
--- a/dist2/m4/ltoptions.m4
+++ b/dist2/m4/ltoptions.m4
@@ -1,6 +1,6 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+#   Copyright (C) 2004-2005, 2007-2009, 2011-2017 Free Software
 #   Foundation, Inc.
 #   Written by Gary V. Vaughan, 2004
 #
diff --git a/dist2/m4/ltsugar.m4 b/dist2/m4/ltsugar.m4
index 48bc934..ab69a6b 100644
--- a/dist2/m4/ltsugar.m4
+++ b/dist2/m4/ltsugar.m4
@@ -1,6 +1,6 @@
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Copyright (C) 2004-2005, 2007-2008, 2011-2017 Free Software
 # Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
diff --git a/dist2/m4/ltversion.m4 b/dist2/m4/ltversion.m4
index fa04b52..8250ea4 100644
--- a/dist2/m4/ltversion.m4
+++ b/dist2/m4/ltversion.m4
@@ -1,6 +1,6 @@
 # ltversion.m4 -- version numbers			-*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Copyright (C) 2004, 2011-2017 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
 
 # @configure_input@
 
-# serial 4179 ltversion.m4
+# serial 4219 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.6])
-m4_define([LT_PACKAGE_REVISION], [2.4.6])
+m4_define([LT_PACKAGE_VERSION], [2.4.6.40-6ca5-dirty])
+m4_define([LT_PACKAGE_REVISION], [2.4.6.40])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6'
-macro_revision='2.4.6'
+[macro_version='2.4.6.40-6ca5-dirty'
+macro_revision='2.4.6.40'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
diff --git a/dist2/m4/lt~obsolete.m4 b/dist2/m4/lt~obsolete.m4
index c6b26f8..9919d4d 100644
--- a/dist2/m4/lt~obsolete.m4
+++ b/dist2/m4/lt~obsolete.m4
@@ -1,6 +1,6 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+#   Copyright (C) 2004-2005, 2007, 2009, 2011-2017 Free Software
 #   Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
diff --git a/dist2/missing b/dist2/missing
index f62bbae..c6e3795 100755
--- a/dist2/missing
+++ b/dist2/missing
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2013-10-28.13; # UTC
+scriptversion=2016-01-11.22; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -210,6 +210,6 @@
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/dist2/pcre2-config.in b/dist2/pcre2-config.in
index 932160e..74271c0 100644
--- a/dist2/pcre2-config.in
+++ b/dist2/pcre2-config.in
@@ -86,7 +86,7 @@
       ;;
     --libs-posix)
       if test @enable_pcre2_8@ = yes ; then
-        echo $libS$libR -lpcre2posix -lpcre2-8
+        echo $libS$libR -lpcre2-posix -lpcre2-8
       else
         echo "${usage}" 1>&2
       fi
diff --git a/dist2/perltest.sh b/dist2/perltest.sh
index 9cf7b17..1a7679a 100755
--- a/dist2/perltest.sh
+++ b/dist2/perltest.sh
@@ -1,14 +1,17 @@
 #! /bin/sh
 
 # Script for testing regular expressions with perl to check that PCRE2 handles
-# them the same. The Perl code has to have "use utf8" and "require Encode" at
-# the start when running UTF-8 tests, but *not* for non-utf8 tests. (The
-# "require" would actually be OK for non-utf8-tests, but is not always
-# installed, so this way the script will always run for these tests.)
+# them the same. If the first argument to this script is "-w", Perl is also
+# called with "-w", which turns on its warning mode.
+#
+# The Perl code has to have "use utf8" and "require Encode" at the start when
+# running UTF-8 tests, but *not* for non-utf8 tests. (The "require" would
+# actually be OK for non-utf8-tests, but is not always installed, so this way
+# the script will always run for these tests.)
 #
 # The desired effect is achieved by making this a shell script that passes the
-# Perl script to Perl through a pipe. If the first argument is "-utf8", a
-# suitable prefix is set up.
+# Perl script to Perl through a pipe. If the first argument (possibly after
+# removing "-w") is "-utf8", a suitable prefix is set up.
 #
 # The remaining arguments, if any, are passed to Perl. They are an input file
 # and an output file. If there is one argument, the output is written to
@@ -17,7 +20,14 @@
 # of the contorted piping input.)
 
 perl=perl
+perlarg=''
 prefix=''
+
+if [ $# -gt 0 -a "$1" = "-w" ] ; then
+  perlarg="-w"
+  shift
+fi
+
 if [ $# -gt 0 -a "$1" = "-utf8" ] ; then
   prefix="use utf8; require Encode;"
   shift
@@ -32,13 +42,16 @@
 #   aftertext          interpreted as "print $' afterwards"
 #   afteralltext       ignored
 #   dupnames           ignored (Perl always allows)
+#   jitstack           ignored
 #   mark               ignored
 #   no_auto_possess    ignored
 #   no_start_optimize  ignored
+#   subject_literal    does not process subjects for escapes
 #   ucp                sets Perl's /u modifier
 #   utf                invoke UTF-8 functionality
 #
-# The data lines must not have any pcre2test modifiers. They are processed as
+# The data lines must not have any pcre2test modifiers. Unless
+# "subject_litersl" is on the pattern, data lines are processed as
 # Perl double-quoted strings, so if they contain " $ or @ characters, these
 # have to be escaped. For this reason, all such characters in the
 # Perl-compatible testinput1 and testinput4 files are escaped so that they can
@@ -139,6 +152,10 @@
 
   $showrest = ($mod =~ s/aftertext,?//);
 
+  # The "subject_literal" modifer disables escapes in subjects.
+
+  $subject_literal = ($mod =~ s/subject_literal,?//);
+
   # "allaftertext" is used by pcre2test to print remainders after captures
 
   $mod =~ s/allaftertext,?//;
@@ -151,6 +168,10 @@
 
   $mod =~ s/dupnames,?//;
 
+  # Remove "jitstack".
+
+  $mod =~ s/jitstack=\d+,?//;
+
   # Remove "mark" (asks pcre2test to check MARK data) */
 
   $mod =~ s/mark,?//;
@@ -212,7 +233,14 @@
     last if ($_ eq "");
     next if $_ =~ /^\\=(?:\s|$)/;   # Comment line
 
-    $x = eval "\"$_\"";   # To get escapes processed
+    if ($subject_literal)
+      {
+      $x = $_;
+      }
+    else
+      {
+      $x = eval "\"$_\"";   # To get escapes processed
+      }
 
     # Empty array for holding results, ensure $REGERROR and $REGMARK are
     # unset, then do the matching.
@@ -292,6 +320,6 @@
 # printf $outfile "\n";
 
 PERLEND
-) | $perl - $@
+) | $perl $perlarg - $@
 
 # End
diff --git a/dist2/src/config.h.generic b/dist2/src/config.h.generic
index 8a71be0..f738616 100644
--- a/dist2/src/config.h.generic
+++ b/dist2/src/config.h.generic
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 /* #undef HAVE_MEMORY_H */
 
+/* Define to 1 if you have the `mkostemp' function. */
+/* #undef HAVE_MKOSTEMP */
+
 /* Define if you have POSIX threads libraries and header files. */
 /* #undef HAVE_PTHREAD */
 
@@ -90,6 +93,9 @@
 /* Define to 1 if you have the <readline/readline.h> header file. */
 /* #undef HAVE_READLINE_READLINE_H */
 
+/* Define to 1 if you have the `secure_getenv' function. */
+/* #undef HAVE_SECURE_GETENV */
+
 /* Define to 1 if you have the <stdint.h> header file. */
 /* #undef HAVE_STDINT_H */
 
@@ -126,13 +132,11 @@
 /* Define to 1 if you have the <zlib.h> header file. */
 /* #undef HAVE_ZLIB_H */
 
-/* PCRE2 uses recursive function calls to handle backtracking while matching.
-   This can sometimes be a problem on systems that have stacks of limited
-   size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't
-   use recursion in the match() function; instead it creates its own stack by
-   steam using memory from the heap. For more detail, see the comments and
-   other stuff just above the match() function. */
-/* #undef HEAP_MATCH_RECURSE */
+/* This limits the amount of memory that pcre2_match() may use while matching
+   a pattern. The value is in kilobytes. */
+#ifndef HEAP_LIMIT
+#define HEAP_LIMIT 20000000
+#endif
 
 /* The value of LINK_SIZE determines the number of bytes used to store links
    as offsets within the compiled regex. The default is 2, which allows for
@@ -150,25 +154,25 @@
 #endif
 
 /* The value of MATCH_LIMIT determines the default number of times the
-   internal match() function can be called during a single execution of
-   pcre2_match(). There is a runtime interface for setting a different limit.
-   The limit exists in order to catch runaway regular expressions that take
-   for ever to determine that they do not match. The default is set very large
-   so that it does not accidentally catch legitimate cases. */
+   pcre2_match() function can record a backtrack position during a single
+   matching attempt. There is a runtime interface for setting a different
+   limit. The limit exists in order to catch runaway regular expressions that
+   take for ever to determine that they do not match. The default is set very
+   large so that it does not accidentally catch legitimate cases. */
 #ifndef MATCH_LIMIT
 #define MATCH_LIMIT 10000000
 #endif
 
-/* The above limit applies to all calls of match(), whether or not they
-   increase the recursion depth. In some environments it is desirable to limit
-   the depth of recursive calls of match() more strictly, in order to restrict
-   the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined)
-   that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive
-   calls of match(). To have any useful effect, it must be less than the value
-   of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There
-   is a runtime method for setting a different limit. */
-#ifndef MATCH_LIMIT_RECURSION
-#define MATCH_LIMIT_RECURSION MATCH_LIMIT
+/* The above limit applies to all backtracks, whether or not they are nested.
+   In some environments it is desirable to limit the nesting of backtracking
+   (that is, the depth of tree that is searched) more strictly, in order to
+   restrict the maximum amount of heap memory that is used. The value of
+   MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it
+   must be less than the value of MATCH_LIMIT. The default is to use the same
+   value as MATCH_LIMIT. There is a runtime method for setting a different
+   limit. */
+#ifndef MATCH_LIMIT_DEPTH
+#define MATCH_LIMIT_DEPTH MATCH_LIMIT
 #endif
 
 /* This limit is parameterized just in case anybody ever wants to change it.
@@ -190,8 +194,8 @@
 
 /* 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), and 5
-   (ANYCRLF). */
+   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
@@ -206,7 +210,7 @@
 #define PACKAGE_NAME "PCRE2"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE2 10.22"
+#define PACKAGE_STRING "PCRE2 10.31"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "pcre2"
@@ -215,7 +219,7 @@
 #define PACKAGE_URL ""
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "10.22"
+#define PACKAGE_VERSION "10.31"
 
 /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
    parentheses (of any kind) in a pattern. This limits the amount of system
@@ -224,15 +228,24 @@
 #define PARENS_NEST_LIMIT 250
 #endif
 
-/* The value of PCRE2GREP_BUFSIZE determines the size of buffer used by
-   pcre2grep to hold parts of the file it is searching. This is also the
-   minimum value. The actual amount of memory used by pcre2grep is three times
-   this number, because it allows for the buffering of "before" and "after"
-   lines. */
+/* 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
+
 /* Define to any value to include debugging code. */
 /* #undef PCRE2_DEBUG */
 
@@ -254,6 +267,11 @@
    your system. */
 /* #undef PTHREAD_CREATE_JOINABLE */
 
+/* Define to any non-zero number to enable support for SELinux compatible
+   executable memory allocator in JIT. Note that this will have no effect
+   unless SUPPORT_JIT is also defined. */
+/* #undef SLJIT_PROT_EXECUTABLE_ALLOCATOR */
+
 /* Define to 1 if you have the ANSI C header files. */
 /* #undef STDC_HEADERS */
 
@@ -277,7 +295,8 @@
 /* Define to any value to enable callout script support in pcre2grep. */
 /* #undef SUPPORT_PCRE2GREP_CALLOUT */
 
-/* Define to any value to enable JIT support in pcre2grep. */
+/* Define to any value to enable JIT support in pcre2grep. Note that this will
+   have no effect unless SUPPORT_JIT is also defined. */
 /* #undef SUPPORT_PCRE2GREP_JIT */
 
 /* Define to any value to enable the 16 bit PCRE2 library. */
@@ -298,8 +317,39 @@
 /* Define to any value for valgrind support to find invalid memory reads. */
 /* #undef SUPPORT_VALGRIND */
 
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
 /* Version number of package */
-#define VERSION "10.22"
+#define VERSION "10.31"
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
diff --git a/dist2/src/config.h.in b/dist2/src/config.h.in
index d4821af..7a3a861 100644
--- a/dist2/src/config.h.in
+++ b/dist2/src/config.h.in
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* Define to 1 if you have the `mkostemp' function. */
+#undef HAVE_MKOSTEMP
+
 /* Define if you have POSIX threads libraries and header files. */
 #undef HAVE_PTHREAD
 
@@ -90,6 +93,9 @@
 /* Define to 1 if you have the <readline/readline.h> header file. */
 #undef HAVE_READLINE_READLINE_H
 
+/* Define to 1 if you have the `secure_getenv' function. */
+#undef HAVE_SECURE_GETENV
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
@@ -126,13 +132,9 @@
 /* Define to 1 if you have the <zlib.h> header file. */
 #undef HAVE_ZLIB_H
 
-/* PCRE2 uses recursive function calls to handle backtracking while matching.
-   This can sometimes be a problem on systems that have stacks of limited
-   size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't
-   use recursion in the match() function; instead it creates its own stack by
-   steam using memory from the heap. For more detail, see the comments and
-   other stuff just above the match() function. */
-#undef HEAP_MATCH_RECURSE
+/* This limits the amount of memory that pcre2_match() may use while matching
+   a pattern. The value is in kilobytes. */
+#undef HEAP_LIMIT
 
 /* The value of LINK_SIZE determines the number of bytes used to store links
    as offsets within the compiled regex. The default is 2, which allows for
@@ -145,22 +147,22 @@
 #undef LT_OBJDIR
 
 /* The value of MATCH_LIMIT determines the default number of times the
-   internal match() function can be called during a single execution of
-   pcre2_match(). There is a runtime interface for setting a different limit.
-   The limit exists in order to catch runaway regular expressions that take
-   for ever to determine that they do not match. The default is set very large
-   so that it does not accidentally catch legitimate cases. */
+   pcre2_match() function can record a backtrack position during a single
+   matching attempt. There is a runtime interface for setting a different
+   limit. The limit exists in order to catch runaway regular expressions that
+   take for ever to determine that they do not match. The default is set very
+   large so that it does not accidentally catch legitimate cases. */
 #undef MATCH_LIMIT
 
-/* The above limit applies to all calls of match(), whether or not they
-   increase the recursion depth. In some environments it is desirable to limit
-   the depth of recursive calls of match() more strictly, in order to restrict
-   the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined)
-   that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive
-   calls of match(). To have any useful effect, it must be less than the value
-   of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There
-   is a runtime method for setting a different limit. */
-#undef MATCH_LIMIT_RECURSION
+/* The above limit applies to all backtracks, whether or not they are nested.
+   In some environments it is desirable to limit the nesting of backtracking
+   (that is, the depth of tree that is searched) more strictly, in order to
+   restrict the maximum amount of heap memory that is used. The value of
+   MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it
+   must be less than the value of MATCH_LIMIT. The default is to use the same
+   value as MATCH_LIMIT. There is a runtime method for setting a different
+   limit. */
+#undef MATCH_LIMIT_DEPTH
 
 /* This limit is parameterized just in case anybody ever wants to change it.
    Care must be taken if it is increased, because it guards against integer
@@ -177,8 +179,8 @@
 
 /* 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), and 5
-   (ANYCRLF). */
+   at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5
+   (ANYCRLF), and 6 (NUL). */
 #undef NEWLINE_DEFAULT
 
 /* Name of package */
@@ -207,13 +209,20 @@
    stack that is used while compiling a pattern. */
 #undef PARENS_NEST_LIMIT
 
-/* The value of PCRE2GREP_BUFSIZE determines the size of buffer used by
-   pcre2grep to hold parts of the file it is searching. This is also the
-   minimum value. The actual amount of memory used by pcre2grep is three times
-   this number, because it allows for the buffering of "before" and "after"
-   lines. */
+/* 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. */
 #undef PCRE2GREP_BUFSIZE
 
+/* 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. */
+#undef PCRE2GREP_MAX_BUFSIZE
+
 /* to make a symbol visible */
 #undef PCRE2POSIX_EXP_DECL
 
@@ -245,6 +254,11 @@
    your system. */
 #undef PTHREAD_CREATE_JOINABLE
 
+/* Define to any non-zero number to enable support for SELinux compatible
+   executable memory allocator in JIT. Note that this will have no effect
+   unless SUPPORT_JIT is also defined. */
+#undef SLJIT_PROT_EXECUTABLE_ALLOCATOR
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
@@ -268,7 +282,8 @@
 /* Define to any value to enable callout script support in pcre2grep. */
 #undef SUPPORT_PCRE2GREP_CALLOUT
 
-/* Define to any value to enable JIT support in pcre2grep. */
+/* Define to any value to enable JIT support in pcre2grep. Note that this will
+   have no effect unless SUPPORT_JIT is also defined. */
 #undef SUPPORT_PCRE2GREP_JIT
 
 /* Define to any value to enable the 16 bit PCRE2 library. */
@@ -289,9 +304,41 @@
 /* Define to any value for valgrind support to find invalid memory reads. */
 #undef SUPPORT_VALGRIND
 
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
 /* Version number of package */
 #undef VERSION
 
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
diff --git a/dist2/src/pcre2.h.generic b/dist2/src/pcre2.h.generic
index 20d221b..fffcc30 100644
--- a/dist2/src/pcre2.h.generic
+++ b/dist2/src/pcre2.h.generic
@@ -5,7 +5,7 @@
 /* This is the public header file for the PCRE library, second API, to be
 #included by applications that call PCRE2 functions.
 
-           Copyright (c) 2016 University of Cambridge
+           Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -36,15 +36,15 @@
 -----------------------------------------------------------------------------
 */
 
-#ifndef _PCRE2_H
-#define _PCRE2_H
+#ifndef PCRE2_H_IDEMPOTENT_GUARD
+#define PCRE2_H_IDEMPOTENT_GUARD
 
 /* The current PCRE version information. */
 
 #define PCRE2_MAJOR          10
-#define PCRE2_MINOR          22
+#define PCRE2_MINOR          31
 #define PCRE2_PRERELEASE     
-#define PCRE2_DATE           2016-07-29
+#define PCRE2_DATE           2018-02-12
 
 /* 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
@@ -67,6 +67,20 @@
 #  endif
 #endif
 
+/* When compiling with the MSVC compiler, it is sometimes necessary to include
+a "calling convention" before exported function names. (This is secondhand
+information; I know nothing about MSVC myself). For example, something like
+
+  void __cdecl function(....)
+
+might be needed. In order so make this easy, all the exported functions have
+PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not
+set, we ensure here that it has no effect. */
+
+#ifndef PCRE2_CALL_CONVENTION
+#define PCRE2_CALL_CONVENTION
+#endif
+
 /* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and
 uint8_t, UCHAR_MAX, etc are defined. */
 
@@ -87,6 +101,7 @@
 
 #define PCRE2_ANCHORED            0x80000000u
 #define PCRE2_NO_UTF_CHECK        0x40000000u
+#define PCRE2_ENDANCHORED         0x20000000u
 
 /* The following option bits can be passed only to pcre2_compile(). However,
 they may affect compilation, JIT compilation, and/or interpretive execution.
@@ -122,6 +137,15 @@
 #define PCRE2_ALT_CIRCUMFLEX      0x00200000u  /*   J M D */
 #define PCRE2_ALT_VERBNAMES       0x00400000u  /* C       */
 #define PCRE2_USE_OFFSET_LIMIT    0x00800000u  /*   J M D */
+#define PCRE2_EXTENDED_MORE       0x01000000u  /* C       */
+#define PCRE2_LITERAL             0x02000000u  /* C       */
+
+/* An additional compile options word is available in the compile context. */
+
+#define PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES  0x00000001u  /* C */
+#define PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL    0x00000002u  /* C */
+#define PCRE2_EXTRA_MATCH_WORD               0x00000004u  /* C */
+#define PCRE2_EXTRA_MATCH_LINE               0x00000008u  /* C */
 
 /* These are for pcre2_jit_compile(). */
 
@@ -160,6 +184,16 @@
 
 #define PCRE2_NO_JIT              0x00002000u
 
+/* Options for pcre2_pattern_convert(). */
+
+#define PCRE2_CONVERT_UTF                    0x00000001u
+#define PCRE2_CONVERT_NO_UTF_CHECK           0x00000002u
+#define PCRE2_CONVERT_POSIX_BASIC            0x00000004u
+#define PCRE2_CONVERT_POSIX_EXTENDED         0x00000008u
+#define PCRE2_CONVERT_GLOB                   0x00000010u
+#define PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR 0x00000030u
+#define PCRE2_CONVERT_GLOB_NO_STARSTAR       0x00000050u
+
 /* Newline and \R settings, for use in compile contexts. The newline values
 must be kept in step with values set in config.h and both sets must all be
 greater than zero. */
@@ -169,11 +203,109 @@
 #define PCRE2_NEWLINE_CRLF        3
 #define PCRE2_NEWLINE_ANY         4
 #define PCRE2_NEWLINE_ANYCRLF     5
+#define PCRE2_NEWLINE_NUL         6
 
 #define PCRE2_BSR_UNICODE         1
 #define PCRE2_BSR_ANYCRLF         2
 
-/* Error codes: no match and partial match are "expected" errors. */
+/* Error codes for pcre2_compile(). Some of these are also used by
+pcre2_pattern_convert(). */
+
+#define PCRE2_ERROR_END_BACKSLASH                  101
+#define PCRE2_ERROR_END_BACKSLASH_C                102
+#define PCRE2_ERROR_UNKNOWN_ESCAPE                 103
+#define PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER        104
+#define PCRE2_ERROR_QUANTIFIER_TOO_BIG             105
+#define PCRE2_ERROR_MISSING_SQUARE_BRACKET         106
+#define PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS        107
+#define PCRE2_ERROR_CLASS_RANGE_ORDER              108
+#define PCRE2_ERROR_QUANTIFIER_INVALID             109
+#define PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT     110
+#define PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY     111
+#define PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS       112
+#define PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING     113
+#define PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS    114
+#define PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE       115
+#define PCRE2_ERROR_NULL_PATTERN                   116
+#define PCRE2_ERROR_BAD_OPTIONS                    117
+#define PCRE2_ERROR_MISSING_COMMENT_CLOSING        118
+#define PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP      119
+#define PCRE2_ERROR_PATTERN_TOO_LARGE              120
+#define PCRE2_ERROR_HEAP_FAILED                    121
+#define PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS  122
+#define PCRE2_ERROR_INTERNAL_CODE_OVERFLOW         123
+#define PCRE2_ERROR_MISSING_CONDITION_CLOSING      124
+#define PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH    125
+#define PCRE2_ERROR_ZERO_RELATIVE_REFERENCE        126
+#define PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES    127
+#define PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED   128
+#define PCRE2_ERROR_BAD_RELATIVE_REFERENCE         129
+#define PCRE2_ERROR_UNKNOWN_POSIX_CLASS            130
+#define PCRE2_ERROR_INTERNAL_STUDY_ERROR           131
+#define PCRE2_ERROR_UNICODE_NOT_SUPPORTED          132
+#define PCRE2_ERROR_PARENTHESES_STACK_CHECK        133
+#define PCRE2_ERROR_CODE_POINT_TOO_BIG             134
+#define PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED     135
+#define PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C 136
+#define PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE    137
+#define PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG         138
+#define PCRE2_ERROR_MISSING_CALLOUT_CLOSING        139
+#define PCRE2_ERROR_ESCAPE_INVALID_IN_VERB         140
+#define PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P     141
+#define PCRE2_ERROR_MISSING_NAME_TERMINATOR        142
+#define PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME      143
+#define PCRE2_ERROR_INVALID_SUBPATTERN_NAME        144
+#define PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE 145
+#define PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY     146
+#define PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY       147
+#define PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG       148
+#define PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS     149
+#define PCRE2_ERROR_CLASS_INVALID_RANGE            150
+#define PCRE2_ERROR_OCTAL_BYTE_TOO_BIG             151
+#define PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE     152
+#define PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN    153
+#define PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES       154
+#define PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE      155
+#define PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE       156
+#define PCRE2_ERROR_BACKSLASH_G_SYNTAX             157
+#define PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING 158
+#define PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED      159
+#define PCRE2_ERROR_VERB_UNKNOWN                   160
+#define PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG      161
+#define PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED       162
+#define PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW       163
+#define PCRE2_ERROR_INVALID_OCTAL                  164
+#define PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH      165
+#define PCRE2_ERROR_MARK_MISSING_ARGUMENT          166
+#define PCRE2_ERROR_INVALID_HEXADECIMAL            167
+#define PCRE2_ERROR_BACKSLASH_C_SYNTAX             168
+#define PCRE2_ERROR_BACKSLASH_K_SYNTAX             169
+#define PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS  170
+#define PCRE2_ERROR_BACKSLASH_N_IN_CLASS           171
+#define PCRE2_ERROR_CALLOUT_STRING_TOO_LONG        172
+#define PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT  173
+#define PCRE2_ERROR_UTF_IS_DISABLED                174
+#define PCRE2_ERROR_UCP_IS_DISABLED                175
+#define PCRE2_ERROR_VERB_NAME_TOO_LONG             176
+#define PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG 177
+#define PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS    178
+#define PCRE2_ERROR_VERSION_CONDITION_SYNTAX       179
+#define PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS 180
+#define PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER    181
+#define PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER   182
+#define PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED    183
+#define PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP      184
+#define PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED   185
+#define PCRE2_ERROR_PATTERN_TOO_COMPLICATED        186
+#define PCRE2_ERROR_LOOKBEHIND_TOO_LONG            187
+#define PCRE2_ERROR_PATTERN_STRING_TOO_LONG        188
+#define PCRE2_ERROR_INTERNAL_BAD_CODE              189
+#define PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP      190
+#define PCRE2_ERROR_NO_SURROGATES_IN_UTF16         191
+#define PCRE2_ERROR_BAD_LITERAL_OPTIONS            192
+
+
+/* "Expected" matching error codes: no match and partial match. */
 
 #define PCRE2_ERROR_NOMATCH          (-1)
 #define PCRE2_ERROR_PARTIAL          (-2)
@@ -213,10 +345,10 @@
 #define PCRE2_ERROR_UTF32_ERR1      (-27)
 #define PCRE2_ERROR_UTF32_ERR2      (-28)
 
-/* Error codes for pcre2[_dfa]_match(), substring extraction functions, context
-functions, and serializing functions. They are in numerical order. Originally
-they were in alphabetical order too, but now that PCRE2 is released, the
-numbers must not be changed. */
+/* Miscellaneous error codes for pcre2[_dfa]_match(), substring extraction
+functions, context functions, and serializing functions. They are in numerical
+order. Originally they were in alphabetical order too, but now that PCRE2 is
+released, the numbers must not be changed. */
 
 #define PCRE2_ERROR_BADDATA           (-29)
 #define PCRE2_ERROR_MIXEDTABLES       (-30)  /* Name was changed */
@@ -242,7 +374,8 @@
 #define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)
 #define PCRE2_ERROR_NULL              (-51)
 #define PCRE2_ERROR_RECURSELOOP       (-52)
-#define PCRE2_ERROR_RECURSIONLIMIT    (-53)
+#define PCRE2_ERROR_DEPTHLIMIT        (-53)
+#define PCRE2_ERROR_RECURSIONLIMIT    (-53)  /* Obsolete synonym */
 #define PCRE2_ERROR_UNAVAILABLE       (-54)
 #define PCRE2_ERROR_UNSET             (-55)
 #define PCRE2_ERROR_BADOFFSETLIMIT    (-56)
@@ -252,6 +385,9 @@
 #define PCRE2_ERROR_BADSUBSPATTERN    (-60)
 #define PCRE2_ERROR_TOOMANYREPLACE    (-61)
 #define PCRE2_ERROR_BADSERIALIZEDDATA (-62)
+#define PCRE2_ERROR_HEAPLIMIT         (-63)
+#define PCRE2_ERROR_CONVERT_SYNTAX    (-64)
+
 
 /* Request types for pcre2_pattern_info() */
 
@@ -276,9 +412,13 @@
 #define PCRE2_INFO_NAMEENTRYSIZE        18
 #define PCRE2_INFO_NAMETABLE            19
 #define PCRE2_INFO_NEWLINE              20
-#define PCRE2_INFO_RECURSIONLIMIT       21
+#define PCRE2_INFO_DEPTHLIMIT           21
+#define PCRE2_INFO_RECURSIONLIMIT       21  /* Obsolete synonym */
 #define PCRE2_INFO_SIZE                 22
 #define PCRE2_INFO_HASBACKSLASHC        23
+#define PCRE2_INFO_FRAMESIZE            24
+#define PCRE2_INFO_HEAPLIMIT            25
+#define PCRE2_INFO_EXTRAOPTIONS         26
 
 /* Request types for pcre2_config(). */
 
@@ -289,11 +429,16 @@
 #define PCRE2_CONFIG_MATCHLIMIT              4
 #define PCRE2_CONFIG_NEWLINE                 5
 #define PCRE2_CONFIG_PARENSLIMIT             6
-#define PCRE2_CONFIG_RECURSIONLIMIT          7
-#define PCRE2_CONFIG_STACKRECURSE            8
+#define PCRE2_CONFIG_DEPTHLIMIT              7
+#define PCRE2_CONFIG_RECURSIONLIMIT          7  /* Obsolete synonym */
+#define PCRE2_CONFIG_STACKRECURSE            8  /* Obsolete */
 #define PCRE2_CONFIG_UNICODE                 9
 #define PCRE2_CONFIG_UNICODE_VERSION        10
 #define PCRE2_CONFIG_VERSION                11
+#define PCRE2_CONFIG_HEAPLIMIT              12
+#define PCRE2_CONFIG_NEVER_BACKSLASH_C      13
+#define PCRE2_CONFIG_COMPILED_WIDTHS        14
+
 
 /* Types for code units in patterns and subject strings. */
 
@@ -328,6 +473,9 @@
 struct pcre2_real_match_context; \
 typedef struct pcre2_real_match_context pcre2_match_context; \
 \
+struct pcre2_real_convert_context; \
+typedef struct pcre2_real_convert_context pcre2_convert_context; \
+\
 struct pcre2_real_code; \
 typedef struct pcre2_real_code pcre2_code; \
 \
@@ -346,6 +494,11 @@
 without modification. Define the generic version in a macro; the width-specific
 versions are generated from this macro below. */
 
+/* Flags for the callout_flags field. These are cleared after a callout. */
+
+#define PCRE2_CALLOUT_STARTMATCH    0x00000001u  /* Set for each bumpalong */
+#define PCRE2_CALLOUT_BACKTRACK     0x00000002u  /* Set after a backtrack */
+
 #define PCRE2_STRUCTURE_LIST \
 typedef struct pcre2_callout_block { \
   uint32_t      version;           /* Identifies version of block */ \
@@ -365,6 +518,8 @@
   PCRE2_SIZE    callout_string_offset; /* Offset to string within pattern */ \
   PCRE2_SIZE    callout_string_length; /* Length of string compiled into pattern */ \
   PCRE2_SPTR    callout_string;    /* String compiled into pattern */ \
+  /* ------------------- Added for Version 2 -------------------------- */ \
+  uint32_t      callout_flags;     /* See above for list */ \
   /* ------------------------------------------------------------------ */ \
 } pcre2_callout_block; \
 \
@@ -386,170 +541,220 @@
 information. */
 
 #define PCRE2_GENERAL_INFO_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_config(uint32_t, void *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *);
 
 
 /* Functions for manipulating contexts. */
 
 #define PCRE2_GENERAL_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_general_context *pcre2_general_context_copy(pcre2_general_context *); \
-PCRE2_EXP_DECL \
-  pcre2_general_context *pcre2_general_context_create( \
-                           void *(*)(PCRE2_SIZE, void *), \
-                           void (*)(void *, void *), void *); \
-PCRE2_EXP_DECL void      pcre2_general_context_free(pcre2_general_context *);
+PCRE2_EXP_DECL pcre2_general_context PCRE2_CALL_CONVENTION \
+  *pcre2_general_context_copy(pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_general_context PCRE2_CALL_CONVENTION \
+  *pcre2_general_context_create(void *(*)(PCRE2_SIZE, void *), \
+    void (*)(void *, void *), void *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_general_context_free(pcre2_general_context *);
 
 #define PCRE2_COMPILE_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_compile_context *pcre2_compile_context_copy(pcre2_compile_context *); \
-PCRE2_EXP_DECL \
-  pcre2_compile_context *pcre2_compile_context_create(pcre2_general_context *);\
-PCRE2_EXP_DECL void      pcre2_compile_context_free(pcre2_compile_context *); \
-PCRE2_EXP_DECL int       pcre2_set_bsr(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_character_tables(pcre2_compile_context *, \
-                           const unsigned char *); \
-PCRE2_EXP_DECL int       pcre2_set_max_pattern_length(pcre2_compile_context *, \
-                           PCRE2_SIZE); \
-PCRE2_EXP_DECL int       pcre2_set_newline(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_parens_nest_limit(pcre2_compile_context *, \
-                           uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_compile_recursion_guard(\
-                           pcre2_compile_context *, int (*)(uint32_t, void *), \
-                           void *);
+PCRE2_EXP_DECL pcre2_compile_context PCRE2_CALL_CONVENTION \
+  *pcre2_compile_context_copy(pcre2_compile_context *); \
+PCRE2_EXP_DECL pcre2_compile_context PCRE2_CALL_CONVENTION \
+  *pcre2_compile_context_create(pcre2_general_context *);\
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_compile_context_free(pcre2_compile_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_bsr(pcre2_compile_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_character_tables(pcre2_compile_context *, const unsigned char *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_newline(pcre2_compile_context *, uint32_t); \
+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 *);
 
 #define PCRE2_MATCH_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_match_context   *pcre2_match_context_copy(pcre2_match_context *); \
-PCRE2_EXP_DECL \
-  pcre2_match_context   *pcre2_match_context_create(pcre2_general_context *); \
-PCRE2_EXP_DECL void      pcre2_match_context_free(pcre2_match_context *); \
-PCRE2_EXP_DECL int       pcre2_set_callout(pcre2_match_context *, \
-                           int (*)(pcre2_callout_block *, void *), void *); \
-PCRE2_EXP_DECL int       pcre2_set_match_limit(pcre2_match_context *, \
-                           uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_offset_limit(pcre2_match_context *, \
-                           PCRE2_SIZE); \
-PCRE2_EXP_DECL int       pcre2_set_recursion_limit(pcre2_match_context *, \
-                           uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_recursion_memory_management( \
-                           pcre2_match_context *, void *(*)(PCRE2_SIZE, void *), \
-                           void (*)(void *, void *), void *);
+PCRE2_EXP_DECL pcre2_match_context PCRE2_CALL_CONVENTION \
+  *pcre2_match_context_copy(pcre2_match_context *); \
+PCRE2_EXP_DECL pcre2_match_context PCRE2_CALL_CONVENTION \
+  *pcre2_match_context_create(pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_match_context_free(pcre2_match_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_callout(pcre2_match_context *, \
+    int (*)(pcre2_callout_block *, 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 \
+  pcre2_set_heap_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_match_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_recursion_memory_management(pcre2_match_context *, \
+    void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *);
+
+#define PCRE2_CONVERT_CONTEXT_FUNCTIONS \
+PCRE2_EXP_DECL pcre2_convert_context PCRE2_CALL_CONVENTION \
+  *pcre2_convert_context_copy(pcre2_convert_context *); \
+PCRE2_EXP_DECL pcre2_convert_context PCRE2_CALL_CONVENTION \
+  *pcre2_convert_context_create(pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_convert_context_free(pcre2_convert_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_glob_escape(pcre2_convert_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_glob_separator(pcre2_convert_context *, uint32_t);
 
 
 /* Functions concerned with compiling a pattern to PCRE internal code. */
 
 #define PCRE2_COMPILE_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_code            *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \
-                           int *, PCRE2_SIZE *, pcre2_compile_context *); \
-PCRE2_EXP_DECL void      pcre2_code_free(pcre2_code *); \
-PCRE2_EXP_DECL \
-  pcre2_code            *pcre2_code_copy(const pcre2_code *);
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+  *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, \
+    pcre2_compile_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_code_free(pcre2_code *); \
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+  *pcre2_code_copy(const pcre2_code *); \
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+  *pcre2_code_copy_with_tables(const pcre2_code *);
 
 
 /* Functions that give information about a compiled pattern. */
 
 #define PCRE2_PATTERN_INFO_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_pattern_info(const pcre2_code *, uint32_t, \
-                           void *); \
-PCRE2_EXP_DECL int       pcre2_callout_enumerate(const pcre2_code *, \
-                           int (*)(pcre2_callout_enumerate_block *, void *), \
-                           void *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_pattern_info(const pcre2_code *, uint32_t, void *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_callout_enumerate(const pcre2_code *, \
+    int (*)(pcre2_callout_enumerate_block *, void *), void *);
 
 
 /* Functions for running a match and inspecting the result. */
 
 #define PCRE2_MATCH_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_match_data        *pcre2_match_data_create(uint32_t, \
-                             pcre2_general_context *); \
-PCRE2_EXP_DECL \
-  pcre2_match_data        *pcre2_match_data_create_from_pattern(\
-                             const pcre2_code *, \
-                             pcre2_general_context *); \
-PCRE2_EXP_DECL int         pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, \
-                             PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                             pcre2_match_data *, pcre2_match_context *, int *, \
-                             PCRE2_SIZE); \
-PCRE2_EXP_DECL int         pcre2_match(const pcre2_code *, \
-                             PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                             pcre2_match_data *, pcre2_match_context *); \
-PCRE2_EXP_DECL void        pcre2_match_data_free(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SPTR  pcre2_get_mark(pcre2_match_data *); \
-PCRE2_EXP_DECL uint32_t    pcre2_get_ovector_count(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SIZE *pcre2_get_ovector_pointer(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SIZE  pcre2_get_startchar(pcre2_match_data *);
+PCRE2_EXP_DECL pcre2_match_data PCRE2_CALL_CONVENTION \
+  *pcre2_match_data_create(uint32_t, pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_match_data PCRE2_CALL_CONVENTION \
+  *pcre2_match_data_create_from_pattern(const pcre2_code *, \
+    pcre2_general_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *, int *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_match_data_free(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \
+  pcre2_get_mark(pcre2_match_data *); \
+PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \
+  pcre2_get_ovector_count(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
+  *pcre2_get_ovector_pointer(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
+  pcre2_get_startchar(pcre2_match_data *);
 
 
 /* Convenience functions for handling matched substrings. */
 
 #define PCRE2_SUBSTRING_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_substring_copy_byname(pcre2_match_data *, \
-                           PCRE2_SPTR, PCRE2_UCHAR *, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_copy_bynumber(pcre2_match_data *, \
-                           uint32_t, PCRE2_UCHAR *, PCRE2_SIZE *); \
-PCRE2_EXP_DECL void      pcre2_substring_free(PCRE2_UCHAR *); \
-PCRE2_EXP_DECL int       pcre2_substring_get_byname(pcre2_match_data *, \
-                           PCRE2_SPTR, PCRE2_UCHAR **, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_get_bynumber(pcre2_match_data *, \
-                           uint32_t, PCRE2_UCHAR **, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_length_byname(pcre2_match_data *, \
-                           PCRE2_SPTR, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_length_bynumber(pcre2_match_data *, \
-                           uint32_t, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_nametable_scan(const pcre2_code *, \
-                           PCRE2_SPTR, PCRE2_SPTR *, PCRE2_SPTR *); \
-PCRE2_EXP_DECL int       pcre2_substring_number_from_name(\
-                           const pcre2_code *, PCRE2_SPTR); \
-PCRE2_EXP_DECL void      pcre2_substring_list_free(PCRE2_SPTR *); \
-PCRE2_EXP_DECL int       pcre2_substring_list_get(pcre2_match_data *, \
-                           PCRE2_UCHAR ***, PCRE2_SIZE **);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_copy_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR *, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_copy_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR *, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_substring_free(PCRE2_UCHAR *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_get_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR **, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_get_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR **, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_length_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_length_bynumber(pcre2_match_data *, uint32_t, PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_nametable_scan(const pcre2_code *, PCRE2_SPTR, PCRE2_SPTR *, \
+    PCRE2_SPTR *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_substring_list_free(PCRE2_SPTR *); \
+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 \
-PCRE2_EXP_DECL int32_t   pcre2_serialize_encode(const pcre2_code **, \
-                           int32_t, uint8_t **, PCRE2_SIZE *, \
-                           pcre2_general_context *); \
-PCRE2_EXP_DECL int32_t   pcre2_serialize_decode(pcre2_code **, int32_t, \
-                           const uint8_t *, pcre2_general_context *); \
-PCRE2_EXP_DECL int32_t   pcre2_serialize_get_number_of_codes(const uint8_t *); \
-PCRE2_EXP_DECL void      pcre2_serialize_free(uint8_t *);
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+  pcre2_serialize_encode(const pcre2_code **, int32_t, uint8_t **, \
+    PCRE2_SIZE *, pcre2_general_context *); \
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+  pcre2_serialize_decode(pcre2_code **, int32_t, const uint8_t *, \
+    pcre2_general_context *); \
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+  pcre2_serialize_get_number_of_codes(const uint8_t *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_serialize_free(uint8_t *);
 
 
 /* Convenience function for match + substitute. */
 
 #define PCRE2_SUBSTITUTE_FUNCTION \
-PCRE2_EXP_DECL int       pcre2_substitute(const pcre2_code *, \
-                           PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                           pcre2_match_data *, pcre2_match_context *, \
-                           PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, \
-                           PCRE2_SIZE *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substitute(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *, PCRE2_SPTR, \
+    PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE *);
+
+
+/* Functions for converting pattern source strings. */
+
+#define PCRE2_CONVERT_FUNCTIONS \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_pattern_convert(PCRE2_SPTR, PCRE2_SIZE, uint32_t, PCRE2_UCHAR **, \
+    PCRE2_SIZE *, pcre2_convert_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_converted_pattern_free(PCRE2_UCHAR *);
 
 
 /* Functions for JIT processing */
 
 #define PCRE2_JIT_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_jit_compile(pcre2_code *, uint32_t); \
-PCRE2_EXP_DECL int       pcre2_jit_match(const pcre2_code *, \
-                           PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                           pcre2_match_data *, pcre2_match_context *); \
-PCRE2_EXP_DECL void      pcre2_jit_free_unused_memory(pcre2_general_context *); \
-PCRE2_EXP_DECL \
-  pcre2_jit_stack       *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, \
-                           pcre2_general_context *); \
-PCRE2_EXP_DECL void      pcre2_jit_stack_assign(pcre2_match_context *, \
-                           pcre2_jit_callback, void *); \
-PCRE2_EXP_DECL void      pcre2_jit_stack_free(pcre2_jit_stack *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_jit_compile(pcre2_code *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_jit_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_jit_free_unused_memory(pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_jit_stack PCRE2_CALL_CONVENTION \
+  *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_jit_stack_free(pcre2_jit_stack *);
 
 
 /* Other miscellaneous functions. */
 
 #define PCRE2_OTHER_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \
-PCRE2_EXP_DECL \
-  const uint8_t         *pcre2_maketables(pcre2_general_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \
+PCRE2_EXP_DECL const uint8_t PCRE2_CALL_CONVENTION \
+  *pcre2_maketables(pcre2_general_context *); \
 
 
 /* Define macros that generate width-specific names from generic versions. The
@@ -576,6 +781,7 @@
 #define pcre2_real_code             PCRE2_SUFFIX(pcre2_real_code_)
 #define pcre2_real_general_context  PCRE2_SUFFIX(pcre2_real_general_context_)
 #define pcre2_real_compile_context  PCRE2_SUFFIX(pcre2_real_compile_context_)
+#define pcre2_real_convert_context  PCRE2_SUFFIX(pcre2_real_convert_context_)
 #define pcre2_real_match_context    PCRE2_SUFFIX(pcre2_real_match_context_)
 #define pcre2_real_jit_stack        PCRE2_SUFFIX(pcre2_real_jit_stack_)
 #define pcre2_real_match_data       PCRE2_SUFFIX(pcre2_real_match_data_)
@@ -587,6 +793,7 @@
 #define pcre2_callout_enumerate_block  PCRE2_SUFFIX(pcre2_callout_enumerate_block_)
 #define pcre2_general_context          PCRE2_SUFFIX(pcre2_general_context_)
 #define pcre2_compile_context          PCRE2_SUFFIX(pcre2_compile_context_)
+#define pcre2_convert_context          PCRE2_SUFFIX(pcre2_convert_context_)
 #define pcre2_match_context            PCRE2_SUFFIX(pcre2_match_context_)
 #define pcre2_match_data               PCRE2_SUFFIX(pcre2_match_data_)
 
@@ -595,12 +802,17 @@
 
 #define pcre2_callout_enumerate               PCRE2_SUFFIX(pcre2_callout_enumerate_)
 #define pcre2_code_copy                       PCRE2_SUFFIX(pcre2_code_copy_)
+#define pcre2_code_copy_with_tables           PCRE2_SUFFIX(pcre2_code_copy_with_tables_)
 #define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)
 #define pcre2_compile                         PCRE2_SUFFIX(pcre2_compile_)
 #define pcre2_compile_context_copy            PCRE2_SUFFIX(pcre2_compile_context_copy_)
 #define pcre2_compile_context_create          PCRE2_SUFFIX(pcre2_compile_context_create_)
 #define pcre2_compile_context_free            PCRE2_SUFFIX(pcre2_compile_context_free_)
 #define pcre2_config                          PCRE2_SUFFIX(pcre2_config_)
+#define pcre2_convert_context_copy            PCRE2_SUFFIX(pcre2_convert_context_copy_)
+#define pcre2_convert_context_create          PCRE2_SUFFIX(pcre2_convert_context_create_)
+#define pcre2_convert_context_free            PCRE2_SUFFIX(pcre2_convert_context_free_)
+#define pcre2_converted_pattern_free          PCRE2_SUFFIX(pcre2_converted_pattern_free_)
 #define pcre2_dfa_match                       PCRE2_SUFFIX(pcre2_dfa_match_)
 #define pcre2_general_context_copy            PCRE2_SUFFIX(pcre2_general_context_copy_)
 #define pcre2_general_context_create          PCRE2_SUFFIX(pcre2_general_context_create_)
@@ -624,6 +836,7 @@
 #define pcre2_match_data_create               PCRE2_SUFFIX(pcre2_match_data_create_)
 #define pcre2_match_data_create_from_pattern  PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_)
 #define pcre2_match_data_free                 PCRE2_SUFFIX(pcre2_match_data_free_)
+#define pcre2_pattern_convert                 PCRE2_SUFFIX(pcre2_pattern_convert_)
 #define pcre2_pattern_info                    PCRE2_SUFFIX(pcre2_pattern_info_)
 #define pcre2_serialize_decode                PCRE2_SUFFIX(pcre2_serialize_decode_)
 #define pcre2_serialize_encode                PCRE2_SUFFIX(pcre2_serialize_encode_)
@@ -632,14 +845,17 @@
 #define pcre2_set_bsr                         PCRE2_SUFFIX(pcre2_set_bsr_)
 #define pcre2_set_callout                     PCRE2_SUFFIX(pcre2_set_callout_)
 #define pcre2_set_character_tables            PCRE2_SUFFIX(pcre2_set_character_tables_)
+#define pcre2_set_compile_extra_options       PCRE2_SUFFIX(pcre2_set_compile_extra_options_)
 #define pcre2_set_compile_recursion_guard     PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)
+#define pcre2_set_depth_limit                 PCRE2_SUFFIX(pcre2_set_depth_limit_)
+#define pcre2_set_glob_escape                 PCRE2_SUFFIX(pcre2_set_glob_escape_)
+#define pcre2_set_glob_separator              PCRE2_SUFFIX(pcre2_set_glob_separator_)
+#define pcre2_set_heap_limit                  PCRE2_SUFFIX(pcre2_set_heap_limit_)
 #define pcre2_set_match_limit                 PCRE2_SUFFIX(pcre2_set_match_limit_)
 #define pcre2_set_max_pattern_length          PCRE2_SUFFIX(pcre2_set_max_pattern_length_)
 #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_recursion_limit             PCRE2_SUFFIX(pcre2_set_recursion_limit_)
-#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
 #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_)
@@ -653,6 +869,11 @@
 #define pcre2_substring_nametable_scan        PCRE2_SUFFIX(pcre2_substring_nametable_scan_)
 #define pcre2_substring_number_from_name      PCRE2_SUFFIX(pcre2_substring_number_from_name_)
 
+/* Keep this old function name for backwards compatibility */
+#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)
+
+/* Keep this obsolete function for backwards compatibility: it is now a noop. */
+#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
 
 /* Now generate all three sets of width-specific structures and function
 prototypes. */
@@ -663,6 +884,8 @@
 PCRE2_GENERAL_INFO_FUNCTIONS \
 PCRE2_GENERAL_CONTEXT_FUNCTIONS \
 PCRE2_COMPILE_CONTEXT_FUNCTIONS \
+PCRE2_CONVERT_CONTEXT_FUNCTIONS \
+PCRE2_CONVERT_FUNCTIONS \
 PCRE2_MATCH_CONTEXT_FUNCTIONS \
 PCRE2_COMPILE_FUNCTIONS \
 PCRE2_PATTERN_INFO_FUNCTIONS \
@@ -692,6 +915,7 @@
 #undef PCRE2_GENERAL_INFO_FUNCTIONS
 #undef PCRE2_GENERAL_CONTEXT_FUNCTIONS
 #undef PCRE2_COMPILE_CONTEXT_FUNCTIONS
+#undef PCRE2_CONVERT_CONTEXT_FUNCTIONS
 #undef PCRE2_MATCH_CONTEXT_FUNCTIONS
 #undef PCRE2_COMPILE_FUNCTIONS
 #undef PCRE2_PATTERN_INFO_FUNCTIONS
@@ -729,4 +953,6 @@
 }  /* extern "C" */
 #endif
 
-#endif /* End of pcre2.h */
+#endif  /* PCRE2_H_IDEMPOTENT_GUARD */
+
+/* End of pcre2.h */
diff --git a/dist2/src/pcre2.h.in b/dist2/src/pcre2.h.in
index e1d944d..a3a3fa6 100644
--- a/dist2/src/pcre2.h.in
+++ b/dist2/src/pcre2.h.in
@@ -5,7 +5,7 @@
 /* This is the public header file for the PCRE library, second API, to be
 #included by applications that call PCRE2 functions.
 
-           Copyright (c) 2016 University of Cambridge
+           Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -36,8 +36,8 @@
 -----------------------------------------------------------------------------
 */
 
-#ifndef _PCRE2_H
-#define _PCRE2_H
+#ifndef PCRE2_H_IDEMPOTENT_GUARD
+#define PCRE2_H_IDEMPOTENT_GUARD
 
 /* The current PCRE version information. */
 
@@ -67,6 +67,20 @@
 #  endif
 #endif
 
+/* When compiling with the MSVC compiler, it is sometimes necessary to include
+a "calling convention" before exported function names. (This is secondhand
+information; I know nothing about MSVC myself). For example, something like
+
+  void __cdecl function(....)
+
+might be needed. In order so make this easy, all the exported functions have
+PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not
+set, we ensure here that it has no effect. */
+
+#ifndef PCRE2_CALL_CONVENTION
+#define PCRE2_CALL_CONVENTION
+#endif
+
 /* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and
 uint8_t, UCHAR_MAX, etc are defined. */
 
@@ -87,6 +101,7 @@
 
 #define PCRE2_ANCHORED            0x80000000u
 #define PCRE2_NO_UTF_CHECK        0x40000000u
+#define PCRE2_ENDANCHORED         0x20000000u
 
 /* The following option bits can be passed only to pcre2_compile(). However,
 they may affect compilation, JIT compilation, and/or interpretive execution.
@@ -122,6 +137,15 @@
 #define PCRE2_ALT_CIRCUMFLEX      0x00200000u  /*   J M D */
 #define PCRE2_ALT_VERBNAMES       0x00400000u  /* C       */
 #define PCRE2_USE_OFFSET_LIMIT    0x00800000u  /*   J M D */
+#define PCRE2_EXTENDED_MORE       0x01000000u  /* C       */
+#define PCRE2_LITERAL             0x02000000u  /* C       */
+
+/* An additional compile options word is available in the compile context. */
+
+#define PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES  0x00000001u  /* C */
+#define PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL    0x00000002u  /* C */
+#define PCRE2_EXTRA_MATCH_WORD               0x00000004u  /* C */
+#define PCRE2_EXTRA_MATCH_LINE               0x00000008u  /* C */
 
 /* These are for pcre2_jit_compile(). */
 
@@ -160,6 +184,16 @@
 
 #define PCRE2_NO_JIT              0x00002000u
 
+/* Options for pcre2_pattern_convert(). */
+
+#define PCRE2_CONVERT_UTF                    0x00000001u
+#define PCRE2_CONVERT_NO_UTF_CHECK           0x00000002u
+#define PCRE2_CONVERT_POSIX_BASIC            0x00000004u
+#define PCRE2_CONVERT_POSIX_EXTENDED         0x00000008u
+#define PCRE2_CONVERT_GLOB                   0x00000010u
+#define PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR 0x00000030u
+#define PCRE2_CONVERT_GLOB_NO_STARSTAR       0x00000050u
+
 /* Newline and \R settings, for use in compile contexts. The newline values
 must be kept in step with values set in config.h and both sets must all be
 greater than zero. */
@@ -169,11 +203,109 @@
 #define PCRE2_NEWLINE_CRLF        3
 #define PCRE2_NEWLINE_ANY         4
 #define PCRE2_NEWLINE_ANYCRLF     5
+#define PCRE2_NEWLINE_NUL         6
 
 #define PCRE2_BSR_UNICODE         1
 #define PCRE2_BSR_ANYCRLF         2
 
-/* Error codes: no match and partial match are "expected" errors. */
+/* Error codes for pcre2_compile(). Some of these are also used by
+pcre2_pattern_convert(). */
+
+#define PCRE2_ERROR_END_BACKSLASH                  101
+#define PCRE2_ERROR_END_BACKSLASH_C                102
+#define PCRE2_ERROR_UNKNOWN_ESCAPE                 103
+#define PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER        104
+#define PCRE2_ERROR_QUANTIFIER_TOO_BIG             105
+#define PCRE2_ERROR_MISSING_SQUARE_BRACKET         106
+#define PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS        107
+#define PCRE2_ERROR_CLASS_RANGE_ORDER              108
+#define PCRE2_ERROR_QUANTIFIER_INVALID             109
+#define PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT     110
+#define PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY     111
+#define PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS       112
+#define PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING     113
+#define PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS    114
+#define PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE       115
+#define PCRE2_ERROR_NULL_PATTERN                   116
+#define PCRE2_ERROR_BAD_OPTIONS                    117
+#define PCRE2_ERROR_MISSING_COMMENT_CLOSING        118
+#define PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP      119
+#define PCRE2_ERROR_PATTERN_TOO_LARGE              120
+#define PCRE2_ERROR_HEAP_FAILED                    121
+#define PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS  122
+#define PCRE2_ERROR_INTERNAL_CODE_OVERFLOW         123
+#define PCRE2_ERROR_MISSING_CONDITION_CLOSING      124
+#define PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH    125
+#define PCRE2_ERROR_ZERO_RELATIVE_REFERENCE        126
+#define PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES    127
+#define PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED   128
+#define PCRE2_ERROR_BAD_RELATIVE_REFERENCE         129
+#define PCRE2_ERROR_UNKNOWN_POSIX_CLASS            130
+#define PCRE2_ERROR_INTERNAL_STUDY_ERROR           131
+#define PCRE2_ERROR_UNICODE_NOT_SUPPORTED          132
+#define PCRE2_ERROR_PARENTHESES_STACK_CHECK        133
+#define PCRE2_ERROR_CODE_POINT_TOO_BIG             134
+#define PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED     135
+#define PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C 136
+#define PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE    137
+#define PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG         138
+#define PCRE2_ERROR_MISSING_CALLOUT_CLOSING        139
+#define PCRE2_ERROR_ESCAPE_INVALID_IN_VERB         140
+#define PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P     141
+#define PCRE2_ERROR_MISSING_NAME_TERMINATOR        142
+#define PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME      143
+#define PCRE2_ERROR_INVALID_SUBPATTERN_NAME        144
+#define PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE 145
+#define PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY     146
+#define PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY       147
+#define PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG       148
+#define PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS     149
+#define PCRE2_ERROR_CLASS_INVALID_RANGE            150
+#define PCRE2_ERROR_OCTAL_BYTE_TOO_BIG             151
+#define PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE     152
+#define PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN    153
+#define PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES       154
+#define PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE      155
+#define PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE       156
+#define PCRE2_ERROR_BACKSLASH_G_SYNTAX             157
+#define PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING 158
+#define PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED      159
+#define PCRE2_ERROR_VERB_UNKNOWN                   160
+#define PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG      161
+#define PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED       162
+#define PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW       163
+#define PCRE2_ERROR_INVALID_OCTAL                  164
+#define PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH      165
+#define PCRE2_ERROR_MARK_MISSING_ARGUMENT          166
+#define PCRE2_ERROR_INVALID_HEXADECIMAL            167
+#define PCRE2_ERROR_BACKSLASH_C_SYNTAX             168
+#define PCRE2_ERROR_BACKSLASH_K_SYNTAX             169
+#define PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS  170
+#define PCRE2_ERROR_BACKSLASH_N_IN_CLASS           171
+#define PCRE2_ERROR_CALLOUT_STRING_TOO_LONG        172
+#define PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT  173
+#define PCRE2_ERROR_UTF_IS_DISABLED                174
+#define PCRE2_ERROR_UCP_IS_DISABLED                175
+#define PCRE2_ERROR_VERB_NAME_TOO_LONG             176
+#define PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG 177
+#define PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS    178
+#define PCRE2_ERROR_VERSION_CONDITION_SYNTAX       179
+#define PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS 180
+#define PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER    181
+#define PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER   182
+#define PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED    183
+#define PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP      184
+#define PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED   185
+#define PCRE2_ERROR_PATTERN_TOO_COMPLICATED        186
+#define PCRE2_ERROR_LOOKBEHIND_TOO_LONG            187
+#define PCRE2_ERROR_PATTERN_STRING_TOO_LONG        188
+#define PCRE2_ERROR_INTERNAL_BAD_CODE              189
+#define PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP      190
+#define PCRE2_ERROR_NO_SURROGATES_IN_UTF16         191
+#define PCRE2_ERROR_BAD_LITERAL_OPTIONS            192
+
+
+/* "Expected" matching error codes: no match and partial match. */
 
 #define PCRE2_ERROR_NOMATCH          (-1)
 #define PCRE2_ERROR_PARTIAL          (-2)
@@ -213,10 +345,10 @@
 #define PCRE2_ERROR_UTF32_ERR1      (-27)
 #define PCRE2_ERROR_UTF32_ERR2      (-28)
 
-/* Error codes for pcre2[_dfa]_match(), substring extraction functions, context
-functions, and serializing functions. They are in numerical order. Originally
-they were in alphabetical order too, but now that PCRE2 is released, the
-numbers must not be changed. */
+/* Miscellaneous error codes for pcre2[_dfa]_match(), substring extraction
+functions, context functions, and serializing functions. They are in numerical
+order. Originally they were in alphabetical order too, but now that PCRE2 is
+released, the numbers must not be changed. */
 
 #define PCRE2_ERROR_BADDATA           (-29)
 #define PCRE2_ERROR_MIXEDTABLES       (-30)  /* Name was changed */
@@ -242,7 +374,8 @@
 #define PCRE2_ERROR_NOUNIQUESUBSTRING (-50)
 #define PCRE2_ERROR_NULL              (-51)
 #define PCRE2_ERROR_RECURSELOOP       (-52)
-#define PCRE2_ERROR_RECURSIONLIMIT    (-53)
+#define PCRE2_ERROR_DEPTHLIMIT        (-53)
+#define PCRE2_ERROR_RECURSIONLIMIT    (-53)  /* Obsolete synonym */
 #define PCRE2_ERROR_UNAVAILABLE       (-54)
 #define PCRE2_ERROR_UNSET             (-55)
 #define PCRE2_ERROR_BADOFFSETLIMIT    (-56)
@@ -252,6 +385,9 @@
 #define PCRE2_ERROR_BADSUBSPATTERN    (-60)
 #define PCRE2_ERROR_TOOMANYREPLACE    (-61)
 #define PCRE2_ERROR_BADSERIALIZEDDATA (-62)
+#define PCRE2_ERROR_HEAPLIMIT         (-63)
+#define PCRE2_ERROR_CONVERT_SYNTAX    (-64)
+
 
 /* Request types for pcre2_pattern_info() */
 
@@ -276,9 +412,13 @@
 #define PCRE2_INFO_NAMEENTRYSIZE        18
 #define PCRE2_INFO_NAMETABLE            19
 #define PCRE2_INFO_NEWLINE              20
-#define PCRE2_INFO_RECURSIONLIMIT       21
+#define PCRE2_INFO_DEPTHLIMIT           21
+#define PCRE2_INFO_RECURSIONLIMIT       21  /* Obsolete synonym */
 #define PCRE2_INFO_SIZE                 22
 #define PCRE2_INFO_HASBACKSLASHC        23
+#define PCRE2_INFO_FRAMESIZE            24
+#define PCRE2_INFO_HEAPLIMIT            25
+#define PCRE2_INFO_EXTRAOPTIONS         26
 
 /* Request types for pcre2_config(). */
 
@@ -289,11 +429,16 @@
 #define PCRE2_CONFIG_MATCHLIMIT              4
 #define PCRE2_CONFIG_NEWLINE                 5
 #define PCRE2_CONFIG_PARENSLIMIT             6
-#define PCRE2_CONFIG_RECURSIONLIMIT          7
-#define PCRE2_CONFIG_STACKRECURSE            8
+#define PCRE2_CONFIG_DEPTHLIMIT              7
+#define PCRE2_CONFIG_RECURSIONLIMIT          7  /* Obsolete synonym */
+#define PCRE2_CONFIG_STACKRECURSE            8  /* Obsolete */
 #define PCRE2_CONFIG_UNICODE                 9
 #define PCRE2_CONFIG_UNICODE_VERSION        10
 #define PCRE2_CONFIG_VERSION                11
+#define PCRE2_CONFIG_HEAPLIMIT              12
+#define PCRE2_CONFIG_NEVER_BACKSLASH_C      13
+#define PCRE2_CONFIG_COMPILED_WIDTHS        14
+
 
 /* Types for code units in patterns and subject strings. */
 
@@ -328,6 +473,9 @@
 struct pcre2_real_match_context; \
 typedef struct pcre2_real_match_context pcre2_match_context; \
 \
+struct pcre2_real_convert_context; \
+typedef struct pcre2_real_convert_context pcre2_convert_context; \
+\
 struct pcre2_real_code; \
 typedef struct pcre2_real_code pcre2_code; \
 \
@@ -346,6 +494,11 @@
 without modification. Define the generic version in a macro; the width-specific
 versions are generated from this macro below. */
 
+/* Flags for the callout_flags field. These are cleared after a callout. */
+
+#define PCRE2_CALLOUT_STARTMATCH    0x00000001u  /* Set for each bumpalong */
+#define PCRE2_CALLOUT_BACKTRACK     0x00000002u  /* Set after a backtrack */
+
 #define PCRE2_STRUCTURE_LIST \
 typedef struct pcre2_callout_block { \
   uint32_t      version;           /* Identifies version of block */ \
@@ -365,6 +518,8 @@
   PCRE2_SIZE    callout_string_offset; /* Offset to string within pattern */ \
   PCRE2_SIZE    callout_string_length; /* Length of string compiled into pattern */ \
   PCRE2_SPTR    callout_string;    /* String compiled into pattern */ \
+  /* ------------------- Added for Version 2 -------------------------- */ \
+  uint32_t      callout_flags;     /* See above for list */ \
   /* ------------------------------------------------------------------ */ \
 } pcre2_callout_block; \
 \
@@ -386,170 +541,220 @@
 information. */
 
 #define PCRE2_GENERAL_INFO_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_config(uint32_t, void *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *);
 
 
 /* Functions for manipulating contexts. */
 
 #define PCRE2_GENERAL_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_general_context *pcre2_general_context_copy(pcre2_general_context *); \
-PCRE2_EXP_DECL \
-  pcre2_general_context *pcre2_general_context_create( \
-                           void *(*)(PCRE2_SIZE, void *), \
-                           void (*)(void *, void *), void *); \
-PCRE2_EXP_DECL void      pcre2_general_context_free(pcre2_general_context *);
+PCRE2_EXP_DECL pcre2_general_context PCRE2_CALL_CONVENTION \
+  *pcre2_general_context_copy(pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_general_context PCRE2_CALL_CONVENTION \
+  *pcre2_general_context_create(void *(*)(PCRE2_SIZE, void *), \
+    void (*)(void *, void *), void *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_general_context_free(pcre2_general_context *);
 
 #define PCRE2_COMPILE_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_compile_context *pcre2_compile_context_copy(pcre2_compile_context *); \
-PCRE2_EXP_DECL \
-  pcre2_compile_context *pcre2_compile_context_create(pcre2_general_context *);\
-PCRE2_EXP_DECL void      pcre2_compile_context_free(pcre2_compile_context *); \
-PCRE2_EXP_DECL int       pcre2_set_bsr(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_character_tables(pcre2_compile_context *, \
-                           const unsigned char *); \
-PCRE2_EXP_DECL int       pcre2_set_max_pattern_length(pcre2_compile_context *, \
-                           PCRE2_SIZE); \
-PCRE2_EXP_DECL int       pcre2_set_newline(pcre2_compile_context *, uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_parens_nest_limit(pcre2_compile_context *, \
-                           uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_compile_recursion_guard(\
-                           pcre2_compile_context *, int (*)(uint32_t, void *), \
-                           void *);
+PCRE2_EXP_DECL pcre2_compile_context PCRE2_CALL_CONVENTION \
+  *pcre2_compile_context_copy(pcre2_compile_context *); \
+PCRE2_EXP_DECL pcre2_compile_context PCRE2_CALL_CONVENTION \
+  *pcre2_compile_context_create(pcre2_general_context *);\
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_compile_context_free(pcre2_compile_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_bsr(pcre2_compile_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_character_tables(pcre2_compile_context *, const unsigned char *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_newline(pcre2_compile_context *, uint32_t); \
+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 *);
 
 #define PCRE2_MATCH_CONTEXT_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_match_context   *pcre2_match_context_copy(pcre2_match_context *); \
-PCRE2_EXP_DECL \
-  pcre2_match_context   *pcre2_match_context_create(pcre2_general_context *); \
-PCRE2_EXP_DECL void      pcre2_match_context_free(pcre2_match_context *); \
-PCRE2_EXP_DECL int       pcre2_set_callout(pcre2_match_context *, \
-                           int (*)(pcre2_callout_block *, void *), void *); \
-PCRE2_EXP_DECL int       pcre2_set_match_limit(pcre2_match_context *, \
-                           uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_offset_limit(pcre2_match_context *, \
-                           PCRE2_SIZE); \
-PCRE2_EXP_DECL int       pcre2_set_recursion_limit(pcre2_match_context *, \
-                           uint32_t); \
-PCRE2_EXP_DECL int       pcre2_set_recursion_memory_management( \
-                           pcre2_match_context *, void *(*)(PCRE2_SIZE, void *), \
-                           void (*)(void *, void *), void *);
+PCRE2_EXP_DECL pcre2_match_context PCRE2_CALL_CONVENTION \
+  *pcre2_match_context_copy(pcre2_match_context *); \
+PCRE2_EXP_DECL pcre2_match_context PCRE2_CALL_CONVENTION \
+  *pcre2_match_context_create(pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_match_context_free(pcre2_match_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_callout(pcre2_match_context *, \
+    int (*)(pcre2_callout_block *, 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 \
+  pcre2_set_heap_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_match_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_offset_limit(pcre2_match_context *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_recursion_memory_management(pcre2_match_context *, \
+    void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *);
+
+#define PCRE2_CONVERT_CONTEXT_FUNCTIONS \
+PCRE2_EXP_DECL pcre2_convert_context PCRE2_CALL_CONVENTION \
+  *pcre2_convert_context_copy(pcre2_convert_context *); \
+PCRE2_EXP_DECL pcre2_convert_context PCRE2_CALL_CONVENTION \
+  *pcre2_convert_context_create(pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_convert_context_free(pcre2_convert_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_glob_escape(pcre2_convert_context *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_set_glob_separator(pcre2_convert_context *, uint32_t);
 
 
 /* Functions concerned with compiling a pattern to PCRE internal code. */
 
 #define PCRE2_COMPILE_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_code            *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \
-                           int *, PCRE2_SIZE *, pcre2_compile_context *); \
-PCRE2_EXP_DECL void      pcre2_code_free(pcre2_code *); \
-PCRE2_EXP_DECL \
-  pcre2_code            *pcre2_code_copy(const pcre2_code *);
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+  *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, int *, PCRE2_SIZE *, \
+    pcre2_compile_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_code_free(pcre2_code *); \
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+  *pcre2_code_copy(const pcre2_code *); \
+PCRE2_EXP_DECL pcre2_code PCRE2_CALL_CONVENTION \
+  *pcre2_code_copy_with_tables(const pcre2_code *);
 
 
 /* Functions that give information about a compiled pattern. */
 
 #define PCRE2_PATTERN_INFO_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_pattern_info(const pcre2_code *, uint32_t, \
-                           void *); \
-PCRE2_EXP_DECL int       pcre2_callout_enumerate(const pcre2_code *, \
-                           int (*)(pcre2_callout_enumerate_block *, void *), \
-                           void *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_pattern_info(const pcre2_code *, uint32_t, void *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_callout_enumerate(const pcre2_code *, \
+    int (*)(pcre2_callout_enumerate_block *, void *), void *);
 
 
 /* Functions for running a match and inspecting the result. */
 
 #define PCRE2_MATCH_FUNCTIONS \
-PCRE2_EXP_DECL \
-  pcre2_match_data        *pcre2_match_data_create(uint32_t, \
-                             pcre2_general_context *); \
-PCRE2_EXP_DECL \
-  pcre2_match_data        *pcre2_match_data_create_from_pattern(\
-                             const pcre2_code *, \
-                             pcre2_general_context *); \
-PCRE2_EXP_DECL int         pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, \
-                             PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                             pcre2_match_data *, pcre2_match_context *, int *, \
-                             PCRE2_SIZE); \
-PCRE2_EXP_DECL int         pcre2_match(const pcre2_code *, \
-                             PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                             pcre2_match_data *, pcre2_match_context *); \
-PCRE2_EXP_DECL void        pcre2_match_data_free(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SPTR  pcre2_get_mark(pcre2_match_data *); \
-PCRE2_EXP_DECL uint32_t    pcre2_get_ovector_count(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SIZE *pcre2_get_ovector_pointer(pcre2_match_data *); \
-PCRE2_EXP_DECL PCRE2_SIZE  pcre2_get_startchar(pcre2_match_data *);
+PCRE2_EXP_DECL pcre2_match_data PCRE2_CALL_CONVENTION \
+  *pcre2_match_data_create(uint32_t, pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_match_data PCRE2_CALL_CONVENTION \
+  *pcre2_match_data_create_from_pattern(const pcre2_code *, \
+    pcre2_general_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *, int *, PCRE2_SIZE); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_match_data_free(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \
+  pcre2_get_mark(pcre2_match_data *); \
+PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \
+  pcre2_get_ovector_count(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
+  *pcre2_get_ovector_pointer(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
+  pcre2_get_startchar(pcre2_match_data *);
 
 
 /* Convenience functions for handling matched substrings. */
 
 #define PCRE2_SUBSTRING_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_substring_copy_byname(pcre2_match_data *, \
-                           PCRE2_SPTR, PCRE2_UCHAR *, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_copy_bynumber(pcre2_match_data *, \
-                           uint32_t, PCRE2_UCHAR *, PCRE2_SIZE *); \
-PCRE2_EXP_DECL void      pcre2_substring_free(PCRE2_UCHAR *); \
-PCRE2_EXP_DECL int       pcre2_substring_get_byname(pcre2_match_data *, \
-                           PCRE2_SPTR, PCRE2_UCHAR **, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_get_bynumber(pcre2_match_data *, \
-                           uint32_t, PCRE2_UCHAR **, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_length_byname(pcre2_match_data *, \
-                           PCRE2_SPTR, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_length_bynumber(pcre2_match_data *, \
-                           uint32_t, PCRE2_SIZE *); \
-PCRE2_EXP_DECL int       pcre2_substring_nametable_scan(const pcre2_code *, \
-                           PCRE2_SPTR, PCRE2_SPTR *, PCRE2_SPTR *); \
-PCRE2_EXP_DECL int       pcre2_substring_number_from_name(\
-                           const pcre2_code *, PCRE2_SPTR); \
-PCRE2_EXP_DECL void      pcre2_substring_list_free(PCRE2_SPTR *); \
-PCRE2_EXP_DECL int       pcre2_substring_list_get(pcre2_match_data *, \
-                           PCRE2_UCHAR ***, PCRE2_SIZE **);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_copy_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR *, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_copy_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR *, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_substring_free(PCRE2_UCHAR *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_get_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_UCHAR **, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_get_bynumber(pcre2_match_data *, uint32_t, PCRE2_UCHAR **, \
+    PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_length_byname(pcre2_match_data *, PCRE2_SPTR, PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_length_bynumber(pcre2_match_data *, uint32_t, PCRE2_SIZE *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_nametable_scan(const pcre2_code *, PCRE2_SPTR, PCRE2_SPTR *, \
+    PCRE2_SPTR *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_substring_list_free(PCRE2_SPTR *); \
+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 \
-PCRE2_EXP_DECL int32_t   pcre2_serialize_encode(const pcre2_code **, \
-                           int32_t, uint8_t **, PCRE2_SIZE *, \
-                           pcre2_general_context *); \
-PCRE2_EXP_DECL int32_t   pcre2_serialize_decode(pcre2_code **, int32_t, \
-                           const uint8_t *, pcre2_general_context *); \
-PCRE2_EXP_DECL int32_t   pcre2_serialize_get_number_of_codes(const uint8_t *); \
-PCRE2_EXP_DECL void      pcre2_serialize_free(uint8_t *);
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+  pcre2_serialize_encode(const pcre2_code **, int32_t, uint8_t **, \
+    PCRE2_SIZE *, pcre2_general_context *); \
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+  pcre2_serialize_decode(pcre2_code **, int32_t, const uint8_t *, \
+    pcre2_general_context *); \
+PCRE2_EXP_DECL int32_t PCRE2_CALL_CONVENTION \
+  pcre2_serialize_get_number_of_codes(const uint8_t *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_serialize_free(uint8_t *);
 
 
 /* Convenience function for match + substitute. */
 
 #define PCRE2_SUBSTITUTE_FUNCTION \
-PCRE2_EXP_DECL int       pcre2_substitute(const pcre2_code *, \
-                           PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                           pcre2_match_data *, pcre2_match_context *, \
-                           PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, \
-                           PCRE2_SIZE *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_substitute(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *, PCRE2_SPTR, \
+    PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE *);
+
+
+/* Functions for converting pattern source strings. */
+
+#define PCRE2_CONVERT_FUNCTIONS \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_pattern_convert(PCRE2_SPTR, PCRE2_SIZE, uint32_t, PCRE2_UCHAR **, \
+    PCRE2_SIZE *, pcre2_convert_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_converted_pattern_free(PCRE2_UCHAR *);
 
 
 /* Functions for JIT processing */
 
 #define PCRE2_JIT_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_jit_compile(pcre2_code *, uint32_t); \
-PCRE2_EXP_DECL int       pcre2_jit_match(const pcre2_code *, \
-                           PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
-                           pcre2_match_data *, pcre2_match_context *); \
-PCRE2_EXP_DECL void      pcre2_jit_free_unused_memory(pcre2_general_context *); \
-PCRE2_EXP_DECL \
-  pcre2_jit_stack       *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, \
-                           pcre2_general_context *); \
-PCRE2_EXP_DECL void      pcre2_jit_stack_assign(pcre2_match_context *, \
-                           pcre2_jit_callback, void *); \
-PCRE2_EXP_DECL void      pcre2_jit_stack_free(pcre2_jit_stack *);
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_jit_compile(pcre2_code *, uint32_t); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_jit_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
+    uint32_t, pcre2_match_data *, pcre2_match_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_jit_free_unused_memory(pcre2_general_context *); \
+PCRE2_EXP_DECL pcre2_jit_stack PCRE2_CALL_CONVENTION \
+  *pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+  pcre2_jit_stack_free(pcre2_jit_stack *);
 
 
 /* Other miscellaneous functions. */
 
 #define PCRE2_OTHER_FUNCTIONS \
-PCRE2_EXP_DECL int       pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \
-PCRE2_EXP_DECL \
-  const uint8_t         *pcre2_maketables(pcre2_general_context *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+  pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \
+PCRE2_EXP_DECL const uint8_t PCRE2_CALL_CONVENTION \
+  *pcre2_maketables(pcre2_general_context *); \
 
 
 /* Define macros that generate width-specific names from generic versions. The
@@ -576,6 +781,7 @@
 #define pcre2_real_code             PCRE2_SUFFIX(pcre2_real_code_)
 #define pcre2_real_general_context  PCRE2_SUFFIX(pcre2_real_general_context_)
 #define pcre2_real_compile_context  PCRE2_SUFFIX(pcre2_real_compile_context_)
+#define pcre2_real_convert_context  PCRE2_SUFFIX(pcre2_real_convert_context_)
 #define pcre2_real_match_context    PCRE2_SUFFIX(pcre2_real_match_context_)
 #define pcre2_real_jit_stack        PCRE2_SUFFIX(pcre2_real_jit_stack_)
 #define pcre2_real_match_data       PCRE2_SUFFIX(pcre2_real_match_data_)
@@ -587,6 +793,7 @@
 #define pcre2_callout_enumerate_block  PCRE2_SUFFIX(pcre2_callout_enumerate_block_)
 #define pcre2_general_context          PCRE2_SUFFIX(pcre2_general_context_)
 #define pcre2_compile_context          PCRE2_SUFFIX(pcre2_compile_context_)
+#define pcre2_convert_context          PCRE2_SUFFIX(pcre2_convert_context_)
 #define pcre2_match_context            PCRE2_SUFFIX(pcre2_match_context_)
 #define pcre2_match_data               PCRE2_SUFFIX(pcre2_match_data_)
 
@@ -595,12 +802,17 @@
 
 #define pcre2_callout_enumerate               PCRE2_SUFFIX(pcre2_callout_enumerate_)
 #define pcre2_code_copy                       PCRE2_SUFFIX(pcre2_code_copy_)
+#define pcre2_code_copy_with_tables           PCRE2_SUFFIX(pcre2_code_copy_with_tables_)
 #define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)
 #define pcre2_compile                         PCRE2_SUFFIX(pcre2_compile_)
 #define pcre2_compile_context_copy            PCRE2_SUFFIX(pcre2_compile_context_copy_)
 #define pcre2_compile_context_create          PCRE2_SUFFIX(pcre2_compile_context_create_)
 #define pcre2_compile_context_free            PCRE2_SUFFIX(pcre2_compile_context_free_)
 #define pcre2_config                          PCRE2_SUFFIX(pcre2_config_)
+#define pcre2_convert_context_copy            PCRE2_SUFFIX(pcre2_convert_context_copy_)
+#define pcre2_convert_context_create          PCRE2_SUFFIX(pcre2_convert_context_create_)
+#define pcre2_convert_context_free            PCRE2_SUFFIX(pcre2_convert_context_free_)
+#define pcre2_converted_pattern_free          PCRE2_SUFFIX(pcre2_converted_pattern_free_)
 #define pcre2_dfa_match                       PCRE2_SUFFIX(pcre2_dfa_match_)
 #define pcre2_general_context_copy            PCRE2_SUFFIX(pcre2_general_context_copy_)
 #define pcre2_general_context_create          PCRE2_SUFFIX(pcre2_general_context_create_)
@@ -624,6 +836,7 @@
 #define pcre2_match_data_create               PCRE2_SUFFIX(pcre2_match_data_create_)
 #define pcre2_match_data_create_from_pattern  PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_)
 #define pcre2_match_data_free                 PCRE2_SUFFIX(pcre2_match_data_free_)
+#define pcre2_pattern_convert                 PCRE2_SUFFIX(pcre2_pattern_convert_)
 #define pcre2_pattern_info                    PCRE2_SUFFIX(pcre2_pattern_info_)
 #define pcre2_serialize_decode                PCRE2_SUFFIX(pcre2_serialize_decode_)
 #define pcre2_serialize_encode                PCRE2_SUFFIX(pcre2_serialize_encode_)
@@ -632,14 +845,17 @@
 #define pcre2_set_bsr                         PCRE2_SUFFIX(pcre2_set_bsr_)
 #define pcre2_set_callout                     PCRE2_SUFFIX(pcre2_set_callout_)
 #define pcre2_set_character_tables            PCRE2_SUFFIX(pcre2_set_character_tables_)
+#define pcre2_set_compile_extra_options       PCRE2_SUFFIX(pcre2_set_compile_extra_options_)
 #define pcre2_set_compile_recursion_guard     PCRE2_SUFFIX(pcre2_set_compile_recursion_guard_)
+#define pcre2_set_depth_limit                 PCRE2_SUFFIX(pcre2_set_depth_limit_)
+#define pcre2_set_glob_escape                 PCRE2_SUFFIX(pcre2_set_glob_escape_)
+#define pcre2_set_glob_separator              PCRE2_SUFFIX(pcre2_set_glob_separator_)
+#define pcre2_set_heap_limit                  PCRE2_SUFFIX(pcre2_set_heap_limit_)
 #define pcre2_set_match_limit                 PCRE2_SUFFIX(pcre2_set_match_limit_)
 #define pcre2_set_max_pattern_length          PCRE2_SUFFIX(pcre2_set_max_pattern_length_)
 #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_recursion_limit             PCRE2_SUFFIX(pcre2_set_recursion_limit_)
-#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
 #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_)
@@ -653,6 +869,11 @@
 #define pcre2_substring_nametable_scan        PCRE2_SUFFIX(pcre2_substring_nametable_scan_)
 #define pcre2_substring_number_from_name      PCRE2_SUFFIX(pcre2_substring_number_from_name_)
 
+/* Keep this old function name for backwards compatibility */
+#define pcre2_set_recursion_limit PCRE2_SUFFIX(pcre2_set_recursion_limit_)
+
+/* Keep this obsolete function for backwards compatibility: it is now a noop. */
+#define pcre2_set_recursion_memory_management PCRE2_SUFFIX(pcre2_set_recursion_memory_management_)
 
 /* Now generate all three sets of width-specific structures and function
 prototypes. */
@@ -663,6 +884,8 @@
 PCRE2_GENERAL_INFO_FUNCTIONS \
 PCRE2_GENERAL_CONTEXT_FUNCTIONS \
 PCRE2_COMPILE_CONTEXT_FUNCTIONS \
+PCRE2_CONVERT_CONTEXT_FUNCTIONS \
+PCRE2_CONVERT_FUNCTIONS \
 PCRE2_MATCH_CONTEXT_FUNCTIONS \
 PCRE2_COMPILE_FUNCTIONS \
 PCRE2_PATTERN_INFO_FUNCTIONS \
@@ -692,6 +915,7 @@
 #undef PCRE2_GENERAL_INFO_FUNCTIONS
 #undef PCRE2_GENERAL_CONTEXT_FUNCTIONS
 #undef PCRE2_COMPILE_CONTEXT_FUNCTIONS
+#undef PCRE2_CONVERT_CONTEXT_FUNCTIONS
 #undef PCRE2_MATCH_CONTEXT_FUNCTIONS
 #undef PCRE2_COMPILE_FUNCTIONS
 #undef PCRE2_PATTERN_INFO_FUNCTIONS
@@ -729,4 +953,6 @@
 }  /* extern "C" */
 #endif
 
-#endif /* End of pcre2.h */
+#endif  /* PCRE2_H_IDEMPOTENT_GUARD */
+
+/* End of pcre2.h */
diff --git a/dist2/src/pcre2_auto_possess.c b/dist2/src/pcre2_auto_possess.c
index 8d0fa89..23275a2 100644
--- a/dist2/src/pcre2_auto_possess.c
+++ b/dist2/src/pcre2_auto_possess.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -558,54 +558,82 @@
     continue;
     }
 
+  /* At the end of a branch, skip to the end of the group. */
+
   if (c == OP_ALT)
     {
     do code += GET(code, 1); while (*code == OP_ALT);
     c = *code;
     }
 
+  /* Inspect the next opcode. */
+
   switch(c)
     {
-    case OP_END:
-    case OP_KETRPOS:
-    /* TRUE only in greedy case. The non-greedy case could be replaced by
-    an OP_EXACT, but it is probably not worth it. (And note that OP_EXACT
-    uses more memory, which we cannot get at this stage.) */
+    /* We can always possessify a greedy iterator at the end of the pattern,
+    which is reached after skipping over the final OP_KET. A non-greedy
+    iterator must never be possessified. */
 
+    case OP_END:
     return base_list[1] != 0;
 
+    /* When an iterator is at the end of certain kinds of group we can inspect
+    what follows the group by skipping over the closing ket. Note that this
+    does not apply to OP_KETRMAX or OP_KETRMIN because what follows any given
+    iteration is variable (could be another iteration or could be the next
+    item). As these two opcodes are not listed in the next switch, they will
+    end up as the next code to inspect, and return FALSE by virtue of being
+    unsupported. */
+
     case OP_KET:
-    /* If the bracket is capturing, and referenced by an OP_RECURSE, or
-    it is an atomic sub-pattern (assert, once, etc.) the non-greedy case
-    cannot be converted to a possessive form. */
+    case OP_KETRPOS:
+    /* The non-greedy case cannot be converted to a possessive form. */
 
     if (base_list[1] == 0) return FALSE;
 
+    /* If the bracket is capturing it might be referenced by an OP_RECURSE
+    so its last iterator can never be possessified if the pattern contains
+    recursions. (This could be improved by keeping a list of group numbers that
+    are called by recursion.) */
+
     switch(*(code - GET(code, 1)))
       {
+      case OP_CBRA:
+      case OP_SCBRA:
+      case OP_CBRAPOS:
+      case OP_SCBRAPOS:
+      if (cb->had_recurse) return FALSE;
+      break;
+
+      /* Atomic sub-patterns and 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_ASSERTBACK:
       case OP_ASSERTBACK_NOT:
       case OP_ONCE:
-      case OP_ONCE_NC:
-      /* Atomic sub-patterns and 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. */
 
       return !entered_a_group;
       }
 
+    /* Skip over the bracket and inspect what comes next. */
+
     code += PRIV(OP_lengths)[c];
     continue;
 
+    /* Handle cases where the next item is a group. */
+
     case OP_ONCE:
-    case OP_ONCE_NC:
     case OP_BRA:
     case OP_CBRA:
     next_code = code + GET(code, 1);
     code += PRIV(OP_lengths)[c];
 
+    /* Check each branch. We have to recurse a level for all but the last
+    branch. */
+
     while (*next_code == OP_ALT)
       {
       if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit))
@@ -621,8 +649,8 @@
     case OP_BRAMINZERO:
 
     next_code = code + 1;
-    if (*next_code != OP_BRA && *next_code != OP_CBRA
-        && *next_code != OP_ONCE && *next_code != OP_ONCE_NC) return FALSE;
+    if (*next_code != OP_BRA && *next_code != OP_CBRA &&
+        *next_code != OP_ONCE) return FALSE;
 
     do next_code += GET(next_code, 1); while (*next_code == OP_ALT);
 
@@ -635,11 +663,15 @@
     code += PRIV(OP_lengths)[c];
     continue;
 
+    /* The next opcode does not need special handling; fall through and use it
+    to see if the base can be possessified. */
+
     default:
     break;
     }
 
-  /* Check for a supported opcode, and load its properties. */
+  /* We now have the next appropriate opcode to compare with the base. Check
+  for a supported opcode, and load its properties. */
 
   code = get_chr_property_list(code, utf, cb->fcc, list);
   if (code == NULL) return FALSE;    /* Unsupported */
@@ -1046,8 +1078,10 @@
 
 /* Replaces single character iterations with their possessive alternatives
 if appropriate. This function modifies the compiled opcode! Hitting a
-non-existant opcode may indicate a bug in PCRE2, but it can also be caused if a
-bad UTF string was compiled with PCRE2_NO_UTF_CHECK.
+non-existent opcode may indicate a bug in PCRE2, but it can also be caused if a
+bad UTF string was compiled with PCRE2_NO_UTF_CHECK. The rec_limit catches
+overly complicated or large patterns. In these cases, the check just stops,
+leaving the remainder of the pattern unpossessified.
 
 Arguments:
   code        points to start of the byte code
@@ -1061,17 +1095,17 @@
 int
 PRIV(auto_possessify)(PCRE2_UCHAR *code, BOOL utf, const compile_block *cb)
 {
-register PCRE2_UCHAR c;
+PCRE2_UCHAR c;
 PCRE2_SPTR end;
 PCRE2_UCHAR *repeat_opcode;
 uint32_t list[8];
-int rec_limit;
+int rec_limit = 1000;  /* Was 10,000 but clang+ASAN uses a lot of stack. */
 
 for (;;)
   {
   c = *code;
 
-  if (c > OP_TABLE_LENGTH) return -1;   /* Something gone wrong */
+  if (c >= OP_TABLE_LENGTH) return -1;   /* Something gone wrong */
 
   if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
     {
@@ -1080,7 +1114,6 @@
       get_chr_property_list(code, utf, cb->fcc, list) : NULL;
     list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
 
-    rec_limit = 1000;
     if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit))
       {
       switch(c)
@@ -1137,7 +1170,6 @@
 
       list[1] = (c & 1) == 0;
 
-      rec_limit = 1000;
       if (compare_opcodes(end, utf, cb, list, end, &rec_limit))
         {
         switch (c)
diff --git a/dist2/src/pcre2_compile.c b/dist2/src/pcre2_compile.c
index bb9736c..87530fb 100644
--- a/dist2/src/pcre2_compile.c
+++ b/dist2/src/pcre2_compile.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -58,9 +58,14 @@
 #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
 #endif
 #include "pcre2_printint.c"
-#define CALL_PRINTINT
+#define DEBUG_CALL_PRINTINT
 #endif
 
+/* Other debugging code can be enabled by these defines. */
+
+// #define DEBUG_SHOW_CAPTURES
+// #define DEBUG_SHOW_PARSED
+
 /* There are a few things that vary with different code unit sizes. Handle them
 by defining macros in order to minimize #if usage. */
 
@@ -79,16 +84,56 @@
 #endif
 #endif
 
+/* Macros to store and retrieve a PCRE2_SIZE value in the parsed pattern, which
+consists of uint32_t elements. Assume that if uint32_t can't hold it, two of
+them will be able to (i.e. assume a 64-bit world). */
+
+#if PCRE2_SIZE_MAX <= UINT32_MAX
+#define PUTOFFSET(s,p) *p++ = s
+#define GETOFFSET(s,p) s = *p++
+#define GETPLUSOFFSET(s,p) s = *(++p)
+#define READPLUSOFFSET(s,p) s = p[1]
+#define SKIPOFFSET(p) p++
+#define SIZEOFFSET 1
+#else
+#define PUTOFFSET(s,p) \
+  { *p++ = (uint32_t)(s >> 32); *p++ = (uint32_t)(s & 0xffffffff); }
+#define GETOFFSET(s,p) \
+  { s = ((PCRE2_SIZE)p[0] << 32) | (PCRE2_SIZE)p[1]; p += 2; }
+#define GETPLUSOFFSET(s,p) \
+  { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; p += 2; }
+#define READPLUSOFFSET(s,p) \
+  { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; }
+#define SKIPOFFSET(p) p += 2
+#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(uint8_t *, PCRE2_UCHAR **, uint32_t, compile_block *,
-    const uint32_t *, unsigned int);
+  add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t,
+    compile_block *, const uint32_t *, unsigned int);
+#endif
+
+static int
+  compile_regex(uint32_t, PCRE2_UCHAR **, uint32_t **, int *, uint32_t,
+    uint32_t *, int32_t *, uint32_t *, int32_t *, branch_chain *,
+    compile_block *, PCRE2_SIZE *);
+
+static int
+  get_branchlength(uint32_t **, int *, int *, parsed_recurse_check *,
+    compile_block *);
 
 static BOOL
-  compile_regex(uint32_t, PCRE2_UCHAR **, PCRE2_SPTR *, int *, BOOL, BOOL,
-    uint32_t, int, uint32_t *, int32_t *, uint32_t *, int32_t *,
-    branch_chain *, compile_block *, size_t *);
+  set_lookbehind_lengths(uint32_t **, int *, int *, parsed_recurse_check *,
+    compile_block *);
 
 
 
@@ -96,9 +141,15 @@
 *      Code parameters and static tables         *
 *************************************************/
 
-/* This value specifies the size of stack workspace, which is used in different
-ways in the different pattern scans. The group-identifying pre-scan uses it to
-handle nesting, and needs it to be 16-bit aligned.
+#define MAX_GROUP_NUMBER   65535u
+#define MAX_REPEAT_COUNT   65535u
+#define REPEAT_UNLIMITED   (MAX_REPEAT_COUNT+1)
+
+/* COMPILE_WORK_SIZE specifies the size of stack workspace, which is used in
+different ways in the different pattern scans. The parsing and group-
+identifying pre-scan uses it to handle nesting, and needs it to be 16-bit
+aligned for this. Having defined the size in code units, we set up
+C16_WORK_SIZE as the number of elements in the 16-bit vector.
 
 During the first compiling phase, when determining how much memory is required,
 the regex is partly compiled into this space, but the compiled parts are
@@ -107,16 +158,18 @@
 pathological patterns. The size of the workspace depends on LINK_SIZE because
 the length of compiled items varies with this.
 
-In the real compile phase, the workspace is used for remembering data about
-numbered groups, provided there are not too many of them (if there are, extra
-memory is acquired). For this phase the memory must be 32-bit aligned. Having
-defined the size in code units, we set up C32_WORK_SIZE as the number of
-elements in the 32-bit vector. */
+In the real compile phase, this workspace is not currently used. */
 
-#define COMPILE_WORK_SIZE (2048*LINK_SIZE)   /* Size in code units */
+#define COMPILE_WORK_SIZE (3000*LINK_SIZE)   /* Size in code units */
 
-#define C32_WORK_SIZE \
-  ((COMPILE_WORK_SIZE * sizeof(PCRE2_UCHAR))/sizeof(uint32_t))
+#define C16_WORK_SIZE \
+  ((COMPILE_WORK_SIZE * sizeof(PCRE2_UCHAR))/sizeof(uint16_t))
+
+/* A uint32_t vector is used for caching information about the size of
+capturing groups, to improve performance. A default is created on the stack of
+this size. */
+
+#define GROUPINFO_DEFAULT_SIZE 256
 
 /* The overrun tests check for a slightly smaller size so that they detect the
 overrun before it actually does run off the end of the data block. */
@@ -130,25 +183,176 @@
 
 #define NAMED_GROUP_LIST_SIZE  20
 
-/* The original PCRE required patterns to be zero-terminated, and it simplifies
-the compiling code if it is guaranteed that there is a zero code unit at the
-end of the pattern, because this means that tests for coding sequences such as
-(*SKIP) or even just (?<= can check a sequence of code units without having to
-keep checking for the end of the pattern. The new PCRE2 API allows zero code
-units within patterns if a positive length is given, but in order to keep most
-of the compiling code as it was, we copy such patterns and add a zero on the
-end. This value determines the size of space on the stack that is used if the
-pattern fits; if not, heap memory is used. */
+/* The pre-compiling pass over the pattern creates a parsed pattern in a vector
+of uint32_t. For short patterns this lives on the stack, with this size. Heap
+memory is used for longer patterns. */
 
-#define COPIED_PATTERN_SIZE 1024
+#define PARSED_PATTERN_DEFAULT_SIZE 1024
 
 /* Maximum length value to check against when making sure that the variable
 that holds the compiled pattern length does not overflow. We make it a bit less
-than INT_MAX to allow for adding in group terminating bytes, so that we don't
-have to check them every time. */
+than INT_MAX to allow for adding in group terminating code units, so that we
+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  /* (?(<name>)... */
+#define META_COND_NUMBER      0x80120000u  /* (?(digits)... */
+#define META_COND_RNAME       0x80130000u  /* (?(R&name)... */
+#define META_COND_RNUMBER     0x80140000u  /* (?(Rdigits)... */
+#define META_COND_VERSION     0x80150000u  /* (?(VERSION<op>x.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) */
+
+/* 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        0x80220000u  /* (?= */
+#define META_LOOKAHEADNOT     0x80230000u  /* (?! */
+#define META_LOOKBEHIND       0x80240000u  /* (?<= */
+#define META_LOOKBEHINDNOT    0x80250000u  /* (?<! */
+
+/* These must be kept in this order, with consecutive values, and the _ARG
+versions of PRUNE, SKIP, and THEN immediately after their non-argument
+versions. */
+
+#define META_MARK             0x80260000u  /* (*MARK) */
+#define META_ACCEPT           0x80270000u  /* (*ACCEPT) */
+#define META_COMMIT           0x80280000u  /* (*COMMIT) */
+#define META_FAIL             0x80290000u  /* (*FAIL) */
+#define META_PRUNE            0x802a0000u  /* These pairs must    */
+#define META_PRUNE_ARG        0x802b0000u  /*   be                */
+#define META_SKIP             0x802c0000u  /*     kept            */
+#define META_SKIP_ARG         0x802d0000u  /*         in          */
+#define META_THEN             0x802e0000u  /*           this      */
+#define META_THEN_ARG         0x802f0000u  /*               order */
+
+/* These must be kept in groups of adjacent 3 values, and all together. */
+
+#define META_ASTERISK         0x80300000u  /* *  */
+#define META_ASTERISK_PLUS    0x80310000u  /* *+ */
+#define META_ASTERISK_QUERY   0x80320000u  /* *? */
+#define META_PLUS             0x80330000u  /* +  */
+#define META_PLUS_PLUS        0x80340000u  /* ++ */
+#define META_PLUS_QUERY       0x80350000u  /* +? */
+#define META_QUERY            0x80360000u  /* ?  */
+#define META_QUERY_PLUS       0x80370000u  /* ?+ */
+#define META_QUERY_QUERY      0x80380000u  /* ?? */
+#define META_MINMAX           0x80390000u  /* {n,m}  repeat */
+#define META_MINMAX_PLUS      0x803a0000u  /* {n,m}+ repeat */
+#define META_MINMAX_QUERY     0x803b0000u  /* {n,m}? repeat */
+
+#define META_FIRST_QUANTIFIER META_ASTERISK
+#define META_LAST_QUANTIFIER  META_MINMAX_QUERY
+
+/* Table of extra lengths for each of the meta codes. Must be kept in step with
+the definitions above. For some items these values are a basic length to which
+a variable amount has to be added. */
+
+static unsigned char meta_extra_lengths[] = {
+  0,             /* META_END */
+  0,             /* META_ALT */
+  0,             /* META_ATOMIC */
+  0,             /* META_BACKREF - more if group is >= 10 */
+  1+SIZEOFFSET,  /* META_BACKREF_BYNAME */
+  1,             /* META_BIGVALUE */
+  3,             /* META_CALLOUT_NUMBER */
+  3+SIZEOFFSET,  /* META_CALLOUT_STRING */
+  0,             /* META_CAPTURE */
+  0,             /* META_CIRCUMFLEX */
+  0,             /* META_CLASS */
+  0,             /* META_CLASS_EMPTY */
+  0,             /* META_CLASS_EMPTY_NOT */
+  0,             /* META_CLASS_END */
+  0,             /* META_CLASS_NOT */
+  0,             /* META_COND_ASSERT */
+  SIZEOFFSET,    /* META_COND_DEFINE */
+  1+SIZEOFFSET,  /* META_COND_NAME */
+  1+SIZEOFFSET,  /* META_COND_NUMBER */
+  1+SIZEOFFSET,  /* META_COND_RNAME */
+  1+SIZEOFFSET,  /* META_COND_RNUMBER */
+  3,             /* META_COND_VERSION */
+  0,             /* META_DOLLAR */
+  0,             /* META_DOT */
+  0,             /* META_ESCAPE - more for ESC_P, ESC_p, ESC_g, ESC_k */
+  0,             /* META_KET */
+  0,             /* META_NOCAPTURE */
+  1,             /* META_OPTIONS */
+  1,             /* META_POSIX */
+  1,             /* META_POSIX_NEG */
+  0,             /* META_RANGE_ESCAPED */
+  0,             /* META_RANGE_LITERAL */
+  SIZEOFFSET,    /* META_RECURSE */
+  1+SIZEOFFSET,  /* META_RECURSE_BYNAME */
+  0,             /* META_LOOKAHEAD */
+  0,             /* META_LOOKAHEADNOT */
+  SIZEOFFSET,    /* META_LOOKBEHIND */
+  SIZEOFFSET,    /* META_LOOKBEHINDNOT */
+  1,             /* META_MARK - plus the string length */
+  0,             /* META_ACCEPT */
+  0,             /* META_COMMIT */
+  0,             /* META_FAIL */
+  0,             /* META_PRUNE */
+  1,             /* META_PRUNE_ARG - plus the string length */
+  0,             /* META_SKIP */
+  1,             /* META_SKIP_ARG - plus the string length */
+  0,             /* META_THEN */
+  1,             /* META_THEN_ARG - plus the string length */
+  0,             /* META_ASTERISK */
+  0,             /* META_ASTERISK_PLUS */
+  0,             /* META_ASTERISK_QUERY */
+  0,             /* META_PLUS */
+  0,             /* META_PLUS_PLUS */
+  0,             /* META_PLUS_QUERY */
+  0,             /* META_QUERY */
+  0,             /* META_QUERY_PLUS */
+  0,             /* META_QUERY_QUERY */
+  2,             /* META_MINMAX */
+  2,             /* META_MINMAX_PLUS */
+  2              /* META_MINMAX_QUERY */
+};
+
+/* Types for skipping parts of a parsed pattern. */
+
+enum { PSKIP_ALT, PSKIP_CLASS, PSKIP_KET };
+
 /* Macro for setting individual bits in class bitmaps. It took some
 experimenting to figure out how to stop gcc 5.3.0 from warning with
 -Wconversion. This version gets a warning:
@@ -170,17 +374,10 @@
 
 /* These flags are used in the groupinfo vector. */
 
-#define GI_SET_COULD_BE_EMPTY  0x80000000u
-#define GI_COULD_BE_EMPTY      0x40000000u
-#define GI_NOT_FIXED_LENGTH    0x20000000u
-#define GI_SET_FIXED_LENGTH    0x10000000u
+#define GI_SET_FIXED_LENGTH    0x80000000u
+#define GI_NOT_FIXED_LENGTH    0x40000000u
 #define GI_FIXED_LENGTH_MASK   0x0000ffffu
 
-/* This bit (which is greater than any UTF value) is used to indicate that a
-variable contains a number of code units instead of an actual code point. */
-
-#define UTF_LENGTH     0x10000000l
-
 /* This simple test for a decimal digit works for both ASCII/Unicode and EBCDIC
 and is fast (a good compiler can turn it into a subtraction and unsigned
 comparison). */
@@ -191,8 +388,8 @@
 locale, and may mark arbitrary characters as digits. We want to recognize only
 0-9, a-z, and A-Z as hex digits, which is why we have a private table here. It
 costs 256 bytes, but it is a lot faster than doing character value tests (at
-least in some simple cases I timed), and in some applications one wants PCRE to
-compile efficiently as well as match efficiently. The value in the table is
+least in some simple cases I timed), and in some applications one wants PCRE2
+to compile efficiently as well as match efficiently. The value in the table is
 the binary hex digit value, or 0xff for non-hex digits. */
 
 /* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
@@ -380,9 +577,9 @@
 platforms. */
 
 typedef struct verbitem {
-  int   len;                 /* Length of verb name */
-  int   op;                  /* Op when no arg, or -1 if arg mandatory */
-  int   op_arg;              /* Op when arg present, or -1 if not allowed */
+  unsigned int len;          /* Length of verb name */
+  uint32_t meta;             /* Base META_ code */
+  int has_arg;               /* Argument requirement */
 } verbitem;
 
 static const char verbnames[] =
@@ -397,32 +594,30 @@
   STRING_THEN;
 
 static const verbitem verbs[] = {
-  { 0, -1,        OP_MARK },
-  { 4, -1,        OP_MARK },
-  { 6, OP_ACCEPT, -1 },
-  { 6, OP_COMMIT, -1 },
-  { 1, OP_FAIL,   -1 },
-  { 4, OP_FAIL,   -1 },
-  { 5, OP_PRUNE,  OP_PRUNE_ARG },
-  { 4, OP_SKIP,   OP_SKIP_ARG  },
-  { 4, OP_THEN,   OP_THEN_ARG  }
+  { 0, META_MARK,   +1 },  /* > 0 => must have an argument */
+  { 4, META_MARK,   +1 },
+  { 6, META_ACCEPT, -1 },  /* < 0 => must not have an argument */
+  { 6, META_COMMIT, -1 },
+  { 1, META_FAIL,   -1 },
+  { 4, META_FAIL,   -1 },
+  { 5, META_PRUNE,   0 },  /* Argument is optional; bump META code if found */
+  { 4, META_SKIP,    0 },
+  { 4, META_THEN,    0 }
 };
 
 static const int verbcount = sizeof(verbs)/sizeof(verbitem);
 
+/* Verb opcodes, indexed by their META code offset from META_MARK. */
 
-/* Substitutes for [[:<:]] and [[:>:]], which mean start and end of word in
-another regex library. */
+static const uint32_t verbops[] = {
+  OP_MARK, OP_ACCEPT, OP_COMMIT, OP_FAIL, OP_PRUNE, OP_PRUNE_ARG, OP_SKIP,
+  OP_SKIP_ARG, OP_THEN, OP_THEN_ARG };
 
-static const PCRE2_UCHAR sub_start_of_word[] = {
-  CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK,
-  CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, CHAR_RIGHT_PARENTHESIS, '\0' };
+/* Offsets from OP_STAR for case-independent and negative repeat opcodes. */
 
-static const PCRE2_UCHAR sub_end_of_word[] = {
-  CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK,
-  CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w,
-  CHAR_RIGHT_PARENTHESIS, '\0' };
-
+static uint32_t chartypeoffset[] = {
+  OP_STAR - OP_STAR,    OP_STARI - OP_STAR,
+  OP_NOTSTAR - OP_STAR, OP_NOTSTARI - OP_STAR };
 
 /* Tables of names of POSIX character classes and their lengths. The names are
 now all in a single string, to reduce the number of relocations when a shared
@@ -444,7 +639,6 @@
 #define PC_PRINT  9
 #define PC_PUNCT 10
 
-
 /* 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
@@ -472,130 +666,53 @@
   cbit_xdigit,-1,          0              /* xdigit */
 };
 
-/* Table of substitutes for \d etc when PCRE2_UCP is set. They are replaced by
-Unicode property escapes. */
-
 #ifdef SUPPORT_UNICODE
-static const PCRE2_UCHAR string_PNd[]  = {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_pNd[]  = {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_PXsp[] = {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_pXsp[] = {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_PXwd[] = {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_pXwd[] = {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
 
-static PCRE2_SPTR substitutes[] = {
-  string_PNd,           /* \D */
-  string_pNd,           /* \d */
-  string_PXsp,          /* \S */   /* Xsp is Perl space, but from 8.34, Perl */
-  string_pXsp,          /* \s */   /* space and POSIX space are the same. */
-  string_PXwd,          /* \W */
-  string_pXwd           /* \w */
+/* The POSIX class Unicode property substitutes that are used in UCP mode must
+be in the order of the POSIX class names, defined above. */
+
+static int posix_substitutes[] = {
+  PT_GC, ucp_L,     /* alpha */
+  PT_PC, ucp_Ll,    /* lower */
+  PT_PC, ucp_Lu,    /* upper */
+  PT_ALNUM, 0,      /* alnum */
+  -1, 0,            /* ascii, treat as non-UCP */
+  -1, 1,            /* blank, treat as \h */
+  PT_PC, ucp_Cc,    /* cntrl */
+  PT_PC, ucp_Nd,    /* digit */
+  PT_PXGRAPH, 0,    /* graph */
+  PT_PXPRINT, 0,    /* print */
+  PT_PXPUNCT, 0,    /* punct */
+  PT_PXSPACE, 0,    /* space */   /* Xps is POSIX space, but from 8.34 */
+  PT_WORD, 0,       /* word  */   /* Perl and POSIX space are the same */
+  -1, 0             /* xdigit, treat as non-UCP */
 };
-
-/* The POSIX class substitutes must be in the order of the POSIX class names,
-defined above, and there are both positive and negative cases. NULL means no
-general substitute of a Unicode property escape (\p or \P). However, for some
-POSIX classes (e.g. graph, print, punct) a special property code is compiled
-directly. */
-
-static const PCRE2_UCHAR string_pCc[] =  {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_C, CHAR_c, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_pL[] =   {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_pLl[] =  {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_pLu[] =  {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_pXan[] = {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_h[] =    {
-  CHAR_BACKSLASH, CHAR_h, '\0' };
-static const PCRE2_UCHAR string_pXps[] = {
-  CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_PCc[] =  {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_C, CHAR_c, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_PL[] =   {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_PLl[] =  {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_PLu[] =  {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_PXan[] = {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const PCRE2_UCHAR string_H[] =    {
-  CHAR_BACKSLASH, CHAR_H, '\0' };
-static const PCRE2_UCHAR string_PXps[] = {
-  CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
-  CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-
-static PCRE2_SPTR posix_substitutes[] = {
-  string_pL,            /* alpha */
-  string_pLl,           /* lower */
-  string_pLu,           /* upper */
-  string_pXan,          /* alnum */
-  NULL,                 /* ascii */
-  string_h,             /* blank */
-  string_pCc,           /* cntrl */
-  string_pNd,           /* digit */
-  NULL,                 /* graph */
-  NULL,                 /* print */
-  NULL,                 /* punct */
-  string_pXps,          /* space */   /* Xps is POSIX space, but from 8.34 */
-  string_pXwd,          /* word  */   /* Perl and POSIX space are the same */
-  NULL,                 /* xdigit */
-  /* Negated cases */
-  string_PL,            /* ^alpha */
-  string_PLl,           /* ^lower */
-  string_PLu,           /* ^upper */
-  string_PXan,          /* ^alnum */
-  NULL,                 /* ^ascii */
-  string_H,             /* ^blank */
-  string_PCc,           /* ^cntrl */
-  string_PNd,           /* ^digit */
-  NULL,                 /* ^graph */
-  NULL,                 /* ^print */
-  NULL,                 /* ^punct */
-  string_PXps,          /* ^space */  /* Xps is POSIX space, but from 8.34 */
-  string_PXwd,          /* ^word */   /* Perl and POSIX space are the same */
-  NULL                  /* ^xdigit */
-};
-#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(PCRE2_UCHAR *))
+#define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t)))
 #endif  /* SUPPORT_UNICODE */
 
-/* Masks for checking option settings. */
+/* Masks for checking option settings. When PCRE2_LITERAL is set, only a subset
+are allowed. */
+
+#define PUBLIC_LITERAL_COMPILE_OPTIONS \
+  (PCRE2_ANCHORED|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_ENDANCHORED| \
+   PCRE2_FIRSTLINE|PCRE2_LITERAL|PCRE2_NO_START_OPTIMIZE| \
+   PCRE2_NO_UTF_CHECK|PCRE2_USE_OFFSET_LIMIT|PCRE2_UTF)
 
 #define PUBLIC_COMPILE_OPTIONS \
-  (PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
-   PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \
-   PCRE2_DOTALL|PCRE2_DUPNAMES|PCRE2_EXTENDED|PCRE2_FIRSTLINE| \
-   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_NO_START_OPTIMIZE| \
-   PCRE2_NO_UTF_CHECK|PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_USE_OFFSET_LIMIT| \
-   PCRE2_UTF)
+  (PUBLIC_LITERAL_COMPILE_OPTIONS| \
+   PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
+   PCRE2_ALT_VERBNAMES|PCRE2_DOLLAR_ENDONLY|PCRE2_DOTALL|PCRE2_DUPNAMES| \
+   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)
+
+#define PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS \
+   (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD)
+
+#define PUBLIC_COMPILE_EXTRA_OPTIONS \
+   (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \
+    PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES|PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL)
 
 /* 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
@@ -611,21 +728,8 @@
        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 };
-
-/* Error codes that correspond to negative error codes returned by
-find_fixedlength(). */
-
-static int fixed_length_errors[] =
-  {
-  ERR0,    /* Not an error */
-  ERR0,    /* Not an error; -1 is used for "process later" */
-  ERR25,   /* Lookbehind is not fixed length */
-  ERR36,   /* \C in lookbehind is not allowed */
-  ERR87,   /* Lookbehind is too long */
-  ERR86,   /* Pattern too complicated */
-  ERR70    /* Internal error: unknown opcode encountered */
-  };
+       ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90,
+       ERR91, ERR92};
 
 /* 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
@@ -636,8 +740,9 @@
        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_LIMR };  /* Read integer value for recursion limit */
+       PSO_LIMD };  /* Read integer value for depth limit */
 
 typedef struct pso {
   const uint8_t *name;
@@ -658,12 +763,15 @@
   { (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_RECURSION_EQ,         16, PSO_LIMR, 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 }
@@ -728,6 +836,265 @@
 };
 
 
+#ifdef DEBUG_SHOW_PARSED
+/*************************************************
+*     Show the parsed pattern for debugging      *
+*************************************************/
+
+/* For debugging the pre-scan, this code, which outputs the parsed data vector,
+can be enabled. */
+
+static void show_parsed(compile_block *cb)
+{
+uint32_t *pptr = cb->parsed_pattern;
+
+for (;;)
+  {
+  int max, min;
+  PCRE2_SIZE offset;
+  uint32_t i;
+  uint32_t length;
+  uint32_t meta_arg = META_DATA(*pptr);
+
+  fprintf(stderr, "+++ %02d %.8x ", (int)(pptr - cb->parsed_pattern), *pptr);
+
+  if (*pptr < META_END)
+    {
+    if (*pptr > 32 && *pptr < 128) fprintf(stderr, "%c", *pptr);
+    pptr++;
+    }
+
+  else switch (META_CODE(*pptr++))
+    {
+    default:
+    fprintf(stderr, "**** OOPS - unknown META value - giving up ****\n");
+    return;
+
+    case META_END:
+    fprintf(stderr, "META_END\n");
+    return;
+
+    case META_CAPTURE:
+    fprintf(stderr, "META_CAPTURE %d", meta_arg);
+    break;
+
+    case META_RECURSE:
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "META_RECURSE %d %zd", meta_arg, offset);
+    break;
+
+    case META_BACKREF:
+    if (meta_arg < 10)
+      offset = cb->small_ref_offset[meta_arg];
+    else
+      GETOFFSET(offset, pptr);
+    fprintf(stderr, "META_BACKREF %d %zd", meta_arg, offset);
+    break;
+
+    case META_ESCAPE:
+    if (meta_arg == ESC_P || meta_arg == ESC_p)
+      {
+      uint32_t ptype = *pptr >> 16;
+      uint32_t pvalue = *pptr++ & 0xffff;
+      fprintf(stderr, "META \\%c %d %d", (meta_arg == ESC_P)? 'P':'p',
+        ptype, pvalue);
+      }
+    else
+      {
+      uint32_t cc;
+      /* There's just one escape we might have here that isn't negated in the
+      escapes table. */
+      if (meta_arg == ESC_g) cc = CHAR_g;
+      else for (cc = ESCAPES_FIRST; cc <= ESCAPES_LAST; cc++)
+        {
+        if (meta_arg == (uint32_t)(-escapes[cc - ESCAPES_FIRST])) break;
+        }
+      if (cc > ESCAPES_LAST) cc = CHAR_QUESTION_MARK;
+      fprintf(stderr, "META \\%c", cc);
+      }
+    break;
+
+    case META_MINMAX:
+    min = *pptr++;
+    max = *pptr++;
+    if (max != REPEAT_UNLIMITED)
+      fprintf(stderr, "META {%d,%d}", min, max);
+    else
+      fprintf(stderr, "META {%d,}", min);
+    break;
+
+    case META_MINMAX_QUERY:
+    min = *pptr++;
+    max = *pptr++;
+    if (max != REPEAT_UNLIMITED)
+      fprintf(stderr, "META {%d,%d}?", min, max);
+    else
+      fprintf(stderr, "META {%d,}?", min);
+    break;
+
+    case META_MINMAX_PLUS:
+    min = *pptr++;
+    max = *pptr++;
+    if (max != REPEAT_UNLIMITED)
+      fprintf(stderr, "META {%d,%d}+", min, max);
+    else
+      fprintf(stderr, "META {%d,}+", min);
+    break;
+
+    case META_BIGVALUE: fprintf(stderr, "META_BIGVALUE %.8x", *pptr++); break;
+    case META_CIRCUMFLEX: fprintf(stderr, "META_CIRCUMFLEX"); break;
+    case META_COND_ASSERT: fprintf(stderr, "META_COND_ASSERT"); break;
+    case META_DOLLAR: fprintf(stderr, "META_DOLLAR"); break;
+    case META_DOT: fprintf(stderr, "META_DOT"); break;
+    case META_ASTERISK: fprintf(stderr, "META *"); break;
+    case META_ASTERISK_QUERY: fprintf(stderr, "META *?"); break;
+    case META_ASTERISK_PLUS: fprintf(stderr, "META *+"); break;
+    case META_PLUS: fprintf(stderr, "META +"); break;
+    case META_PLUS_QUERY: fprintf(stderr, "META +?"); break;
+    case META_PLUS_PLUS: fprintf(stderr, "META ++"); break;
+    case META_QUERY: fprintf(stderr, "META ?"); break;
+    case META_QUERY_QUERY: fprintf(stderr, "META ??"); break;
+    case META_QUERY_PLUS: fprintf(stderr, "META ?+"); break;
+
+    case META_ATOMIC: fprintf(stderr, "META (?>"); break;
+    case META_NOCAPTURE: fprintf(stderr, "META (?:"); break;
+    case META_LOOKAHEAD: fprintf(stderr, "META (?="); break;
+    case META_LOOKAHEADNOT: fprintf(stderr, "META (?!"); break;
+    case META_KET: fprintf(stderr, "META )"); break;
+    case META_ALT: fprintf(stderr, "META | %d", meta_arg); break;
+
+    case META_CLASS: fprintf(stderr, "META ["); break;
+    case META_CLASS_NOT: fprintf(stderr, "META [^"); break;
+    case META_CLASS_END: fprintf(stderr, "META ]"); break;
+    case META_CLASS_EMPTY: fprintf(stderr, "META []"); break;
+    case META_CLASS_EMPTY_NOT: fprintf(stderr, "META [^]"); break;
+
+    case META_RANGE_LITERAL: fprintf(stderr, "META - (literal)"); break;
+    case META_RANGE_ESCAPED: fprintf(stderr, "META - (escaped)"); break;
+
+    case META_POSIX: fprintf(stderr, "META_POSIX %d", *pptr++); break;
+    case META_POSIX_NEG: fprintf(stderr, "META_POSIX_NEG %d", *pptr++); break;
+
+    case META_ACCEPT: fprintf(stderr, "META (*ACCEPT)"); break;
+    case META_COMMIT: fprintf(stderr, "META (*COMMIT)"); break;
+    case META_FAIL: fprintf(stderr, "META (*FAIL)"); break;
+    case META_PRUNE: fprintf(stderr, "META (*PRUNE)"); break;
+    case META_SKIP: fprintf(stderr, "META (*SKIP)"); break;
+    case META_THEN: fprintf(stderr, "META (*THEN)"); break;
+
+    case META_OPTIONS: fprintf(stderr, "META_OPTIONS 0x%02x", *pptr++); break;
+
+    case META_LOOKBEHIND:
+    fprintf(stderr, "META (?<= %d offset=", meta_arg);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    case META_LOOKBEHINDNOT:
+    fprintf(stderr, "META (?<! %d offset=", meta_arg);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    case META_CALLOUT_NUMBER:
+    fprintf(stderr, "META (?C%d) next=%d/%d", pptr[2], pptr[0],
+       pptr[1]);
+    pptr += 3;
+    break;
+
+    case META_CALLOUT_STRING:
+      {
+      uint32_t patoffset = *pptr++;    /* Offset of next pattern item */
+      uint32_t patlength = *pptr++;    /* Length of next pattern item */
+      fprintf(stderr, "META (?Cstring) length=%d offset=", *pptr++);
+      GETOFFSET(offset, pptr);
+      fprintf(stderr, "%zd next=%d/%d", offset, patoffset, patlength);
+      }
+    break;
+
+    case META_RECURSE_BYNAME:
+    fprintf(stderr, "META (?(&name) length=%d offset=", *pptr++);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    case META_BACKREF_BYNAME:
+    fprintf(stderr, "META_BACKREF_BYNAME length=%d offset=", *pptr++);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    case META_COND_NUMBER:
+    fprintf(stderr, "META_COND_NUMBER %d offset=", pptr[SIZEOFFSET]);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    pptr++;
+    break;
+
+    case META_COND_DEFINE:
+    fprintf(stderr, "META (?(DEFINE) offset=");
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    case META_COND_VERSION:
+    fprintf(stderr, "META (?(VERSION%s", (*pptr++ == 0)? "=" : ">=");
+    fprintf(stderr, "%d.", *pptr++);
+    fprintf(stderr, "%d)", *pptr++);
+    break;
+
+    case META_COND_NAME:
+    fprintf(stderr, "META (?(<name>) length=%d offset=", *pptr++);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    case META_COND_RNAME:
+    fprintf(stderr, "META (?(R&name) length=%d offset=", *pptr++);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    /* This is kept as a name, because it might be. */
+
+    case META_COND_RNUMBER:
+    fprintf(stderr, "META (?(Rnumber) length=%d offset=", *pptr++);
+    GETOFFSET(offset, pptr);
+    fprintf(stderr, "%zd", offset);
+    break;
+
+    case META_MARK:
+    fprintf(stderr, "META (*MARK:");
+    goto SHOWARG;
+
+    case META_PRUNE_ARG:
+    fprintf(stderr, "META (*PRUNE:");
+    goto SHOWARG;
+
+    case META_SKIP_ARG:
+    fprintf(stderr, "META (*SKIP:");
+    goto SHOWARG;
+
+    case META_THEN_ARG:
+    fprintf(stderr, "META (*THEN:");
+    SHOWARG:
+    length = *pptr++;
+    for (i = 0; i < length; i++)
+      {
+      uint32_t cc = *pptr++;
+      if (cc > 32 && cc < 128) fprintf(stderr, "%c", cc);
+        else fprintf(stderr, "\\x{%x}", cc);
+      }
+    fprintf(stderr, ") length=%u", length);
+    break;
+    }
+  fprintf(stderr, "\n");
+  }
+return;
+}
+#endif  /* DEBUG_SHOW_PARSED */
+
+
 
 /*************************************************
 *               Copy compiled code               *
@@ -763,6 +1130,45 @@
 
 
 /*************************************************
+*     Copy compiled code and character tables    *
+*************************************************/
+
+/* Compiled JIT code cannot be copied, so the new compiled block has no
+associated JIT data. This version of code_copy also makes a separate copy of
+the character tables. */
+
+PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
+pcre2_code_copy_with_tables(const pcre2_code *code)
+{
+PCRE2_SIZE* ref_count;
+pcre2_code *newcode;
+uint8_t *newtables;
+
+if (code == NULL) return NULL;
+newcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);
+if (newcode == NULL) return NULL;
+memcpy(newcode, code, code->blocksize);
+newcode->executable_jit = NULL;
+
+newtables = code->memctl.malloc(tables_length + sizeof(PCRE2_SIZE),
+  code->memctl.memory_data);
+if (newtables == NULL)
+  {
+  code->memctl.free((void *)newcode, code->memctl.memory_data);
+  return NULL;
+  }
+memcpy(newtables, code->tables, tables_length);
+ref_count = (PCRE2_SIZE *)(newtables + tables_length);
+*ref_count = 1;
+
+newcode->tables = newtables;
+newcode->flags |= PCRE2_DEREF_TABLES;
+return newcode;
+}
+
+
+
+/*************************************************
 *               Free compiled code               *
 *************************************************/
 
@@ -798,473 +1204,3058 @@
 
 
 /*************************************************
-*        Insert an automatic callout point       *
+*         Read a number, possibly signed         *
 *************************************************/
 
-/* This function is called when the PCRE2_AUTO_CALLOUT option is set, to insert
-callout points before each pattern item.
+/* This function is used to read numbers in the pattern. The initial pointer
+must be the sign or first digit of the number. When relative values (introduced
+by + or -) are allowed, they are relative group numbers, and the result must be
+greater than zero.
 
 Arguments:
-  code           current code pointer
-  ptr            current pattern pointer
-  cb             general compile-time data
+  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_error   the error to give for an over-large number
+  intptr      where to put the result
+  errcodeptr  where to put an error code
 
-Returns:         new code pointer
+Returns:      TRUE  - a number was read
+              FALSE - errorcode == 0 => no number was found
+                      errorcode != 0 => an error occurred
 */
 
-static PCRE2_UCHAR *
-auto_callout(PCRE2_UCHAR *code, PCRE2_SPTR ptr, compile_block *cb)
+static BOOL
+read_number(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, int32_t allow_sign,
+  uint32_t max_value, uint32_t max_error, int *intptr, int *errorcodeptr)
 {
-code[0] = OP_CALLOUT;
-PUT(code, 1, ptr - cb->start_pattern);  /* Pattern offset */
-PUT(code, 1 + LINK_SIZE, 0);            /* Default length */
-code[1 + 2*LINK_SIZE] = 255;
-return code + PRIV(OP_lengths)[OP_CALLOUT];
-}
+int sign = 0;
+uint32_t n = 0;
+PCRE2_SPTR ptr = *ptrptr;
+BOOL yield = FALSE;
 
+*errorcodeptr = 0;
 
-
-/*************************************************
-*         Complete a callout item                *
-*************************************************/
-
-/* A callout item contains the length of the next item in the pattern, which
-we can't fill in till after we have reached the relevant point. This is used
-for both automatic and manual callouts.
-
-Arguments:
-  previous_callout   points to previous callout item
-  ptr                current pattern pointer
-  cb                 general compile-time data
-
-Returns:             nothing
-*/
-
-static void
-complete_callout(PCRE2_UCHAR *previous_callout, PCRE2_SPTR ptr,
-  compile_block *cb)
-{
-size_t length = (size_t)(ptr - cb->start_pattern - GET(previous_callout, 1));
-PUT(previous_callout, 1 + LINK_SIZE, length);
-}
-
-
-
-/*************************************************
-*        Find the fixed length of a branch       *
-*************************************************/
-
-/* Scan a branch and compute the fixed length of subject that will match it, if
-the length is fixed. This is needed for dealing with lookbehind assertions. In
-UTF mode, the result is in code units rather than bytes. The branch is
-temporarily terminated with OP_END when this function is called.
-
-This function is called when a lookbehind assertion is encountered, so that if
-it fails, the error message can point to the correct place in the pattern.
-However, we cannot do this when the assertion contains subroutine calls,
-because they can be forward references. We solve this by remembering this case
-and doing the check at the end; a flag specifies which mode we are running in.
-
-Lookbehind lengths are held in 16-bit fields and the maximum value is defined
-as LOOKBEHIND_MAX.
-
-Arguments:
-  code        points to the start of the pattern (the bracket)
-  utf         TRUE in UTF mode
-  atend       TRUE if called when the pattern is complete
-  cb          the "compile data" structure
-  recurses    chain of recurse_check to catch mutual recursion
-  countptr    pointer to counter, to catch over-complexity
-
-Returns:   if non-negative, the fixed length,
-             or -1 if an OP_RECURSE item was encountered and atend is FALSE
-             or -2 if there is no fixed length,
-             or -3 if \C was encountered (in UTF mode only)
-             or -4 if length is too long
-             or -5 if regex is too complicated
-             or -6 if an unknown opcode was encountered (internal error)
-*/
-
-#define FFL_LATER           (-1)
-#define FFL_NOTFIXED        (-2)
-#define FFL_BACKSLASHC      (-3)
-#define FFL_TOOLONG         (-4)
-#define FFL_TOOCOMPLICATED  (-5)
-#define FFL_UNKNOWNOP       (-6)
-
-static int
-find_fixedlength(PCRE2_UCHAR *code, BOOL utf, BOOL atend, compile_block *cb,
-  recurse_check *recurses, int *countptr)
-{
-uint32_t length = 0xffffffffu;   /* Unset */
-uint32_t group = 0;
-uint32_t groupinfo = 0;
-recurse_check this_recurse;
-register uint32_t branchlength = 0;
-register PCRE2_UCHAR *cc = code + 1 + LINK_SIZE;
-
-/* If this is a capturing group, we may have the answer cached, but we can only
-use this information if there are no (?| groups in the pattern, because
-otherwise group numbers are not unique. */
-
-if (*code == OP_CBRA || *code == OP_CBRAPOS || *code == OP_SCBRA ||
-    *code == OP_SCBRAPOS)
+if (allow_sign >= 0 && ptr < ptrend)
   {
-  group = GET2(cc, 0);
-  cc += IMM2_SIZE;
-  groupinfo = cb->groupinfo[group];
-  if ((cb->external_flags & PCRE2_DUPCAPUSED) == 0)
+  if (*ptr == CHAR_PLUS)
     {
-    if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return FFL_NOTFIXED;
-    if ((groupinfo & GI_SET_FIXED_LENGTH) != 0)
-      return groupinfo & GI_FIXED_LENGTH_MASK;
+    sign = +1;
+    max_value -= allow_sign;
+    ptr++;
+    }
+  else if (*ptr == CHAR_MINUS)
+    {
+    sign = -1;
+    ptr++;
     }
   }
 
-/* A large and/or complex regex can take too long to process. This can happen
-more often when (?| groups are present in the pattern. */
-
-if ((*countptr)++ > 2000) return FFL_TOOCOMPLICATED;
-
-/* Scan along the opcodes for this branch. If we get to the end of the
-branch, check the length against that of the other branches. */
-
-for (;;)
+if (ptr >= ptrend || !IS_DIGIT(*ptr)) return FALSE;
+while (ptr < ptrend && IS_DIGIT(*ptr))
   {
-  int d;
-  PCRE2_UCHAR *ce, *cs;
-  register PCRE2_UCHAR op = *cc;
-
-  if (branchlength > LOOKBEHIND_MAX) return FFL_TOOLONG;
-
-  switch (op)
+  n = n * 10 + *ptr++ - CHAR_0;
+  if (n > max_value)
     {
-    /* We only need to continue for OP_CBRA (normal capturing bracket) and
-    OP_BRA (normal non-capturing bracket) because the other variants of these
-    opcodes are all concerned with unlimited repeated groups, which of course
-    are not of fixed length. */
+    *errorcodeptr = max_error;
+    goto EXIT;
+    }
+  }
 
-    case OP_CBRA:
-    case OP_BRA:
-    case OP_ONCE:
-    case OP_ONCE_NC:
-    case OP_COND:
-    d = find_fixedlength(cc, utf, atend, cb, recurses, countptr);
-    if (d < 0) return d;
-    branchlength += (uint32_t)d;
-    do cc += GET(cc, 1); while (*cc == OP_ALT);
-    cc += 1 + LINK_SIZE;
+if (allow_sign >= 0 && sign != 0)
+  {
+  if (n == 0)
+    {
+    *errorcodeptr = ERR26;  /* +0 and -0 are not allowed */
+    goto EXIT;
+    }
+
+  if (sign > 0) n += allow_sign;
+  else if ((int)n > allow_sign)
+    {
+    *errorcodeptr = ERR15;  /* Non-existent subpattern */
+    goto EXIT;
+    }
+  else n = allow_sign + 1 - n;
+  }
+
+yield = TRUE;
+
+EXIT:
+*intptr = n;
+*ptrptr = ptr;
+return yield;
+}
+
+
+
+/*************************************************
+*         Read repeat counts                     *
+*************************************************/
+
+/* Read an item of the form {n,m} and return the values if non-NULL pointers
+are supplied. Repeat counts must be less than 65536 (MAX_REPEAT_COUNT); a
+larger value is used for "unlimited". We have to use signed arguments for
+read_number() because it is capable of returning a signed value.
+
+Arguments:
+  ptrptr         points to pointer to character after'{'
+  ptrend         pointer to end of input
+  minp           if not NULL, pointer to int for min
+  maxp           if not NULL, pointer to int for max (-1 if no max)
+                 returned as -1 if no max
+  errorcodeptr   points to error code variable
+
+Returns:         FALSE if not a repeat quantifier, errorcode set zero
+                 FALSE on error, with errorcode set non-zero
+                 TRUE on success, with pointer updated to point after '}'
+*/
+
+static BOOL
+read_repeat_counts(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *minp,
+  uint32_t *maxp, int *errorcodeptr)
+{
+PCRE2_SPTR p = *ptrptr;
+BOOL yield = FALSE;
+int32_t min = 0;
+int32_t max = REPEAT_UNLIMITED; /* This value is larger than MAX_REPEAT_COUNT */
+
+/* NB read_number() initializes the error code to zero. The only error is for a
+number that is too big. */
+
+if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr))
+  goto EXIT;
+
+if (p >= ptrend) goto EXIT;
+
+if (*p == CHAR_RIGHT_CURLY_BRACKET)
+  {
+  p++;
+  max = min;
+  }
+
+else
+  {
+  if (*p++ != CHAR_COMMA || p >= ptrend) goto EXIT;
+  if (*p != CHAR_RIGHT_CURLY_BRACKET)
+    {
+    if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max,
+        errorcodeptr) || p >= ptrend ||  *p != CHAR_RIGHT_CURLY_BRACKET)
+      goto EXIT;
+    if (max < min)
+      {
+      *errorcodeptr = ERR4;
+      goto EXIT;
+      }
+    }
+  p++;
+  }
+
+yield = TRUE;
+if (minp != NULL) *minp = (uint32_t)min;
+if (maxp != NULL) *maxp = (uint32_t)max;
+
+/* Update the pattern pointer on success, or after an error, but not when
+the result is "not a repeat quantifier". */
+
+EXIT:
+if (yield || *errorcodeptr != 0) *ptrptr = p;
+return yield;
+
+
+
+}
+
+
+
+/*************************************************
+*            Handle escapes                      *
+*************************************************/
+
+/* 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
+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.
+
+Arguments:
+  ptrptr         points to the input position pointer
+  ptrend         points to the end of the input
+  chptr          points to a returned data character
+  errorcodeptr   points to the errorcode variable (containing zero)
+  options        the current options bits
+  isclass        TRUE if inside a character class
+  cb             compile data block
+
+Returns:         zero => a data character
+                 positive => a special escape sequence
+                 negative => a numerical back reference
+                 on error, errorcodeptr is set non-zero
+*/
+
+int
+PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr,
+  int *errorcodeptr, uint32_t options, BOOL isclass, compile_block *cb)
+{
+BOOL utf = (options & PCRE2_UTF) != 0;
+PCRE2_SPTR ptr = *ptrptr;
+uint32_t c, cc;
+int escape = 0;
+int i;
+
+/* If backslash is at the end of the string, it's an error. */
+
+if (ptr >= ptrend)
+  {
+  *errorcodeptr = ERR1;
+  return 0;
+  }
+
+GETCHARINCTEST(c, ptr);         /* Get character value, increment pointer */
+*errorcodeptr = 0;              /* Be optimistic */
+
+/* Non-alphanumerics are literals, so we just leave the value in c. An initial
+value test saves a memory lookup for code points outside the alphanumeric
+range. Otherwise, do a table lookup. A non-zero result is something that can be
+returned immediately. Otherwise further processing is required. */
+
+if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {}  /* Definitely literal */
+
+else if ((i = escapes[c - ESCAPES_FIRST]) != 0)
+  {
+  if (i > 0) c = (uint32_t)i; else  /* Positive is a data character */
+    {
+    escape = -i;                    /* Else return a special escape */
+    if (cb != NULL && (escape == ESC_P || escape == ESC_p || escape == ESC_X))
+      cb->external_flags |= PCRE2_HASBKPORX;   /* Note \P, \p, or \X */
+    }
+  }
+
+/* Escapes that need further processing, including those that are unknown.
+When called from pcre2_substitute(), only \c, \o, and \x are recognized (and \u
+when BSUX is set). */
+
+else
+  {
+  PCRE2_SPTR oldptr;
+  BOOL overflow;
+  int s;
+
+  /* Filter calls from pcre2_substitute(). */
+
+  if (cb == NULL && c != CHAR_c && c != CHAR_o && c != CHAR_x &&
+      (c != CHAR_u || (options & PCRE2_ALT_BSUX) != 0))
+    {
+    *errorcodeptr = ERR3;
+    return 0;
+    }
+
+  switch (c)
+    {
+    /* A number of Perl escapes are not handled by PCRE. We give an explicit
+    error. */
+
+    case CHAR_l:
+    case CHAR_L:
+    *errorcodeptr = ERR37;
     break;
 
-    /* Reached end of a branch; if it's a ket it is the end of a nested call.
-    If it's ALT it is an alternation in a nested call. An ACCEPT is effectively
-    an ALT. If it is END it's the end of the outer call. All can be handled by
-    the same code. Note that we must not include the OP_KETRxxx opcodes here,
-    because they all imply an unlimited repeat. */
+    /* \u is unrecognized when PCRE2_ALT_BSUX is not set. When it is treated
+    specially, \u must be followed by four hex digits. Otherwise it is a
+    lowercase u letter. */
 
-    case OP_ALT:
-    case OP_KET:
-    case OP_END:
-    case OP_ACCEPT:
-    case OP_ASSERT_ACCEPT:
-    if (length == 0xffffffffu) length = branchlength;
-      else if (length != branchlength) goto ISNOTFIXED;
-    if (*cc != OP_ALT)
+    case CHAR_u:
+    if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; else
       {
-      if (group > 0)
+      uint32_t xc;
+      if (ptrend - ptr < 4) break;              /* Less than 4 chars */
+      if ((cc = XDIGIT(ptr[0])) == 0xff) break;  /* Not a hex digit */
+      if ((xc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */
+      cc = (cc << 4) | xc;
+      if ((xc = XDIGIT(ptr[2])) == 0xff) break;  /* Not a hex digit */
+      cc = (cc << 4) | xc;
+      if ((xc = XDIGIT(ptr[3])) == 0xff) break;  /* Not a hex digit */
+      c = (cc << 4) | xc;
+      ptr += 4;
+      if (utf)
         {
-        groupinfo |= (uint32_t)(GI_SET_FIXED_LENGTH | length);
-        cb->groupinfo[group] = groupinfo;
+        if (c > 0x10ffffU) *errorcodeptr = ERR77;
+        else
+          if (c >= 0xd800 && c <= 0xdfff &&
+            (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
+              *errorcodeptr = ERR73;
         }
-      return (int)length;
+      else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77;
       }
-    cc += 1 + LINK_SIZE;
-    branchlength = 0;
     break;
 
-    /* A true recursion implies not fixed length, but a subroutine call may
-    be OK. If the subroutine is a forward reference, we can't deal with
-    it until the end of the pattern, so return FFL_LATER. */
+    /* \U is unrecognized unless PCRE2_ALT_BSUX is set, in which case it is an
+    upper case letter. */
 
-    case OP_RECURSE:
-    if (!atend) return FFL_LATER;
-    cs = ce = (PCRE2_UCHAR *)cb->start_code + GET(cc, 1); /* Start subpattern */
-    do ce += GET(ce, 1); while (*ce == OP_ALT);           /* End subpattern */
-    if (cc > cs && cc < ce) goto ISNOTFIXED;          /* Recursion */
-    else   /* Check for mutual recursion */
+    case CHAR_U:
+    if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37;
+    break;
+
+    /* In a character class, \g is just a literal "g". Outside a character
+    class, \g must be followed by one of a number of specific things:
+
+    (1) A number, either plain or braced. If positive, it is an absolute
+    backreference. If negative, it is a relative backreference. This is a Perl
+    5.10 feature.
+
+    (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
+    is part of Perl's movement towards a unified syntax for back references. As
+    this is synonymous with \k{name}, we fudge it up by pretending it really
+    was \k{name}.
+
+    (3) For Oniguruma compatibility we also support \g followed by a name or a
+    number either in angle brackets or in single quotes. However, these are
+    (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.
+    */
+
+    case CHAR_g:
+    if (isclass) break;
+
+    if (ptr >= ptrend)
       {
-      recurse_check *r = recurses;
-      for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
-      if (r != NULL) goto ISNOTFIXED;   /* Mutual recursion */
+      *errorcodeptr = ERR57;
+      break;
       }
-    this_recurse.prev = recurses;
-    this_recurse.group = cs;
-    d = find_fixedlength(cs, utf, atend, cb, &this_recurse, countptr);
-    if (d < 0) return d;
-    branchlength += (uint32_t)d;
-    cc += 1 + LINK_SIZE;
+
+    if (*ptr == CHAR_LESS_THAN_SIGN || *ptr == CHAR_APOSTROPHE)
+      {
+      escape = ESC_g;
+      break;
+      }
+
+    /* If there is a brace delimiter, try to read a numerical reference. If
+    there isn't one, assume we have a name and treat it as \k. */
+
+    if (*ptr == CHAR_LEFT_CURLY_BRACKET)
+      {
+      PCRE2_SPTR p = ptr + 1;
+      if (!read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s,
+          errorcodeptr))
+        {
+        if (*errorcodeptr == 0) escape = ESC_k;  /* No number found */
+        break;
+        }
+      if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET)
+        {
+        *errorcodeptr = ERR57;
+        break;
+        }
+      ptr = p + 1;
+      }
+
+    /* Read an undelimited number */
+
+    else
+      {
+      if (!read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s,
+          errorcodeptr))
+        {
+        if (*errorcodeptr == 0) *errorcodeptr = ERR57;  /* No number found */
+        break;
+        }
+      }
+
+    if (s <= 0)
+      {
+      *errorcodeptr = ERR15;
+      break;
+      }
+
+    escape = -s;
     break;
 
-    /* Skip over assertive subpatterns. Note that we must increment cc by
-    1 + LINK_SIZE at the end, not by OP_length[*cc] because in a recursive
-    situation this assertion may be the one that is ultimately being checked
-    for having a fixed length, in which case its terminating OP_KET will have
-    been temporarily replaced by OP_END. */
+    /* The handling of escape sequences consisting of a string of digits
+    starting with one that is not zero is not straightforward. Perl has changed
+    over the years. Nowadays \g{} for backreferences and \o{} for octal are
+    recommended to avoid the ambiguities in the old syntax.
 
-    case OP_ASSERT:
-    case OP_ASSERT_NOT:
-    case OP_ASSERTBACK:
-    case OP_ASSERTBACK_NOT:
-    do cc += GET(cc, 1); while (*cc == OP_ALT);
-    cc += 1 + LINK_SIZE;
-    break;
+    Outside a character class, the digits are read as a decimal number. If the
+    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).
 
-    /* Skip over things that don't match chars */
+    Inside a character class, \ followed by a digit is always either a literal
+    8 or 9 or an octal number. */
 
-    case OP_MARK:
-    case OP_PRUNE_ARG:
-    case OP_SKIP_ARG:
-    case OP_THEN_ARG:
-    cc += cc[1] + PRIV(OP_lengths)[*cc];
-    break;
+    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:
 
-    case OP_CALLOUT:
-    case OP_CIRC:
-    case OP_CIRCM:
-    case OP_CLOSE:
-    case OP_COMMIT:
-    case OP_CREF:
-    case OP_FALSE:
-    case OP_TRUE:
-    case OP_DNCREF:
-    case OP_DNRREF:
-    case OP_DOLL:
-    case OP_DOLLM:
-    case OP_EOD:
-    case OP_EODN:
-    case OP_FAIL:
-    case OP_NOT_WORD_BOUNDARY:
-    case OP_PRUNE:
-    case OP_REVERSE:
-    case OP_RREF:
-    case OP_SET_SOM:
-    case OP_SKIP:
-    case OP_SOD:
-    case OP_SOM:
-    case OP_THEN:
-    case OP_WORD_BOUNDARY:
-    cc += PRIV(OP_lengths)[*cc];
-    break;
+    if (!isclass)
+      {
+      oldptr = ptr;
+      ptr--;   /* Back to the digit */
+      if (!read_number(&ptr, ptrend, -1, INT_MAX/10 - 1, ERR61, &s,
+          errorcodeptr))
+        break;
 
-    case OP_CALLOUT_STR:
-    cc += GET(cc, 1 + 2*LINK_SIZE);
-    break;
+      /* \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. */
 
-    /* Handle literal characters */
+      if (s < 10 || oldptr[-1] >= CHAR_8 || s <= (int)cb->bracount)
+        {
+        if (s > (int)MAX_GROUP_NUMBER) *errorcodeptr = ERR61;
+          else escape = -s;     /* Indicates a back reference */
+        break;
+        }
+      ptr = oldptr;      /* Put the pointer back and fall through */
+      }
 
-    case OP_CHAR:
-    case OP_CHARI:
-    case OP_NOT:
-    case OP_NOTI:
-    branchlength++;
-    cc += 2;
-#ifdef SUPPORT_UNICODE
-    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
-    break;
+    /* Handle a digit following \ when the number is not a back reference, or
+    we are within a character class. If the first digit is 8 or 9, Perl used to
+    generate a binary zero and then treat the digit as a following literal. At
+    least by Perl 5.18 this changed so as not to insert the binary zero. */
 
-    /* Handle exact repetitions. The count is already in characters, but we
-    need to skip over a multibyte character in UTF8 mode.  */
+    if (c >= CHAR_8) break;
 
-    case OP_EXACT:
-    case OP_EXACTI:
-    case OP_NOTEXACT:
-    case OP_NOTEXACTI:
-    branchlength += GET2(cc,1);
-    cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UNICODE
-    if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
-    break;
-
-    case OP_TYPEEXACT:
-    branchlength += GET2(cc,1);
-    if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP)
-      cc += 2;
-    cc += 1 + IMM2_SIZE + 1;
-    break;
-
-    /* Handle single-char matchers */
-
-    case OP_PROP:
-    case OP_NOTPROP:
-    cc += 2;
     /* Fall through */
 
-    case OP_HSPACE:
-    case OP_VSPACE:
-    case OP_NOT_HSPACE:
-    case OP_NOT_VSPACE:
-    case OP_NOT_DIGIT:
-    case OP_DIGIT:
-    case OP_NOT_WHITESPACE:
-    case OP_WHITESPACE:
-    case OP_NOT_WORDCHAR:
-    case OP_WORDCHAR:
-    case OP_ANY:
-    case OP_ALLANY:
-    branchlength++;
-    cc++;
+    /* \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,
+    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 PCRE2_CODE_UNIT_WIDTH == 8
+    if (!utf && c > 0xff) *errorcodeptr = ERR51;
+#endif
     break;
 
-    /* The single-byte matcher isn't allowed. This only happens in UTF-8 or
-    UTF-16 mode; otherwise \C is coded as OP_ALLANY. */
+    /* \o is a relatively new Perl feature, supporting a more general way of
+    specifying character codes in octal. The only supported form is \o{ddd}. */
 
-    case OP_ANYBYTE:
-    return FFL_BACKSLASHC;
-
-    /* Check a class for variable quantification */
-
-    case OP_CLASS:
-    case OP_NCLASS:
-#ifdef SUPPORT_WIDE_CHARS
-    case OP_XCLASS:
-    /* The original code caused an unsigned overflow in 64 bit systems,
-    so now we use a conditional statement. */
-    if (op == OP_XCLASS)
-      cc += GET(cc, 1);
+    case CHAR_o:
+    if (ptr >= ptrend || *ptr++ != CHAR_LEFT_CURLY_BRACKET)
+      {
+      ptr--;
+      *errorcodeptr = ERR55;
+      }
+    else if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)
+      *errorcodeptr = ERR78;
     else
-      cc += PRIV(OP_lengths)[OP_CLASS];
+      {
+      c = 0;
+      overflow = FALSE;
+      while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7)
+        {
+        cc = *ptr++;
+        if (c == 0 && cc == CHAR_0) continue;     /* Leading zeroes */
+#if PCRE2_CODE_UNIT_WIDTH == 32
+        if (c >= 0x20000000l) { overflow = TRUE; break; }
+#endif
+        c = (c << 3) + (cc - CHAR_0);
+#if PCRE2_CODE_UNIT_WIDTH == 8
+        if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+        if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+        if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
+#endif
+        }
+      if (overflow)
+        {
+        while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;
+        *errorcodeptr = ERR34;
+        }
+      else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
+        {
+        if (utf && c >= 0xd800 && c <= 0xdfff && (cb == NULL ||
+            (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0))
+          {
+          ptr--;
+          *errorcodeptr = ERR73;
+          }
+        }
+      else
+        {
+        ptr--;
+        *errorcodeptr = ERR64;
+        }
+      }
+    break;
+
+    /* \x is complicated. When PCRE2_ALT_BSUX is set, \x must be followed by
+    two hexadecimal digits. Otherwise it is a lowercase x letter. */
+
+    case CHAR_x:
+    if ((options & PCRE2_ALT_BSUX) != 0)
+      {
+      uint32_t xc;
+      if (ptrend - ptr < 2) break;               /* Less than 2 characters */
+      if ((cc = XDIGIT(ptr[0])) == 0xff) break;  /* Not a hex digit */
+      if ((xc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */
+      c = (cc << 4) | xc;
+      ptr += 2;
+      }    /* End PCRE2_ALT_BSUX handling */
+
+    /* Handle \x in Perl's style. \x{ddd} is a character number which can be
+    greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex
+    digits. If not, { used to be treated as a data character. However, Perl
+    seems to read hex digits up to the first non-such, and ignore the rest, so
+    that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE
+    now gives an error. */
+
+    else
+      {
+      if (ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET)
+        {
+        if (++ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)
+          {
+          *errorcodeptr = ERR78;
+          break;
+          }
+        c = 0;
+        overflow = FALSE;
+
+        while (ptr < ptrend && (cc = XDIGIT(*ptr)) != 0xff)
+          {
+          ptr++;
+          if (c == 0 && cc == 0) continue;   /* Leading zeroes */
+#if PCRE2_CODE_UNIT_WIDTH == 32
+          if (c >= 0x10000000l) { overflow = TRUE; break; }
+#endif
+          c = (c << 4) | cc;
+          if ((utf && c > 0x10ffffU) || (!utf && c > MAX_NON_UTF_CHAR))
+            {
+            overflow = TRUE;
+            break;
+            }
+          }
+
+        if (overflow)
+          {
+          while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++;
+          *errorcodeptr = ERR34;
+          }
+        else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
+          {
+          if (utf && c >= 0xd800 && c <= 0xdfff && (cb == NULL ||
+              (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0))
+            {
+            ptr--;
+            *errorcodeptr = ERR73;
+            }
+          }
+
+        /* If the sequence of hex digits does not end with '}', give an error.
+        We used just to recognize this construct and fall through to the normal
+        \x handling, but nowadays Perl gives an error, which seems much more
+        sensible, so we do too. */
+
+        else
+          {
+          ptr--;
+          *errorcodeptr = ERR67;
+          }
+        }   /* End of \x{} processing */
+
+      /* Read a up to two hex digits after \x */
+
+      else
+        {
+        c = 0;
+        if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break;  /* Not a hex digit */
+        ptr++;
+        c = cc;
+        if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break;  /* Not a hex digit */
+        ptr++;
+        c = (c << 4) | cc;
+        }     /* End of \xdd handling */
+      }       /* End of Perl-style \x handling */
+    break;
+
+    /* The handling of \c is different in ASCII and EBCDIC environments. In an
+    ASCII (or Unicode) environment, an error is given if the character
+    following \c is not a printable ASCII character. Otherwise, the following
+    character is upper-cased if it is a letter, and after that the 0x40 bit is
+    flipped. The result is the value of the escape.
+
+    In an EBCDIC environment the handling of \c is compatible with the
+    specification in the perlebcdic document. The following character must be
+    a letter or one of small number of special characters. These provide a
+    means of defining the character values 0-31.
+
+    For testing the EBCDIC handling of \c in an ASCII environment, recognize
+    the EBCDIC value of 'c' explicitly. */
+
+#if defined EBCDIC && 'a' != 0x81
+    case 0x83:
 #else
-    cc += PRIV(OP_lengths)[OP_CLASS];
+    case CHAR_c:
+#endif
+    if (ptr >= ptrend)
+      {
+      *errorcodeptr = ERR2;
+      break;
+      }
+    c = *ptr;
+    if (c >= CHAR_a && c <= CHAR_z) c = UPPER_CASE(c);
+
+    /* Handle \c in an ASCII/Unicode environment. */
+
+#ifndef EBCDIC    /* ASCII/UTF-8 coding */
+    if (c < 32 || c > 126)  /* Excludes all non-printable ASCII */
+      {
+      *errorcodeptr = ERR68;
+      break;
+      }
+    c ^= 0x40;
+
+    /* Handle \c in an EBCDIC environment. The special case \c? is converted to
+    255 (0xff) or 95 (0x5f) if other character suggest we are using th POSIX-BC
+    encoding. (This is the way Perl indicates that it handles \c?.) The other
+    valid sequences correspond to a list of specific characters. */
+
+#else
+    if (c == CHAR_QUESTION_MARK)
+      c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
+    else
+      {
+      for (i = 0; i < 32; i++)
+        {
+        if (c == ebcdic_escape_c[i]) break;
+        }
+      if (i < 32) c = i; else *errorcodeptr = ERR68;
+      }
+#endif  /* EBCDIC */
+
+    ptr++;
+    break;
+
+    /* Any other alphanumeric following \ is an error. Perl gives an error only
+    if in warning mode, but PCRE doesn't have a warning mode. */
+
+    default:
+    *errorcodeptr = ERR3;
+    *ptrptr = ptr - 1;     /* Point to the character at fault */
+    return 0;
+    }
+  }
+
+/* Perl supports \N{name} for character names, as well as plain \N for "not
+newline". PCRE does not support \N{name}. However, it does support
+quantification such as \N{2,3}. */
+
+if (escape == ESC_N && ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET &&
+    ptrend - ptr > 2)
+  {
+  PCRE2_SPTR p = ptr + 1;
+  if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) &&
+       *errorcodeptr == 0)
+    *errorcodeptr = ERR37;
+  }
+
+/* Set the pointer to the next character before returning. */
+
+*ptrptr = ptr;
+*chptr = c;
+return escape;
+}
+
+
+
+#ifdef SUPPORT_UNICODE
+/*************************************************
+*               Handle \P and \p                 *
+*************************************************/
+
+/* This function is called after \P or \p has been encountered, provided that
+PCRE2 is compiled with support for UTF and Unicode properties. On entry, the
+contents of ptrptr are pointing after the P or p. On exit, it is left pointing
+after the final code unit of the escape sequence.
+
+Arguments:
+  ptrptr         the pattern position pointer
+  negptr         a boolean that is set TRUE for negation else FALSE
+  ptypeptr       an unsigned int that is set to the type value
+  pdataptr       an unsigned int that is set to the detailed property value
+  errorcodeptr   the error code variable
+  cb             the compile data
+
+Returns:         TRUE if the type value was found, or FALSE for an invalid type
+*/
+
+static BOOL
+get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, uint16_t *ptypeptr,
+  uint16_t *pdataptr, int *errorcodeptr, compile_block *cb)
+{
+PCRE2_UCHAR c;
+PCRE2_SIZE i, bot, top;
+PCRE2_SPTR ptr = *ptrptr;
+PCRE2_UCHAR name[32];
+
+if (ptr >= cb->end_pattern) goto ERROR_RETURN;
+c = *ptr++;
+*negptr = FALSE;
+
+/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
+negation. */
+
+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++)
+    {
+    if (ptr >= cb->end_pattern) goto ERROR_RETURN;
+    c = *ptr++;
+    if (c == CHAR_NUL) goto ERROR_RETURN;
+    if (c == CHAR_RIGHT_CURLY_BRACKET) break;
+    name[i] = c;
+    }
+  if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
+  name[i] = 0;
+  }
+
+/* Otherwise there is just one following character, which must be an ASCII
+letter. */
+
+else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0)
+  {
+  name[0] = c;
+  name[1] = 0;
+  }
+else goto ERROR_RETURN;
+
+*ptrptr = ptr;
+
+/* Search for a recognized property name using binary chop. */
+
+bot = 0;
+top = PRIV(utt_size);
+
+while (bot < top)
+  {
+  int r;
+  i = (bot + top) >> 1;
+  r = PRIV(strcmp_c8)(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
+  if (r == 0)
+    {
+    *ptypeptr = PRIV(utt)[i].type;
+    *pdataptr = PRIV(utt)[i].value;
+    return TRUE;
+    }
+  if (r > 0) bot = i + 1; else top = i;
+  }
+*errorcodeptr = ERR47;   /* Unrecognized name */
+return FALSE;
+
+ERROR_RETURN:            /* Malformed \P or \p */
+*errorcodeptr = ERR46;
+*ptrptr = ptr;
+return FALSE;
+}
 #endif
 
-    switch (*cc)
-      {
-      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:
-      goto ISNOTFIXED;
 
-      case OP_CRRANGE:
-      case OP_CRMINRANGE:
-      case OP_CRPOSRANGE:
-      if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) goto ISNOTFIXED;
-      branchlength += GET2(cc,1);
-      cc += 1 + 2 * IMM2_SIZE;
+
+/*************************************************
+*           Check for POSIX class syntax         *
+*************************************************/
+
+/* This function is called when the sequence "[:" or "[." or "[=" is
+encountered in a character class. It checks whether this is followed by a
+sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
+reach an unescaped ']' without the special preceding character, return FALSE.
+
+Originally, this function only recognized a sequence of letters between the
+terminators, but it seems that Perl recognizes any sequence of characters,
+though of course unknown POSIX names are subsequently rejected. Perl gives an
+"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
+didn't consider this to be a POSIX class. Likewise for [:1234:].
+
+The problem in trying to be exactly like Perl is in the handling of escapes. We
+have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
+class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
+below handles the special cases \\ and \], but does not try to do any other
+escape processing. This makes it different from Perl for cases such as
+[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does
+not recognize "l\ower". This is a lesser evil than not diagnosing bad classes
+when Perl does, I think.
+
+A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
+It seems that the appearance of a nested POSIX class supersedes an apparent
+external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
+a digit. This is handled by returning FALSE if the start of a new group with
+the same terminator is encountered, since the next closing sequence must close
+the nested group, not the outer one.
+
+In Perl, unescaped square brackets may also appear as part of class names. For
+example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
+[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
+seem right at all. PCRE does not allow closing square brackets in POSIX class
+names.
+
+Arguments:
+  ptr      pointer to the character after the initial [ (colon, dot, equals)
+  ptrend   pointer to the end of the pattern
+  endptr   where to return a pointer to the terminating ':', '.', or '='
+
+Returns:   TRUE or FALSE
+*/
+
+static BOOL
+check_posix_syntax(PCRE2_SPTR ptr, PCRE2_SPTR ptrend, PCRE2_SPTR *endptr)
+{
+PCRE2_UCHAR terminator;  /* Don't combine these lines; the Solaris cc */
+terminator = *ptr++;     /* compiler warns about "non-constant" initializer. */
+
+for (; ptrend - ptr >= 2; ptr++)
+  {
+  if (*ptr == CHAR_BACKSLASH &&
+      (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET || ptr[1] == CHAR_BACKSLASH))
+    ptr++;
+
+  else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||
+            *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
+
+  else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+    {
+    *endptr = ptr;
+    return TRUE;
+    }
+  }
+
+return FALSE;
+}
+
+
+
+/*************************************************
+*          Check POSIX class name                *
+*************************************************/
+
+/* This function is called to check the name given in a POSIX-style class entry
+such as [:alnum:].
+
+Arguments:
+  ptr        points to the first letter
+  len        the length of the name
+
+Returns:     a value representing the name, or -1 if unknown
+*/
+
+static int
+check_posix_name(PCRE2_SPTR ptr, int len)
+{
+const char *pn = posix_names;
+int yield = 0;
+while (posix_name_lengths[yield] != 0)
+  {
+  if (len == posix_name_lengths[yield] &&
+    PRIV(strncmp_c8)(ptr, pn, (unsigned int)len) == 0) return yield;
+  pn += posix_name_lengths[yield] + 1;
+  yield++;
+  }
+return -1;
+}
+
+
+
+/*************************************************
+*       Read a subpattern or VERB name           *
+*************************************************/
+
+/* This function is called from parse_regex() below whenever it needs to read
+the name of a subpattern or a (*VERB). The initial pointer must be to the
+character before the name. If that character is '*' we are reading a verb name.
+The pointer is updated to point after the name, for a VERB, or after tha name's
+terminator for a subpattern name. Returning both the offset and the name
+pointer is redundant information, but some callers use one and some the other,
+so it is simplest just to return both.
+
+Arguments:
+  ptrptr      points to the character pointer variable
+  ptrend      points to the end of the input string
+  terminator  the terminator of a subpattern name must be this
+  offsetptr   where to put the offset from the start of the pattern
+  nameptr     where to put a pointer to the name in the input
+  namelenptr  where to put the length of the name
+  errcodeptr  where to put an error code
+  cb          pointer to the compile data block
+
+Returns:    TRUE if a name was read
+            FALSE otherwise, with error code set
+*/
+
+static BOOL
+read_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t terminator,
+  PCRE2_SIZE *offsetptr, PCRE2_SPTR *nameptr, uint32_t *namelenptr,
+  int *errorcodeptr, compile_block *cb)
+{
+PCRE2_SPTR ptr = *ptrptr;
+BOOL is_verb = (*ptr == CHAR_ASTERISK);
+uint32_t namelen = 0;
+uint32_t ctype = is_verb? ctype_letter : ctype_word;
+
+if (++ptr >= ptrend)
+  {
+  *errorcodeptr = is_verb? ERR60:  /* Verb not recognized or malformed */
+                           ERR62;  /* Subpattern name expected */
+  goto FAILED;
+  }
+
+*nameptr = ptr;
+*offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern);
+
+if (IS_DIGIT(*ptr))
+  {
+  *errorcodeptr = ERR44;   /* Group name must not start with digit */
+  goto FAILED;
+  }
+
+while (ptr < ptrend && MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype) != 0)
+  {
+  ptr++;
+  namelen++;
+  if (namelen > MAX_NAME_SIZE)
+    {
+    *errorcodeptr = ERR48;
+    goto FAILED;
+    }
+  }
+
+/* Subpattern names must not be empty, and their terminator is checked here.
+(What follows a verb name is checked separately.) */
+
+if (!is_verb)
+  {
+  if (namelen == 0)
+    {
+    *errorcodeptr = ERR62;   /* Subpattern name expected */
+    goto FAILED;
+    }
+  if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator)
+    {
+    *errorcodeptr = ERR42;
+    goto FAILED;
+    }
+  ptr++;
+  }
+
+*namelenptr = namelen;
+*ptrptr = ptr;
+return TRUE;
+
+FAILED:
+*ptrptr = ptr;
+return FALSE;
+}
+
+
+
+/*************************************************
+*          Manage callouts at start of cycle     *
+*************************************************/
+
+/* At the start of a new item in parse_regex() we are able to record the
+details of the previous item in a prior callout, and also to set up an
+automatic callout if enabled. Avoid having two adjacent automatic callouts,
+which would otherwise happen for items such as \Q that contribute nothing to
+the parsed pattern.
+
+Arguments:
+  ptr              current pattern pointer
+  pcalloutptr      points to a pointer to previous callout, or NULL
+  auto_callout     TRUE if auto_callouts are enabled
+  parsed_pattern   the parsed pattern pointer
+  cb               compile block
+
+Returns: possibly updated parsed_pattern pointer.
+*/
+
+static uint32_t *
+manage_callouts(PCRE2_SPTR ptr, uint32_t **pcalloutptr, BOOL auto_callout,
+  uint32_t *parsed_pattern, compile_block *cb)
+{
+uint32_t *previous_callout = *pcalloutptr;
+
+if (previous_callout != NULL) previous_callout[2] = (uint32_t)(ptr -
+  cb->start_pattern - (PCRE2_SIZE)previous_callout[1]);
+
+if (!auto_callout) previous_callout = NULL; else
+  {
+  if (previous_callout == NULL ||
+      previous_callout != parsed_pattern - 4 ||
+      previous_callout[3] != 255)
+    {
+    previous_callout = parsed_pattern;  /* Set up new automatic callout */
+    parsed_pattern += 4;
+    previous_callout[0] = META_CALLOUT_NUMBER;
+    previous_callout[2] = 0;
+    previous_callout[3] = 255;
+    }
+  previous_callout[1] = (uint32_t)(ptr - cb->start_pattern);
+  }
+
+*pcalloutptr = previous_callout;
+return parsed_pattern;
+}
+
+
+
+/*************************************************
+*      Parse regex and identify named groups     *
+*************************************************/
+
+/* This function is called first of all. It scans the pattern and does two
+things: (1) It identifies capturing groups and makes a table of named capturing
+groups so that information about them is fully available to both the compiling
+scans. (2) It writes a parsed version of the pattern with comments omitted and
+escapes processed into the parsed_pattern vector.
+
+Arguments:
+  ptr             points to the start of the pattern
+  options         compiling dynamic options (may change during the scan)
+  has_lookbehind  points to a boolean, set TRUE if a lookbehind is found
+  cb              pointer to the compile data block
+
+Returns:   zero on success or a non-zero error code, with the
+             error offset placed in the cb field
+*/
+
+/* A structure and some flags for dealing with nested groups. */
+
+typedef struct nest_save {
+  uint16_t  nest_depth;
+  uint16_t  reset_group;
+  uint16_t  max_group;
+  uint16_t  flags;
+  uint32_t  options;
+} nest_save;
+
+#define NSF_RESET          0x0001u
+#define NSF_CONDASSERT     0x0002u
+
+/* Of the options that are changeable within the pattern, these are tracked
+during parsing. The rest are used from META_OPTIONS items when compiling. */
+
+#define PARSE_TRACKED_OPTIONS \
+  (PCRE2_DUPNAMES|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_NO_AUTO_CAPTURE)
+
+/* 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 };
+
+/* Only in 32-bit mode can there be literals > META_END. A macros encapsulates
+the storing of literal values in the parsed pattern. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 32
+#define PARSED_LITERAL(c, p) \
+  { \
+  if (c >= META_END) *p++ = META_BIGVALUE; \
+  *p++ = c; \
+  okquantifier = TRUE; \
+  }
+#else
+#define PARSED_LITERAL(c, p) *p++ = c; okquantifier = TRUE;
+#endif
+
+/* Here's the actual function. */
+
+static int parse_regex(PCRE2_SPTR ptr, uint32_t options, BOOL *has_lookbehind,
+  compile_block *cb)
+{
+uint32_t c;
+uint32_t delimiter;
+uint32_t namelen;
+uint32_t class_range_state;
+uint32_t *verblengthptr = NULL;     /* Value avoids compiler warning */
+uint32_t *previous_callout = NULL;
+uint32_t *parsed_pattern = cb->parsed_pattern;
+uint32_t *parsed_pattern_end = cb->parsed_pattern_end;
+uint32_t meta_quantifier = 0;
+uint16_t nest_depth = 0;
+int after_manual_callout = 0;
+int expect_cond_assert = 0;
+int errorcode = 0;
+int escape;
+int i;
+BOOL inescq = FALSE;
+BOOL inverbname = FALSE;
+BOOL utf = (options & PCRE2_UTF) != 0;
+BOOL auto_callout = (options & PCRE2_AUTO_CALLOUT) != 0;
+BOOL isdupname;
+BOOL negate_class;
+BOOL okquantifier = FALSE;
+PCRE2_SPTR thisptr;
+PCRE2_SPTR name;
+PCRE2_SPTR ptrend = cb->end_pattern;
+PCRE2_SPTR verbnamestart = NULL;    /* Value avoids compiler warning */
+named_group *ng;
+nest_save *top_nest, *end_nests;
+
+/* Insert leading items for word and line matching (features provided for the
+benefit of pcre2grep). */
+
+if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_LINE) != 0)
+  {
+  *parsed_pattern++ = META_CIRCUMFLEX;
+  *parsed_pattern++ = META_NOCAPTURE;
+  }
+else if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_WORD) != 0)
+  {
+  *parsed_pattern++ = META_ESCAPE + ESC_b;
+  *parsed_pattern++ = META_NOCAPTURE;
+  }
+
+/* If the pattern is actually a literal string, process it separately to avoid
+cluttering up the main loop. */
+
+if ((options & PCRE2_LITERAL) != 0)
+  {
+  while (ptr < ptrend)
+    {
+    if (parsed_pattern >= parsed_pattern_end)
+      {
+      errorcode = ERR63;  /* Internal error (parsed pattern overflow) */
+      goto FAILED;
+      }
+    thisptr = ptr;
+    GETCHARINCTEST(c, ptr);
+    if (auto_callout)
+      parsed_pattern = manage_callouts(thisptr, &previous_callout,
+        auto_callout, parsed_pattern, cb);
+    PARSED_LITERAL(c, parsed_pattern);
+    }
+  goto PARSED_END;
+  }
+
+/* Process a real regex which may contain meta-characters. */
+
+top_nest = NULL;
+end_nests = (nest_save *)(cb->start_workspace + cb->workspace_size);
+
+/* The size of the nest_save structure might not be a factor of the size of the
+workspace. Therefore we must round down end_nests so as to correctly avoid
+creating a nest_save that spans the end of the workspace. */
+
+end_nests = (nest_save *)((char *)end_nests -
+  ((cb->workspace_size * sizeof(PCRE2_UCHAR)) % sizeof(nest_save)));
+
+/* PCRE2_EXTENDED_MORE implies PCRE2_EXTENDED */
+
+if ((options & PCRE2_EXTENDED_MORE) != 0) options |= PCRE2_EXTENDED;
+
+/* Now scan the pattern */
+
+while (ptr < ptrend)
+  {
+  int prev_expect_cond_assert;
+  uint32_t min_repeat, max_repeat;
+  uint32_t set, unset, *optset;
+  uint32_t terminator;
+  uint32_t prev_meta_quantifier;
+  BOOL prev_okquantifier;
+  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 */
+    }
+
+  /* Get next input character, save its position for callout handling. */
+
+  thisptr = ptr;
+  GETCHARINCTEST(c, ptr);
+
+  /* Copy quoted literals until \E, allowing for the possibility of automatic
+  callouts, except when processing a (*VERB) "name".  */
+
+  if (inescq)
+    {
+    if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)
+      {
+      inescq = FALSE;
+      ptr++;   /* Skip E */
+      }
+    else
+      {
+      if (expect_cond_assert > 0)   /* A literal is not allowed if we are */
+        {                           /* expecting a conditional assertion, */
+        ptr--;                      /* but an empty \Q\E sequence is OK.  */
+        errorcode = ERR28;
+        goto FAILED;
+        }
+      if (!inverbname && after_manual_callout-- <= 0)
+        parsed_pattern = manage_callouts(thisptr, &previous_callout,
+          auto_callout, parsed_pattern, cb);
+      PARSED_LITERAL(c, parsed_pattern);
+      meta_quantifier = 0;
+      }
+    continue;  /* Next character */
+    }
+
+  /* If we are processing the "name" part of a (*VERB:NAME) item, all
+  characters up to the closing parenthesis are literals except when
+  PCRE2_ALT_VERBNAMES is set. That causes backslash interpretation, but only \Q
+  and \E and escaped characters are allowed (no character types such as \d). If
+  PCRE2_EXTENDED is also set, we must ignore white space and # comments. Do
+  this by not entering the special (*VERB:NAME) processing - they are then
+  picked up below. Note that c is a character, not a code unit, so we must not
+  use MAX_255 to test its size because MAX_255 tests code units and is assumed
+  TRUE in 8-bit mode. */
+
+  if (inverbname &&
+       (
+        /* EITHER: not both options set */
+        ((options & (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) !=
+                    (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) ||
+        /* OR: character > 255 */
+        c > 255 ||
+        /* OR: not a # comment or white space */
+        (c != CHAR_NUMBER_SIGN && (cb->ctypes[c] & ctype_space) == 0)
+       ))
+    {
+    PCRE2_SIZE verbnamelength;
+
+    switch(c)
+      {
+      default:
+      PARSED_LITERAL(c, parsed_pattern);
+      break;
+
+      case CHAR_RIGHT_PARENTHESIS:
+      inverbname = FALSE;
+      okquantifier = FALSE;   /* Was probably set by literals */
+      /* This is the length in characters */
+      verbnamelength = (PCRE2_SIZE)(parsed_pattern - verblengthptr - 1);
+      /* But the limit on the length is in code units */
+      if (ptr - verbnamestart - 1 > (int)MAX_MARK)
+        {
+        ptr--;
+        errorcode = ERR76;
+        goto FAILED;
+        }
+      *verblengthptr = (uint32_t)verbnamelength;
+      break;
+
+      case CHAR_BACKSLASH:
+      if ((options & PCRE2_ALT_VERBNAMES) != 0)
+        {
+        escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,
+          FALSE, cb);
+        if (errorcode != 0) goto FAILED;
+        }
+      else escape = 0;   /* Treat all as literal */
+
+      switch(escape)
+        {
+        case 0:
+        PARSED_LITERAL(c, parsed_pattern);
+        break;
+
+        case ESC_Q:
+        inescq = TRUE;
+        break;
+
+        case ESC_E:           /* Ignore */
+        break;
+
+        default:
+        errorcode = ERR40;    /* Invalid in verb name */
+        goto FAILED;
+        }
+      }
+    continue;   /* Next character in pattern */
+    }
+
+  /* Not a verb name character. At this point we must process everything that
+  must not change the quantification state. This is mainly comments, but we
+  handle \Q and \E here as well, so that an item such as A\Q\E+ is treated as
+  A+, as in Perl. An isolated \E is ignored. */
+
+  if (c == CHAR_BACKSLASH && ptr < ptrend)
+    {
+    if (*ptr == CHAR_Q || *ptr == CHAR_E)
+      {
+      inescq = *ptr == CHAR_Q;
+      ptr++;
+      continue;
+      }
+    }
+
+  /* Skip over whitespace and # comments in extended mode. Note that c is a
+  character, not a code unit, so we must not use MAX_255 to test its size
+  because MAX_255 tests code units and is assumed TRUE in 8-bit mode. */
+
+  if ((options & PCRE2_EXTENDED) != 0)
+    {
+    if (c < 256 && (cb->ctypes[c] & ctype_space) != 0) continue;
+    if (c == CHAR_NUMBER_SIGN)
+      {
+      while (ptr < ptrend)
+        {
+        if (IS_NEWLINE(ptr))      /* For non-fixed-length newline cases, */
+          {                       /* IS_NEWLINE sets cb->nllen. */
+          ptr += cb->nllen;
+          break;
+          }
+        ptr++;
+#ifdef SUPPORT_UNICODE
+        if (utf) FORWARDCHARTEST(ptr, ptrend);
+#endif
+        }
+      continue;  /* Next character in pattern */
+      }
+    }
+
+  /* Skip over bracketed comments */
+
+  if (c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 2 &&
+      ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN)
+    {
+    while (++ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS);
+    if (ptr >= ptrend)
+      {
+      errorcode = ERR18;  /* A special error for missing ) in a comment */
+      goto FAILED;        /* to make it easier to debug. */
+      }
+    ptr++;
+    continue;  /* Next character in pattern */
+    }
+
+  /* If the next item is not a quantifier, fill in length of any previous
+  callout and create an auto callout if required. */
+
+  if (c != CHAR_ASTERISK && c != CHAR_PLUS && c != CHAR_QUESTION_MARK &&
+       (c != CHAR_LEFT_CURLY_BRACKET ||
+         (tempptr = ptr,
+         !read_repeat_counts(&tempptr, ptrend, NULL, NULL, &errorcode))))
+    {
+    if (after_manual_callout-- <= 0)
+      parsed_pattern = manage_callouts(thisptr, &previous_callout, auto_callout,
+        parsed_pattern, cb);
+    }
+
+  /* If expect_cond_assert is 2, we have just passed (?( and are expecting an
+  assertion, possibly preceded by a callout. If the value is 1, we have just
+  had the callout and expect an assertion. There must be at least 3 more
+  characters in all cases. When expect_cond_assert is 2, we know that the
+  current character is an opening parenthesis, as otherwise we wouldn't be
+  here. However, when it is 1, we need to check, and it's easiest just to check
+  always. Note that expect_cond_assert may be negative, since all callouts just
+  decrement it. */
+
+  if (expect_cond_assert > 0)
+    {
+    BOOL ok = c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 3 &&
+              ptr[0] == CHAR_QUESTION_MARK;
+    if (ok) switch(ptr[1])
+      {
+      case CHAR_C:
+      ok = expect_cond_assert == 2;
+      break;
+
+      case CHAR_EQUALS_SIGN:
+      case CHAR_EXCLAMATION_MARK:
+      break;
+
+      case CHAR_LESS_THAN_SIGN:
+      ok = ptr[2] == CHAR_EQUALS_SIGN || ptr[2] == CHAR_EXCLAMATION_MARK;
       break;
 
       default:
-      branchlength++;
+      ok = FALSE;
+      }
+
+    if (!ok)
+      {
+      ptr--;   /* Adjust error offset */
+      errorcode = ERR28;
+      goto FAILED;
+      }
+    }
+
+  /* Remember whether we are expecting a conditional assertion, and set the
+  default for this item. */
+
+  prev_expect_cond_assert = expect_cond_assert;
+  expect_cond_assert = 0;
+
+  /* Remember quantification status for the previous significant item, then set
+  default for this item. */
+
+  prev_okquantifier = okquantifier;
+  prev_meta_quantifier = meta_quantifier;
+  okquantifier = FALSE;
+  meta_quantifier = 0;
+
+  /* If the previous significant item was a quantifier, adjust the parsed code
+  if there is a following modifier. The base meta value is always followed by
+  the PLUS and QUERY values, in that order. We do this here rather than after
+  reading a quantifier so that intervening comments and /x whitespace can be
+  ignored without having to replicate code. */
+
+  if (prev_meta_quantifier != 0 && (c == CHAR_QUESTION_MARK || c == CHAR_PLUS))
+    {
+    parsed_pattern[(prev_meta_quantifier == META_MINMAX)? -3 : -1] =
+      prev_meta_quantifier + ((c == CHAR_QUESTION_MARK)?
+        0x00020000u : 0x00010000u);
+    continue;  /* Next character in pattern */
+    }
+
+
+  /* Process the next item in the main part of a pattern. */
+
+  switch(c)
+    {
+    default:              /* Non-special character */
+    PARSED_LITERAL(c, parsed_pattern);
+    break;
+
+
+    /* ---- Escape sequence ---- */
+
+    case CHAR_BACKSLASH:
+    tempptr = ptr;
+    escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options,
+      FALSE, cb);
+    if (errorcode != 0)
+      {
+      ESCAPE_FAILED:
+      if ((cb->cx->extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0)
+        goto FAILED;
+      ptr = tempptr;
+      if (ptr >= ptrend) c = CHAR_BACKSLASH; else
+        {
+        GETCHARINCTEST(c, ptr);   /* Get character value, increment pointer */
+        }
+      escape = 0;                 /* Treat as literal character */
+      }
+
+    /* The escape was a data escape or literal character. */
+
+    if (escape == 0)
+      {
+      PARSED_LITERAL(c, parsed_pattern);
+      }
+
+    /* The escape was a back (or forward) reference. We keep the offset in
+    order to give a more useful diagnostic for a bad forward reference. For
+    references to groups numbered less than 10 we can't use more than two items
+    in parsed_pattern because they may be just two characters in the input (and
+    in a 64-bit world an offset may need two elements). So for them, the offset
+    of the first occurrent is held in a special vector. */
+
+    else if (escape < 0)
+      {
+      offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 1);
+      escape = -escape;
+      *parsed_pattern++ = META_BACKREF | (uint32_t)escape;
+      if (escape < 10)
+        {
+        if (cb->small_ref_offset[escape] == PCRE2_UNSET)
+          cb->small_ref_offset[escape] = offset;
+        }
+      else
+        {
+        PUTOFFSET(offset, parsed_pattern);
+        }
+      okquantifier = TRUE;
+      }
+
+    /* The escape was a character class such as \d etc. or other special
+    escape indicator such as \A or \X. Most of them generate just a single
+    parsed item, but \P and \p are followed by a 16-bit type and a 16-bit
+    value. They are supported only when Unicode is available. The type and
+    value are packed into a single 32-bit value so that the whole sequences
+    uses only two elements in the parsed_vector. This is because the same
+    coding is used if \d (for example) is turned into \p{Nd} when PCRE2_UCP is
+    set.
+
+    There are also some cases where the escape sequence is followed by a name:
+    \k{name}, \k<name>, and \k'name' are backreferences by name, and \g<name>
+    and \g'name' are subroutine calls by name; \g{name} is a synonym for
+    \k{name}. Note that \g<number> and \g'number' are handled by check_escape()
+    and returned as a negative value (handled above). A name is coded as an
+    offset into the pattern and a length. */
+
+    else switch (escape)
+      {
+      case ESC_C:
+#ifdef NEVER_BACKSLASH_C
+      errorcode = ERR85;
+      goto ESCAPE_FAILED;
+#else
+      if ((options & PCRE2_NEVER_BACKSLASH_C) != 0)
+        {
+        errorcode = ERR83;
+        goto ESCAPE_FAILED;
+        }
+#endif
+      okquantifier = TRUE;
+      *parsed_pattern++ = META_ESCAPE + escape;
+      break;
+
+      case ESC_X:
+#ifndef SUPPORT_UNICODE
+      errorcode = ERR45;   /* Supported only with Unicode support */
+      goto ESCAPE_FAILED;
+#endif
+      case ESC_H:
+      case ESC_h:
+      case ESC_N:
+      case ESC_R:
+      case ESC_V:
+      case ESC_v:
+      okquantifier = TRUE;
+      *parsed_pattern++ = META_ESCAPE + escape;
+      break;
+
+      default:  /* \A, \B, \b, \G, \K, \Z, \z cannot be quantified. */
+      *parsed_pattern++ = META_ESCAPE + escape;
+      break;
+
+      /* Escapes that change in UCP mode. Note that PCRE2_UCP will never be set
+      without Unicode support because it is checked when pcre2_compile() is
+      called. */
+
+      case ESC_d:
+      case ESC_D:
+      case ESC_s:
+      case ESC_S:
+      case ESC_w:
+      case ESC_W:
+      okquantifier = TRUE;
+      if ((options & PCRE2_UCP) == 0)
+        {
+        *parsed_pattern++ = META_ESCAPE + escape;
+        }
+      else
+        {
+        *parsed_pattern++ = META_ESCAPE +
+          ((escape == ESC_d || escape == ESC_s || escape == ESC_w)?
+            ESC_p : ESC_P);
+        switch(escape)
+          {
+          case ESC_d:
+          case ESC_D:
+          *parsed_pattern++ = (PT_PC << 16) | ucp_Nd;
+          break;
+
+          case ESC_s:
+          case ESC_S:
+          *parsed_pattern++ = PT_SPACE << 16;
+          break;
+
+          case ESC_w:
+          case ESC_W:
+          *parsed_pattern++ = PT_WORD << 16;
+          break;
+          }
+        }
+      break;
+
+      /* Unicode property matching */
+
+      case ESC_P:
+      case ESC_p:
+#ifdef SUPPORT_UNICODE
+        {
+        BOOL negated;
+        uint16_t ptype = 0, pdata = 0;
+        if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
+          goto ESCAPE_FAILED;
+        if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;
+        *parsed_pattern++ = META_ESCAPE + escape;
+        *parsed_pattern++ = (ptype << 16) | pdata;
+        okquantifier = TRUE;
+        }
+#else
+      errorcode = ERR45;
+      goto ESCAPE_FAILED;
+#endif
+      break;  /* End \P and \p */
+
+      /* 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
+      here because check_escape() returns it directly as a reference. \k is
+      always a named back reference. */
+
+      case ESC_g:
+      case ESC_k:
+      if (ptr >= ptrend || (*ptr != CHAR_LEFT_CURLY_BRACKET &&
+          *ptr != CHAR_LESS_THAN_SIGN && *ptr != CHAR_APOSTROPHE))
+        {
+        errorcode = (escape == ESC_g)? ERR57 : ERR69;
+        goto ESCAPE_FAILED;
+        }
+      terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
+        CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
+        CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
+
+      /* For a non-braced \g, check for a numerical recursion. */
+
+      if (escape == ESC_g && terminator != CHAR_RIGHT_CURLY_BRACKET)
+        {
+        PCRE2_SPTR p = ptr + 1;
+
+        if (read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,
+            &errorcode))
+          {
+          if (p >= ptrend || *p != terminator)
+            {
+            errorcode = ERR57;
+            goto ESCAPE_FAILED;
+            }
+          ptr = p;
+          goto SET_RECURSION;
+          }
+        if (errorcode != 0) goto ESCAPE_FAILED;
+        }
+
+      /* Not a numerical recursion */
+
+      if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen,
+          &errorcode, cb)) goto ESCAPE_FAILED;
+
+      /* \k and \g when used with braces are back references, whereas \g used
+      with quotes or angle brackets is a recursion */
+
+      *parsed_pattern++ =
+        (escape == ESC_k || terminator == CHAR_RIGHT_CURLY_BRACKET)?
+          META_BACKREF_BYNAME : META_RECURSE_BYNAME;
+      *parsed_pattern++ = namelen;
+
+      PUTOFFSET(offset, parsed_pattern);
+      okquantifier = TRUE;
+      break;  /* End special escape processing */
+      }
+    break;    /* End escape sequence processing */
+
+
+    /* ---- Single-character special items ---- */
+
+    case CHAR_CIRCUMFLEX_ACCENT:
+    *parsed_pattern++ = META_CIRCUMFLEX;
+    break;
+
+    case CHAR_DOLLAR_SIGN:
+    *parsed_pattern++ = META_DOLLAR;
+    break;
+
+    case CHAR_DOT:
+    *parsed_pattern++ = META_DOT;
+    okquantifier = TRUE;
+    break;
+
+
+    /* ---- Single-character quantifiers ---- */
+
+    case CHAR_ASTERISK:
+    meta_quantifier = META_ASTERISK;
+    goto CHECK_QUANTIFIER;
+
+    case CHAR_PLUS:
+    meta_quantifier = META_PLUS;
+    goto CHECK_QUANTIFIER;
+
+    case CHAR_QUESTION_MARK:
+    meta_quantifier = META_QUERY;
+    goto CHECK_QUANTIFIER;
+
+
+    /* ---- Potential {n,m} quantifier ---- */
+
+    case CHAR_LEFT_CURLY_BRACKET:
+    if (!read_repeat_counts(&ptr, ptrend, &min_repeat, &max_repeat,
+        &errorcode))
+      {
+      if (errorcode != 0) goto FAILED;     /* Error in quantifier. */
+      PARSED_LITERAL(c, parsed_pattern);   /* Not a quantifier */
+      break;                               /* No more quantifier processing */
+      }
+    meta_quantifier = META_MINMAX;
+    /* Fall through */
+
+
+    /* ---- Quantifier post-processing ---- */
+
+    /* Check that a quantifier is allowed after the previous item. */
+
+    CHECK_QUANTIFIER:
+    if (!prev_okquantifier)
+      {
+      errorcode = ERR9;
+      goto FAILED_BACK;
+      }
+
+    /* Now we can put the quantifier into the parsed pattern vector. At this
+    stage, we have only the basic quantifier. The check for a following + or ?
+    modifier happens at the top of the loop, after any intervening comments
+    have been removed. */
+
+    *parsed_pattern++ = meta_quantifier;
+    if (c == CHAR_LEFT_CURLY_BRACKET)
+      {
+      *parsed_pattern++ = min_repeat;
+      *parsed_pattern++ = max_repeat;
       }
     break;
 
-    /* Anything else is variable length */
 
-    case OP_ANYNL:
-    case OP_BRAMINZERO:
-    case OP_BRAPOS:
-    case OP_BRAPOSZERO:
-    case OP_BRAZERO:
-    case OP_CBRAPOS:
-    case OP_EXTUNI:
-    case OP_KETRMAX:
-    case OP_KETRMIN:
-    case OP_KETRPOS:
-    case OP_MINPLUS:
-    case OP_MINPLUSI:
-    case OP_MINQUERY:
-    case OP_MINQUERYI:
-    case OP_MINSTAR:
-    case OP_MINSTARI:
-    case OP_MINUPTO:
-    case OP_MINUPTOI:
-    case OP_NOTMINPLUS:
-    case OP_NOTMINPLUSI:
-    case OP_NOTMINQUERY:
-    case OP_NOTMINQUERYI:
-    case OP_NOTMINSTAR:
-    case OP_NOTMINSTARI:
-    case OP_NOTMINUPTO:
-    case OP_NOTMINUPTOI:
-    case OP_NOTPLUS:
-    case OP_NOTPLUSI:
-    case OP_NOTPOSPLUS:
-    case OP_NOTPOSPLUSI:
-    case OP_NOTPOSQUERY:
-    case OP_NOTPOSQUERYI:
-    case OP_NOTPOSSTAR:
-    case OP_NOTPOSSTARI:
-    case OP_NOTPOSUPTO:
-    case OP_NOTPOSUPTOI:
-    case OP_NOTQUERY:
-    case OP_NOTQUERYI:
-    case OP_NOTSTAR:
-    case OP_NOTSTARI:
-    case OP_NOTUPTO:
-    case OP_NOTUPTOI:
-    case OP_PLUS:
-    case OP_PLUSI:
-    case OP_POSPLUS:
-    case OP_POSPLUSI:
-    case OP_POSQUERY:
-    case OP_POSQUERYI:
-    case OP_POSSTAR:
-    case OP_POSSTARI:
-    case OP_POSUPTO:
-    case OP_POSUPTOI:
-    case OP_QUERY:
-    case OP_QUERYI:
-    case OP_REF:
-    case OP_REFI:
-    case OP_DNREF:
-    case OP_DNREFI:
-    case OP_SBRA:
-    case OP_SBRAPOS:
-    case OP_SCBRA:
-    case OP_SCBRAPOS:
-    case OP_SCOND:
-    case OP_SKIPZERO:
-    case OP_STAR:
-    case OP_STARI:
-    case OP_TYPEMINPLUS:
-    case OP_TYPEMINQUERY:
-    case OP_TYPEMINSTAR:
-    case OP_TYPEMINUPTO:
-    case OP_TYPEPLUS:
-    case OP_TYPEPOSPLUS:
-    case OP_TYPEPOSQUERY:
-    case OP_TYPEPOSSTAR:
-    case OP_TYPEPOSUPTO:
-    case OP_TYPEQUERY:
-    case OP_TYPESTAR:
-    case OP_TYPEUPTO:
-    case OP_UPTO:
-    case OP_UPTOI:
-    goto ISNOTFIXED;
+    /* ---- Character class ---- */
 
-    /* Catch unrecognized opcodes so that when new ones are added they
-    are not forgotten, as has happened in the past. */
+    case CHAR_LEFT_SQUARE_BRACKET:
+    okquantifier = TRUE;
 
-    default:
-    return FFL_UNKNOWNOP;
-    }
-  }
-/* Control never gets here except by goto. */
+    /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
+    used for "start of word" and "end of word". As these are otherwise illegal
+    sequences, we don't break anything by recognizing them. They are replaced
+    by \b(?=\w) and \b(?<=\w) respectively. Sequences like [a[:<:]] are
+    erroneous and are handled by the normal code below. */
 
-ISNOTFIXED:
-if (group > 0)
+    if (ptrend - ptr >= 6 &&
+         (PRIV(strncmp_c8)(ptr, STRING_WEIRD_STARTWORD, 6) == 0 ||
+          PRIV(strncmp_c8)(ptr, STRING_WEIRD_ENDWORD, 6) == 0))
+      {
+      *parsed_pattern++ = META_ESCAPE + ESC_b;
+
+      if (ptr[2] == CHAR_LESS_THAN_SIGN)
+        {
+        *parsed_pattern++ = META_LOOKAHEAD;
+        }
+      else
+        {
+        *parsed_pattern++ = META_LOOKBEHIND;
+        *has_lookbehind = TRUE;
+
+        /* The offset is used only for the "non-fixed length" error; this won't
+        occur here, so just store zero. */
+
+        PUTOFFSET((PCRE2_SIZE)0, parsed_pattern);
+        }
+
+      if ((options & PCRE2_UCP) == 0)
+        *parsed_pattern++ = META_ESCAPE + ESC_w;
+      else
+        {
+        *parsed_pattern++ = META_ESCAPE + ESC_p;
+        *parsed_pattern++ = PT_WORD << 16;
+        }
+      *parsed_pattern++ = META_KET;
+      ptr += 6;
+      break;
+      }
+
+    /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
+    they are encountered at the top level, so we'll do that too. */
+
+    if (ptr < ptrend && (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||
+         *ptr == CHAR_EQUALS_SIGN) &&
+        check_posix_syntax(ptr, ptrend, &tempptr))
+      {
+      errorcode = (*ptr-- == CHAR_COLON)? ERR12 : ERR13;
+      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 */
+      }
+
+    /* Process a non-empty class. */
+
+    *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS;
+    class_range_state = RANGE_NO;
+
+    /* 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 ranges where both values are literal; [\xC1-\xE9] is different to [A-Z]
+    in this respect. In order to accommodate this, we keep track of whether
+    character values are literal or not, and a state variable for handling
+    ranges. */
+
+    /* Loop for the contents of the class */
+
+    for (;;)
+      {
+      BOOL char_is_literal = TRUE;
+
+      /* Inside \Q...\E everything is literal except \E */
+
+      if (inescq)
+        {
+        if (c == CHAR_BACKSLASH && ptr < ptrend && *ptr == CHAR_E)
+          {
+          inescq = FALSE;                   /* Reset literal state */
+          ptr++;                            /* Skip the 'E' */
+          goto CLASS_CONTINUE;
+          }
+        goto CLASS_LITERAL;
+        }
+
+      /* Skip over space and tab (only) in extended-more mode. */
+
+      if ((options & PCRE2_EXTENDED_MORE) != 0 &&
+          (c == CHAR_SPACE || c == CHAR_HT))
+        goto CLASS_CONTINUE;
+
+      /* Handle POSIX class names. Perl allows a negation extension of the
+      form [:^name:]. A square bracket that doesn't match the syntax is
+      treated as a literal. We also recognize the POSIX constructions
+      [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
+      5.6 and 5.8 do. */
+
+      if (c == CHAR_LEFT_SQUARE_BRACKET &&
+          ptrend - ptr >= 3 &&
+          (*ptr == CHAR_COLON || *ptr == CHAR_DOT ||
+           *ptr == CHAR_EQUALS_SIGN) &&
+          check_posix_syntax(ptr, ptrend, &tempptr))
+        {
+        BOOL posix_negate = FALSE;
+        int posix_class;
+
+        /* Perl treats a hyphen before a POSIX class as a literal, not the
+        start of a range. However, it gives a warning in its warning mode. PCRE
+        does not have a warning mode, so we give an error, because this is
+        likely an error on the user's part. */
+
+        if (class_range_state == RANGE_STARTED)
+          {
+          errorcode = ERR50;
+          goto FAILED;
+          }
+
+        if (*ptr != CHAR_COLON)
+          {
+          errorcode = ERR13;
+          goto FAILED_BACK;
+          }
+
+        if (*(++ptr) == CHAR_CIRCUMFLEX_ACCENT)
+          {
+          posix_negate = TRUE;
+          ptr++;
+          }
+
+        posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
+        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. */
+
+        class_range_state = RANGE_NO;
+
+        /* When PCRE2_UCP is set, some of the POSIX classes are converted to
+        use Unicode properties \p or \P or, in one case, \h or \H. The
+        substitutes table has two values per class, containing the type and
+        value of a \p or \P item. The special cases are specified with a
+        negative type: a non-zero value causes \h or \H to be used, and a zero
+        value falls through to behave like a non-UCP POSIX class. */
+
+#ifdef SUPPORT_UNICODE
+        if ((options & PCRE2_UCP) != 0)
+          {
+          int ptype = posix_substitutes[2*posix_class];
+          int pvalue = posix_substitutes[2*posix_class + 1];
+          if (ptype >= 0)
+            {
+            *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_P : ESC_p);
+            *parsed_pattern++ = (ptype << 16) | pvalue;
+            goto CLASS_CONTINUE;
+            }
+
+          if (pvalue != 0)
+            {
+            *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_H : ESC_h);
+            goto CLASS_CONTINUE;
+            }
+
+          /* Fall through */
+          }
+#endif  /* SUPPORT_UNICODE */
+
+        /* Non-UCP POSIX class */
+
+        *parsed_pattern++ = posix_negate? META_POSIX_NEG : META_POSIX;
+        *parsed_pattern++ = posix_class;
+        }
+
+      /* 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 a literal character */
+
+      else if (c != CHAR_BACKSLASH)
+        {
+        CLASS_LITERAL:
+        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;
+            }
+          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;
+          }
+        else  /* Potential start of range */
+          {
+          class_range_state = char_is_literal?
+            RANGE_OK_LITERAL : RANGE_OK_ESCAPED;
+          PARSED_LITERAL(c, parsed_pattern);
+          }
+        }
+
+      /* Handle escapes in a class */
+
+      else
+        {
+        tempptr = ptr;
+        escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode,
+          options, TRUE, cb);
+
+        if (errorcode != 0)
+          {
+          CLASS_ESCAPE_FAILED:
+          if ((cb->cx->extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0)
+            goto FAILED;
+          ptr = tempptr;
+          if (ptr >= ptrend) c = CHAR_BACKSLASH; else
+            {
+            GETCHARINCTEST(c, ptr);   /* Get character value, increment pointer */
+            }
+          escape = 0;                 /* Treat as literal character */
+          }
+
+        if (escape == 0)  /* Escaped character code point is in c */
+          {
+          char_is_literal = FALSE;
+          goto CLASS_LITERAL;
+          }
+
+        /* These three escapes do not alter the class range state. */
+
+        if (escape == ESC_b)
+          {
+          c = CHAR_BS;   /* \b is backspace in a class */
+          char_is_literal = FALSE;
+          goto CLASS_LITERAL;
+          }
+
+        else if (escape == ESC_Q)
+          {
+          inescq = TRUE;  /* Enter literal mode */
+          goto CLASS_CONTINUE;
+          }
+
+        else if (escape == ESC_E)  /* Ignore orphan \E */
+          goto CLASS_CONTINUE;
+
+        /* 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 CLASS_ESCAPE_FAILED;
+          }
+
+        /* 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:
+          errorcode = ERR71;  /* Not supported in a class */
+          goto CLASS_ESCAPE_FAILED;
+
+          case ESC_H:
+          case ESC_h:
+          case ESC_V:
+          case ESC_v:
+          *parsed_pattern++ = META_ESCAPE + escape;
+          break;
+
+          /* These escapes are converted to Unicode property tests when
+          PCRE2_UCP is set. */
+
+          case ESC_d:
+          case ESC_D:
+          case ESC_s:
+          case ESC_S:
+          case ESC_w:
+          case ESC_W:
+          if ((options & PCRE2_UCP) == 0)
+            {
+            *parsed_pattern++ = META_ESCAPE + escape;
+            }
+          else
+            {
+            *parsed_pattern++ = META_ESCAPE +
+              ((escape == ESC_d || escape == ESC_s || escape == ESC_w)?
+                ESC_p : ESC_P);
+            switch(escape)
+              {
+              case ESC_d:
+              case ESC_D:
+              *parsed_pattern++ = (PT_PC << 16) | ucp_Nd;
+              break;
+
+              case ESC_s:
+              case ESC_S:
+              *parsed_pattern++ = PT_SPACE << 16;
+              break;
+
+              case ESC_w:
+              case ESC_W:
+              *parsed_pattern++ = PT_WORD << 16;
+              break;
+              }
+            }
+          break;
+
+          /* Explicit Unicode property matching */
+
+          case ESC_P:
+          case ESC_p:
+#ifdef SUPPORT_UNICODE
+            {
+            BOOL negated;
+            uint16_t ptype = 0, pdata = 0;
+            if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
+              goto FAILED;
+            if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;
+            *parsed_pattern++ = META_ESCAPE + escape;
+            *parsed_pattern++ = (ptype << 16) | pdata;
+            }
+#else
+          errorcode = ERR45;
+          goto CLASS_ESCAPE_FAILED;
+#endif
+          break;  /* End \P and \p */
+
+          default:    /* All others are not allowed in a class */
+          errorcode = ERR7;
+          ptr--;
+          goto CLASS_ESCAPE_FAILED;
+          }
+
+        /* Perl gives a warning unless a following hyphen is the last character
+        in the class. PCRE throws an error. */
+
+        if (ptr < ptrend - 1 && *ptr == CHAR_MINUS &&
+            ptr[1] != CHAR_RIGHT_SQUARE_BRACKET)
+          {
+          errorcode = ERR50;
+          goto FAILED;
+          }
+        }
+
+      /* Proceed to next thing in the class. */
+
+      CLASS_CONTINUE:
+      if (ptr >= ptrend)
+        {
+        errorcode = ERR6;  /* Missing terminating ']' */
+        goto FAILED;
+        }
+      GETCHARINCTEST(c, ptr);
+      if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break;
+      }     /* End of class-processing loop */
+
+    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 */
+
+
+    /* ---- Opening parenthesis ---- */
+
+    case CHAR_LEFT_PARENTHESIS:
+    if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+    /* If ( is not followed by ? it is either a capture or a special verb. */
+
+    if (*ptr != CHAR_QUESTION_MARK)
+      {
+      const char *vn;
+
+      /* Handle capturing brackets (or non-capturing if auto-capture is turned
+      off). */
+
+      if (*ptr != CHAR_ASTERISK)
+        {
+        nest_depth++;
+        if ((options & PCRE2_NO_AUTO_CAPTURE) == 0)
+          {
+          cb->bracount++;
+          *parsed_pattern++ = META_CAPTURE | cb->bracount;
+          }
+        else *parsed_pattern++ = META_NOCAPTURE;
+        }
+
+
+      /* ---- Handle (*VERB) and (*VERB:NAME) ---- */
+
+      /* Do nothing for (*) so it gives a "bad quantifier" error rather than
+      "(*MARK) must have an argument". */
+
+      else if (ptrend - ptr > 1 && ptr[1] != CHAR_RIGHT_PARENTHESIS)
+        {
+        vn = verbnames;
+        if (!read_name(&ptr, ptrend, 0, &offset, &name, &namelen, &errorcode,
+          cb)) goto FAILED;
+        if (ptr >= ptrend || (*ptr != CHAR_COLON &&
+                              *ptr != CHAR_RIGHT_PARENTHESIS))
+          {
+          errorcode = ERR60;  /* Malformed */
+          goto FAILED;
+          }
+
+        /* Scan the table of verb names */
+
+        for (i = 0; i < verbcount; i++)
+          {
+          if (namelen == verbs[i].len &&
+              PRIV(strncmp_c8)(name, vn, namelen) == 0)
+            break;
+          vn += verbs[i].len + 1;
+          }
+
+        if (i >= verbcount)
+          {
+          errorcode = ERR60;  /* Verb not recognized */
+          goto FAILED;
+          }
+
+        /* An empty argument is treated as no argument. */
+
+        if (*ptr == CHAR_COLON && ptr + 1 < ptrend &&
+             ptr[1] == CHAR_RIGHT_PARENTHESIS)
+          ptr++;    /* Advance to the closing parens */
+
+        /* Check for mandatory non-empty argument; this is (*MARK) */
+
+        if (verbs[i].has_arg > 0 && *ptr != CHAR_COLON)
+          {
+          errorcode = ERR66;
+          goto FAILED;
+          }
+
+        /* It appears that Perl allows any characters whatsoever, other than a
+        closing parenthesis, to appear in arguments ("names"), so we no longer
+        insist on letters, digits, and underscores. Perl does not, however, do
+        any interpretation within arguments, and has no means of including a
+        closing parenthesis. PCRE supports escape processing but only when it
+        is requested by an option. We set inverbname TRUE here, and let the
+        main loop take care of this so that escape and \x processing is done by
+        the main code above. */
+
+        if (*ptr++ == CHAR_COLON)   /* Skip past : or ) */
+          {
+          if (verbs[i].has_arg < 0)  /* Argument is forbidden */
+            {
+            errorcode = ERR59;
+            goto FAILED;
+            }
+          *parsed_pattern++ = verbs[i].meta +
+            ((verbs[i].meta != META_MARK)? 0x00010000u:0);
+          verblengthptr = parsed_pattern++;
+          verbnamestart = ptr;
+          inverbname = TRUE;
+          }
+        else  /* No verb "name" argument */
+          {
+          *parsed_pattern++ = verbs[i].meta;
+          }
+        }     /* End of (*VERB) handling */
+      break;  /* Done with this parenthesis */
+      }       /* End of groups that don't start with (? */
+
+
+    /* ---- Items starting (? ---- */
+
+    /* The type of item is determined by what follows (?. Handle (?| and option
+    changes under "default" because both need a new block on the nest stack.
+    Comments starting with (?# are handled above. Note that there is some
+    ambiguity about the sequence (?- because if a digit follows it's a relative
+    recursion or subroutine call whereas otherwise it's an option unsetting. */
+
+    if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+    switch(*ptr)
+      {
+      default:
+      if (*ptr == CHAR_MINUS && ptrend - ptr > 1 && IS_DIGIT(ptr[1]))
+        goto RECURSION_BYNUMBER;  /* The + case is handled by CHAR_PLUS */
+
+      /* We now have either (?| or a (possibly empty) option setting,
+      optionally followed by a non-capturing group. */
+
+      nest_depth++;
+      if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
+      else if (++top_nest >= end_nests)
+        {
+        errorcode = ERR84;
+        goto FAILED;
+        }
+      top_nest->nest_depth = nest_depth;
+      top_nest->flags = 0;
+      top_nest->options = options & PARSE_TRACKED_OPTIONS;
+
+      /* Start of non-capturing group that resets the capture count for each
+      branch. */
+
+      if (*ptr == CHAR_VERTICAL_LINE)
+        {
+        top_nest->reset_group = (uint16_t)cb->bracount;
+        top_nest->max_group = (uint16_t)cb->bracount;
+        top_nest->flags |= NSF_RESET;
+        cb->external_flags |= PCRE2_DUPCAPUSED;
+        *parsed_pattern++ = META_NOCAPTURE;
+        ptr++;
+        }
+
+      /* Scan for options imnsxJU to be set or unset. */
+
+      else
+        {
+        top_nest->reset_group = 0;
+        top_nest->max_group = 0;
+        set = unset = 0;
+        optset = &set;
+
+        while (ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS &&
+                               *ptr != CHAR_COLON)
+          {
+          switch (*ptr++)
+            {
+            case CHAR_MINUS: optset = &unset; break;
+
+            case CHAR_J:  /* Record that it changed in the external options */
+            *optset |= PCRE2_DUPNAMES;
+            cb->external_flags |= PCRE2_JCHANGED;
+            break;
+
+            case CHAR_i: *optset |= PCRE2_CASELESS; break;
+            case CHAR_m: *optset |= PCRE2_MULTILINE; break;
+            case CHAR_n: *optset |= PCRE2_NO_AUTO_CAPTURE; break;
+            case CHAR_s: *optset |= PCRE2_DOTALL; break;
+            case CHAR_U: *optset |= PCRE2_UNGREEDY; break;
+
+            /* If x appears twice it sets the extended extended option. */
+
+            case CHAR_x:
+            *optset |= PCRE2_EXTENDED;
+            if (ptr < ptrend && *ptr == CHAR_x)
+              {
+              *optset |= PCRE2_EXTENDED_MORE;
+              ptr++;
+              }
+            break;
+
+            default:
+            errorcode = ERR11;
+            ptr--;    /* Correct the offset */
+            goto FAILED;
+            }
+          }
+
+        /* If we are setting extended without extended-more, ensure that any
+        existing extended-more gets unset. Also, unsetting extended must also
+        unset extended-more. */
+
+        if ((set & (PCRE2_EXTENDED|PCRE2_EXTENDED_MORE)) == PCRE2_EXTENDED ||
+            (unset & PCRE2_EXTENDED) != 0)
+          unset |= PCRE2_EXTENDED_MORE;
+
+        options = (options | set) & (~unset);
+
+        /* If the options ended with ')' this is not the start of a nested
+        group with option changes, so the options change at this level.
+        In this case, if the previous level set up a nest block, discard the
+        one we have just created. Otherwise adjust it for the previous level.
+        If the options ended with ':' we are starting a non-capturing group,
+        possibly with an options setting. */
+
+        if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+        if (*ptr++ == CHAR_RIGHT_PARENTHESIS)
+          {
+          nest_depth--;  /* This is not a nested group after all. */
+          if (top_nest > (nest_save *)(cb->start_workspace) &&
+              (top_nest-1)->nest_depth == nest_depth) top_nest--;
+          else top_nest->nest_depth = nest_depth;
+          }
+        else *parsed_pattern++ = META_NOCAPTURE;
+
+        /* If nothing changed, no need to record. */
+
+        if (set != 0 || unset != 0)
+          {
+          *parsed_pattern++ = META_OPTIONS;
+          *parsed_pattern++ = options;
+          }
+        }     /* End options processing */
+      break;  /* End default case after (? */
+
+
+      /* ---- Python syntax support ---- */
+
+      case CHAR_P:
+      if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+      /* (?P<name> is the same as (?<name>, which defines a named group. */
+
+      if (*ptr == CHAR_LESS_THAN_SIGN)
+        {
+        terminator = CHAR_GREATER_THAN_SIGN;
+        goto DEFINE_NAME;
+        }
+
+      /* (?P>name) is the same as (?&name), which is a recursion or subroutine
+      call. */
+
+      if (*ptr == CHAR_GREATER_THAN_SIGN) goto RECURSE_BY_NAME;
+
+      /* (?P=name) is the same as \k<name>, a back reference by name. Anything
+      else after (?P is an error. */
+
+      if (*ptr != CHAR_EQUALS_SIGN)
+        {
+        errorcode = ERR41;
+        goto FAILED;
+        }
+      if (!read_name(&ptr, ptrend, CHAR_RIGHT_PARENTHESIS, &offset, &name,
+          &namelen, &errorcode, cb)) goto FAILED;
+      *parsed_pattern++ = META_BACKREF_BYNAME;
+      *parsed_pattern++ = namelen;
+      PUTOFFSET(offset, parsed_pattern);
+      okquantifier = TRUE;
+      break;   /* End of (?P processing */
+
+
+      /* ---- Recursion/subroutine calls by number ---- */
+
+      case CHAR_R:
+      i = 0;         /* (?R) == (?R0) */
+      ptr++;
+      if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+        {
+        errorcode = ERR58;
+        goto FAILED;
+        }
+      goto SET_RECURSION;
+
+      /* An item starting (?- followed by a digit comes here via the "default"
+      case because (?- followed by a non-digit is an options setting. */
+
+      case CHAR_PLUS:
+      if (ptrend - ptr < 2 || !IS_DIGIT(ptr[1]))
+        {
+        errorcode = ERR29;   /* Missing number */
+        goto FAILED;
+        }
+      /* Fall through */
+
+      case CHAR_0: 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:
+      RECURSION_BYNUMBER:
+      if (!read_number(&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;
+        }
+      if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+        goto UNCLOSED_PARENTHESIS;
+
+      SET_RECURSION:
+      *parsed_pattern++ = META_RECURSE | (uint32_t)i;
+      offset = (PCRE2_SIZE)(ptr - cb->start_pattern);
+      ptr++;
+      PUTOFFSET(offset, parsed_pattern);
+      okquantifier = TRUE;
+      break;  /* End of recursive call by number handling */
+
+
+      /* ---- Recursion/subroutine calls by name ---- */
+
+      case CHAR_AMPERSAND:
+      RECURSE_BY_NAME:
+      if (!read_name(&ptr, ptrend, CHAR_RIGHT_PARENTHESIS, &offset, &name,
+          &namelen, &errorcode, cb)) goto FAILED;
+      *parsed_pattern++ = META_RECURSE_BYNAME;
+      *parsed_pattern++ = namelen;
+      PUTOFFSET(offset, parsed_pattern);
+      okquantifier = TRUE;
+      break;
+
+      /* ---- Callout with numerical or string argument ---- */
+
+      case CHAR_C:
+      if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+      /* If the previous item was a condition starting (?(? an assertion,
+      optionally preceded by a callout, is expected. This is checked later on,
+      during actual compilation. However we need to identify this kind of
+      assertion in this pass because it must not be qualified. The value of
+      expect_cond_assert is set to 2 after (?(? is processed. We decrement it
+      for a callout - still leaving a positive value that identifies the
+      assertion. Multiple callouts or any other items will make it zero or
+      less, which doesn't matter because they will cause an error later. */
+
+      expect_cond_assert = prev_expect_cond_assert - 1;
+
+      /* If previous_callout is not NULL, it means this follows a previous
+      callout. If it was a manual callout, do nothing; this means its "length
+      of next pattern item" field will remain zero. If it was an automatic
+      callout, abolish it. */
+
+      if (previous_callout != NULL && (options & PCRE2_AUTO_CALLOUT) != 0 &&
+          previous_callout == parsed_pattern - 4 &&
+          parsed_pattern[-1] == 255)
+        parsed_pattern = previous_callout;
+
+      /* Save for updating next pattern item length, and skip one item before
+      completing. */
+
+      previous_callout = parsed_pattern;
+      after_manual_callout = 1;
+
+      /* Handle a string argument; specific delimiter is required. */
+
+      if (*ptr != CHAR_RIGHT_PARENTHESIS && !IS_DIGIT(*ptr))
+        {
+        PCRE2_SIZE calloutlength;
+        PCRE2_SPTR startptr = ptr;
+
+        delimiter = 0;
+        for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
+          {
+          if (*ptr == PRIV(callout_start_delims)[i])
+            {
+            delimiter = PRIV(callout_end_delims)[i];
+            break;
+            }
+          }
+        if (delimiter == 0)
+          {
+          errorcode = ERR82;
+          goto FAILED;
+          }
+
+        *parsed_pattern = META_CALLOUT_STRING;
+        parsed_pattern += 3;   /* Skip pattern info */
+
+        for (;;)
+          {
+          if (++ptr >= ptrend)
+            {
+            errorcode = ERR81;
+            ptr = startptr;   /* To give a more useful message */
+            goto FAILED;
+            }
+          if (*ptr == delimiter && (++ptr >= ptrend || *ptr != delimiter))
+            break;
+          }
+
+        calloutlength = (PCRE2_SIZE)(ptr - startptr);
+        if (calloutlength > UINT32_MAX)
+          {
+          errorcode = ERR72;
+          goto FAILED;
+          }
+        *parsed_pattern++ = (uint32_t)calloutlength;
+        offset = (PCRE2_SIZE)(startptr - cb->start_pattern);
+        PUTOFFSET(offset, parsed_pattern);
+        }
+
+      /* Handle a callout with an optional numerical argument, which must be
+      less than or equal to 255. A missing argument gives 0. */
+
+      else
+        {
+        int n = 0;
+        *parsed_pattern = META_CALLOUT_NUMBER;     /* Numerical callout */
+        parsed_pattern += 3;                       /* Skip pattern info */
+        while (ptr < ptrend && IS_DIGIT(*ptr))
+          {
+          n = n * 10 + *ptr++ - CHAR_0;
+          if (n > 255)
+            {
+            errorcode = ERR38;
+            goto FAILED;
+            }
+          }
+        *parsed_pattern++ = n;
+        }
+
+      /* Both formats must have a closing parenthesis */
+
+      if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+        {
+        errorcode = ERR39;
+        goto FAILED;
+        }
+      ptr++;
+
+      /* Remember the offset to the next item in the pattern, and set a default
+      length. This should get updated after the next item is read. */
+
+      previous_callout[1] = (uint32_t)(ptr - cb->start_pattern);
+      previous_callout[2] = 0;
+      break;                  /* End callout */
+
+
+      /* ---- Conditional group ---- */
+
+      /* A condition can be an assertion, a number (referring to a numbered
+      group's having been set), a name (referring to a named group), or 'R',
+      referring to overall recursion. R<digits> and R&name are also permitted
+      for recursion state tests. Numbers may be preceded by + or - to specify a
+      relative group number.
+
+      There are several syntaxes for testing a named group: (?(name)) is used
+      by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
+
+      There are two unfortunate ambiguities. 'R' can be the recursive thing or
+      the name 'R' (and similarly for 'R' followed by digits). 'DEFINE' can be
+      the Perl DEFINE feature or the Python named test. We look for a name
+      first; if not found, we try the other case.
+
+      For compatibility with auto-callouts, we allow a callout to be specified
+      before a condition that is an assertion. */
+
+      case CHAR_LEFT_PARENTHESIS:
+      if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+      nest_depth++;
+
+      /* If the next character is ? there must be an assertion next (optionally
+      preceded by a callout). We do not check this here, but instead we set
+      expect_cond_assert to 2. If this is still greater than zero (callouts
+      decrement it) when the next assertion is read, it will be marked as a
+      condition that must not be repeated. A value greater than zero also
+      causes checking that an assertion (possibly with callout) follows. */
+
+      if (*ptr == CHAR_QUESTION_MARK)
+        {
+        *parsed_pattern++ = META_COND_ASSERT;
+        ptr--;   /* Pull pointer back to the opening parenthesis. */
+        expect_cond_assert = 2;
+        break;  /* End of conditional */
+        }
+
+      /* Handle (?([+-]number)... */
+
+      if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i,
+          &errorcode))
+        {
+        if (i <= 0)
+          {
+          errorcode = ERR15;
+          goto FAILED;
+          }
+        *parsed_pattern++ = META_COND_NUMBER;
+        offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
+        PUTOFFSET(offset, parsed_pattern);
+        *parsed_pattern++ = i;
+        }
+      else if (errorcode != 0) goto FAILED;   /* Number too big */
+
+      /* No number found. Handle the special case (?(VERSION[>]=n.m)... */
+
+      else if (ptrend - ptr >= 10 &&
+               PRIV(strncmp_c8)(ptr, STRING_VERSION, 7) == 0 &&
+               ptr[7] != CHAR_RIGHT_PARENTHESIS)
+        {
+        uint32_t ge = 0;
+        int major = 0;
+        int minor = 0;
+
+        ptr += 7;
+        if (*ptr == CHAR_GREATER_THAN_SIGN)
+          {
+          ge = 1;
+          ptr++;
+          }
+
+        /* NOTE: cannot write IS_DIGIT(*(++ptr)) here because IS_DIGIT
+        references its argument twice. */
+
+        if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr)))
+          goto BAD_VERSION_CONDITION;
+
+        if (!read_number(&ptr, ptrend, -1, 1000, ERR79, &major, &errorcode))
+          goto FAILED;
+
+        if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
+        if (*ptr == CHAR_DOT)
+          {
+          if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION;
+          if (!read_number(&ptr, ptrend, -1, 99 , ERR79, &minor, &errorcode))
+            goto FAILED;
+          if (minor < 10) minor *= 10;
+          if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+            goto BAD_VERSION_CONDITION;
+          }
+
+        *parsed_pattern++ = META_COND_VERSION;
+        *parsed_pattern++ = ge;
+        *parsed_pattern++ = major;
+        *parsed_pattern++ = minor;
+        }
+
+      /* All the remaining cases now require us to read a name. We cannot at
+      this stage distinguish ambiguous cases such as (?(R12) which might be a
+      recursion test by number or a name, because the named groups have not yet
+      all been identified. Those cases are treated as names, but given a
+      different META code. */
+
+      else
+        {
+        BOOL was_r_ampersand = FALSE;
+
+        if (*ptr == CHAR_R && ptrend - ptr > 1 && ptr[1] == CHAR_AMPERSAND)
+          {
+          terminator = CHAR_RIGHT_PARENTHESIS;
+          was_r_ampersand = TRUE;
+          ptr++;
+          }
+        else if (*ptr == CHAR_LESS_THAN_SIGN)
+          terminator = CHAR_GREATER_THAN_SIGN;
+        else if (*ptr == CHAR_APOSTROPHE)
+          terminator = CHAR_APOSTROPHE;
+        else
+          {
+          terminator = CHAR_RIGHT_PARENTHESIS;
+          ptr--;   /* Point to char before name */
+          }
+        if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen,
+            &errorcode, cb)) goto FAILED;
+
+        /* Handle (?(R&name) */
+
+        if (was_r_ampersand)
+          {
+          *parsed_pattern = META_COND_RNAME;
+          ptr--;   /* Back to closing parens */
+          }
+
+        /* Handle (?(name). If the name is "DEFINE" we identify it with a
+        special code. Likewise if the name consists of R followed only by
+        digits. Otherwise, handle it like a quoted name. */
+
+        else if (terminator == CHAR_RIGHT_PARENTHESIS)
+          {
+          if (namelen == 6 && PRIV(strncmp_c8)(name, STRING_DEFINE, 6) == 0)
+            *parsed_pattern = META_COND_DEFINE;
+          else
+            {
+            for (i = 1; i < (int)namelen; i++)
+              if (!IS_DIGIT(name[i])) break;
+            *parsed_pattern = (*name == CHAR_R && i >= (int)namelen)?
+              META_COND_RNUMBER : META_COND_NAME;
+            }
+          ptr--;   /* Back to closing parens */
+          }
+
+        /* Handle (?('name') or (?(<name>) */
+
+        else *parsed_pattern = META_COND_NAME;
+
+        /* All these cases except DEFINE end with the name length and offset;
+        DEFINE just has an offset (for the "too many branches" error). */
+
+        if (*parsed_pattern++ != META_COND_DEFINE) *parsed_pattern++ = namelen;
+        PUTOFFSET(offset, parsed_pattern);
+        }  /* End cases that read a name */
+
+      /* Check the closing parenthesis of the condition */
+
+      if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+        {
+        errorcode = ERR24;
+        goto FAILED;
+        }
+      ptr++;
+      break;  /* End of condition processing */
+
+
+      /* ---- Atomic group ---- */
+
+      case CHAR_GREATER_THAN_SIGN:
+      *parsed_pattern++ = META_ATOMIC;
+      nest_depth++;
+      ptr++;
+      break;
+
+
+      /* ---- Lookahead assertions ---- */
+
+      case CHAR_EQUALS_SIGN:
+      *parsed_pattern++ = META_LOOKAHEAD;
+      ptr++;
+      goto POST_ASSERTION;
+
+      case CHAR_EXCLAMATION_MARK:
+      *parsed_pattern++ = META_LOOKAHEADNOT;
+      ptr++;
+      goto POST_ASSERTION;
+
+
+      /* ---- Lookbehind assertions ---- */
+
+      /* (?< followed by = or ! is a lookbehind assertion. Otherwise (?< is the
+      start of the name of a capturing group. */
+
+      case CHAR_LESS_THAN_SIGN:
+      if (ptrend - ptr <= 1 ||
+         (ptr[1] != CHAR_EQUALS_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK))
+        {
+        terminator = CHAR_GREATER_THAN_SIGN;
+        goto DEFINE_NAME;
+        }
+      *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?
+        META_LOOKBEHIND : META_LOOKBEHINDNOT;
+      *has_lookbehind = TRUE;
+      offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
+      PUTOFFSET(offset, parsed_pattern);
+      ptr += 2;
+      /* Fall through */
+
+      /* If the previous item was a condition starting (?(? an assertion,
+      optionally preceded by a callout, is expected. This is checked later on,
+      during actual compilation. However we need to identify this kind of
+      assertion in this pass because it must not be qualified. The value of
+      expect_cond_assert is set to 2 after (?(? is processed. We decrement it
+      for a callout - still leaving a positive value that identifies the
+      assertion. Multiple callouts or any other items will make it zero or
+      less, which doesn't matter because they will cause an error later. */
+
+      POST_ASSERTION:
+      nest_depth++;
+      if (prev_expect_cond_assert > 0)
+        {
+        if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
+        else if (++top_nest >= end_nests)
+          {
+          errorcode = ERR84;
+          goto FAILED;
+          }
+        top_nest->nest_depth = nest_depth;
+        top_nest->flags = NSF_CONDASSERT;
+        top_nest->options = options & PARSE_TRACKED_OPTIONS;
+        }
+      break;
+
+
+      /* ---- Define a named group ---- */
+
+      /* A named group may be defined as (?'name') or (?<name>). In the latter
+      case we jump to DEFINE_NAME from the disambiguation of (?< above with the
+      terminator set to '>'. */
+
+      case CHAR_APOSTROPHE:
+      terminator = CHAR_APOSTROPHE;    /* Terminator */
+
+      DEFINE_NAME:
+      if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen,
+          &errorcode, cb)) goto FAILED;
+
+      /* We have a name for this capturing group. It is also assigned a number,
+      which is its primary means of identification. */
+
+      cb->bracount++;
+      *parsed_pattern++ = META_CAPTURE | cb->bracount;
+      nest_depth++;
+
+      /* Check not too many names */
+
+      if (cb->names_found >= MAX_NAME_COUNT)
+        {
+        errorcode = ERR49;
+        goto FAILED;
+        }
+
+      /* Adjust the entry size to accommodate the longest name found. */
+
+      if (namelen + IMM2_SIZE + 1 > cb->name_entry_size)
+        cb->name_entry_size = (uint16_t)(namelen + IMM2_SIZE + 1);
+
+      /* Scan the list to check for duplicates. For duplicate names, if the
+      number is the same, break the loop, which causes the name to be
+      discarded; otherwise, if DUPNAMES is not set, give an error.
+      If it is set, allow the name with a different number, but continue
+      scanning in case this is a duplicate with the same number. For
+      non-duplicate names, give an error if the number is duplicated. */
+
+      isdupname = FALSE;
+      ng = cb->named_groups;
+      for (i = 0; i < cb->names_found; i++, ng++)
+        {
+        if (namelen == ng->length &&
+            PRIV(strncmp)(name, ng->name, (PCRE2_SIZE)namelen) == 0)
+          {
+          if (ng->number == cb->bracount) break;
+          if ((options & PCRE2_DUPNAMES) == 0)
+            {
+            errorcode = ERR43;
+            goto FAILED;
+            }
+          isdupname = ng->isdup = TRUE;     /* Mark as a duplicate */
+          cb->dupnames = TRUE;              /* Duplicate names exist */
+          }
+        else if (ng->number == cb->bracount)
+          {
+          errorcode = ERR65;
+          goto FAILED;
+          }
+        }
+
+      if (i < cb->names_found) break;   /* Ignore duplicate with same number */
+
+      /* Increase the list size if necessary */
+
+      if (cb->names_found >= cb->named_group_list_size)
+        {
+        uint32_t newsize = cb->named_group_list_size * 2;
+        named_group *newspace =
+          cb->cx->memctl.malloc(newsize * sizeof(named_group),
+          cb->cx->memctl.memory_data);
+        if (newspace == NULL)
+          {
+          errorcode = ERR21;
+          goto FAILED;
+          }
+
+        memcpy(newspace, cb->named_groups,
+          cb->named_group_list_size * sizeof(named_group));
+        if (cb->named_group_list_size > NAMED_GROUP_LIST_SIZE)
+          cb->cx->memctl.free((void *)cb->named_groups,
+          cb->cx->memctl.memory_data);
+        cb->named_groups = newspace;
+        cb->named_group_list_size = newsize;
+        }
+
+      /* Add this name to the list */
+
+      cb->named_groups[cb->names_found].name = name;
+      cb->named_groups[cb->names_found].length = (uint16_t)namelen;
+      cb->named_groups[cb->names_found].number = cb->bracount;
+      cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname;
+      cb->names_found++;
+      break;
+      }        /* End of (? switch */
+    break;     /* End of ( handling */
+
+
+    /* ---- Branch terminators ---- */
+
+    /* Alternation: reset the capture count if we are in a (?| group. */
+
+    case CHAR_VERTICAL_LINE:
+    if (top_nest != NULL && top_nest->nest_depth == nest_depth &&
+        (top_nest->flags & NSF_RESET) != 0)
+      {
+      if (cb->bracount > top_nest->max_group)
+        top_nest->max_group = (uint16_t)cb->bracount;
+      cb->bracount = top_nest->reset_group;
+      }
+    *parsed_pattern++ = META_ALT;
+    break;
+
+    /* End of group; reset the capture count to the maximum if we are in a (?|
+    group and/or reset the options that are tracked during parsing. Disallow
+    quantifier for a condition that is an assertion. */
+
+    case CHAR_RIGHT_PARENTHESIS:
+    okquantifier = TRUE;
+    if (top_nest != NULL && top_nest->nest_depth == nest_depth)
+      {
+      options = (options & ~PARSE_TRACKED_OPTIONS) | top_nest->options;
+      if ((top_nest->flags & NSF_RESET) != 0 &&
+          top_nest->max_group > cb->bracount)
+        cb->bracount = top_nest->max_group;
+      if ((top_nest->flags & NSF_CONDASSERT) != 0)
+        okquantifier = FALSE;
+      if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL;
+        else top_nest--;
+      }
+    if (nest_depth == 0)    /* Unmatched closing parenthesis */
+      {
+      errorcode = ERR22;
+      goto FAILED_BACK;
+      }
+    nest_depth--;
+    *parsed_pattern++ = META_KET;
+    break;
+    }  /* End of switch on pattern character */
+  }    /* End of main character scan loop */
+
+/* End of pattern reached. Check for missing ) at the end of a verb name. */
+
+if (inverbname && ptr >= ptrend)
   {
-  groupinfo |= GI_NOT_FIXED_LENGTH;
-  cb->groupinfo[group] = groupinfo;
+  errorcode = ERR60;
+  goto FAILED;
   }
-return FFL_NOTFIXED;
+
+/* Manage callout for the final item */
+
+PARSED_END:
+parsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout,
+  parsed_pattern, cb);
+
+/* Insert trailing items for word and line matching (features provided for the
+benefit of pcre2grep). */
+
+if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_LINE) != 0)
+  {
+  *parsed_pattern++ = META_KET;
+  *parsed_pattern++ = META_DOLLAR;
+  }
+else if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_WORD) != 0)
+  {
+  *parsed_pattern++ = META_KET;
+  *parsed_pattern++ = META_ESCAPE + ESC_b;
+  }
+
+/* Terminate the parsed pattern, then return success if all groups are closed.
+Otherwise we have unclosed parentheses. */
+
+if (parsed_pattern >= parsed_pattern_end)
+  {
+  errorcode = ERR63;  /* Internal error (parsed pattern overflow) */
+  goto FAILED;
+  }
+
+*parsed_pattern = META_END;
+if (nest_depth == 0) return 0;
+
+UNCLOSED_PARENTHESIS:
+errorcode = ERR14;
+
+/* Come here for all failures. */
+
+FAILED:
+cb->erroroffset = (PCRE2_SIZE)(ptr - cb->start_pattern);
+return errorcode;
+
+/* Some errors need to indicate the previous character. */
+
+FAILED_BACK:
+ptr--;
+goto FAILED;
+
+/* This failure happens several times. */
+
+BAD_VERSION_CONDITION:
+errorcode = ERR79;
+goto FAILED;
 }
 
 
@@ -1320,6 +4311,18 @@
     code += GET(code, 1 + 2*LINK_SIZE);
     break;
 
+    case OP_SKIPZERO:
+    code += 2 + GET(code, 2) + LINK_SIZE;
+    break;
+
+    case OP_COND:
+    case OP_SCOND:
+    if (code[1+LINK_SIZE] != OP_FALSE ||   /* Not DEFINE */
+        code[GET(code, 1)] != OP_KET)      /* More than one branch */
+      return code;
+    code += GET(code, 1) + 1 + LINK_SIZE;
+    break;
+
     default:
     return code;
     }
@@ -1329,1133 +4332,3612 @@
 
 
 
+#ifdef SUPPORT_UNICODE
 /*************************************************
-*    Scan compiled branch for non-emptiness      *
+*           Get othercase range                  *
 *************************************************/
 
-/* This function scans through a branch of a compiled pattern to see whether it
-can match the empty string. It is called at the end of compiling to check the
-entire pattern, and from compile_branch() when checking for an unlimited repeat
-of a group that can match nothing. In the latter case it is called only when
-doing the real compile, not during the pre-compile that measures the size of
-the compiled pattern.
-
-Note that first_significant_code() skips over backward and negative forward
-assertions when its final argument is TRUE. If we hit an unclosed bracket, we
-return "empty" - this means we've struck an inner bracket whose current branch
-will already have been scanned.
+/* This function is passed the start and end of a class range in UCP mode. It
+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:
-  code        points to start of search
-  endcode     points to where to stop
-  utf         TRUE if in UTF mode
-  cb          compile data
-  atend       TRUE if being called to check an entire pattern
-  recurses    chain of recurse_check to catch mutual recursion
-  countptr    pointer to count to catch over-complicated pattern
+  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
 
-Returns:      0 if what is matched cannot be empty
-              1 if what is matched could be empty
-             -1 if the pattern is too complicated
+Yield:        -1 when no more
+               0 when a range is returned
+              >0 the CASESET offset for char with multiple other cases
+                in this case, ocptr contains the original
 */
 
-#define CBE_NOTEMPTY          0
-#define CBE_EMPTY             1
-#define CBE_TOOCOMPLICATED  (-1)
-
-
 static int
-could_be_empty_branch(PCRE2_SPTR code, PCRE2_SPTR endcode, BOOL utf,
-  compile_block *cb, BOOL atend, recurse_check *recurses, int *countptr)
+get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr,
+  uint32_t *odptr)
 {
-uint32_t group = 0;
-uint32_t groupinfo = 0;
-register PCRE2_UCHAR c;
-recurse_check this_recurse;
+uint32_t c, othercase, next;
+unsigned int co;
 
-/* If what we are checking has already been set as "could be empty", we know
-the answer. */
+/* Find the first character that has an other case. If it has multiple other
+cases, return its case offset value. */
 
-if (*code >= OP_SBRA && *code <= OP_SCOND) return CBE_EMPTY;
-
-/* If this is a capturing group, we may have the answer cached, but we can only
-use this information if there are no (?| groups in the pattern, because
-otherwise group numbers are not unique. */
-
-if ((cb->external_flags & PCRE2_DUPCAPUSED) == 0 &&
-    (*code == OP_CBRA || *code == OP_CBRAPOS))
+for (c = *cptr; c <= d; c++)
   {
-  group = GET2(code, 1 + LINK_SIZE);
-  groupinfo = cb->groupinfo[group];
-  if ((groupinfo & GI_SET_COULD_BE_EMPTY) != 0)
-    return ((groupinfo & GI_COULD_BE_EMPTY) != 0)? CBE_EMPTY : CBE_NOTEMPTY;
+  if ((co = UCD_CASESET(c)) != 0)
+    {
+    *ocptr = c++;   /* Character that has the set */
+    *cptr = c;      /* Rest of input range */
+    return (int)co;
+    }
+  if ((othercase = UCD_OTHERCASE(c)) != c) break;
   }
 
-/* A large and/or complex regex can take too long to process. We have to assume
-it can match an empty string. This can happen more often when (?| groups are
-present in the pattern and the caching is disabled. Setting the cap at 1100
-allows the test for more than 1023 capturing patterns to work. */
+if (c > d) return -1;  /* Reached end of range */
 
-if ((*countptr)++ > 1100) return CBE_TOOCOMPLICATED;
+/* 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. */
 
-/* Scan the opcodes for this branch. */
+*ocptr = othercase;
+next = othercase + 1;
 
-for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
-     code < endcode;
-     code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
+for (++c; c <= d; c++)
   {
-  PCRE2_SPTR ccode;
-
-  c = *code;
-
-  /* Skip over forward assertions; the other assertions are skipped by
-  first_significant_code() with a TRUE final argument. */
-
-  if (c == OP_ASSERT)
-    {
-    do code += GET(code, 1); while (*code == OP_ALT);
-    c = *code;
-    continue;
-    }
-
-  /* For a recursion/subroutine call we can scan the recursion when this
-  function is called at the end, to check a complete pattern. Before then,
-  recursions just have the group number as their argument and in any case may
-  be forward references. In that situation, we return CBE_EMPTY, just in case.
-  It means that unlimited repeats of groups that contain recursions are always
-  treated as "could be empty" - which just adds a bit more processing time
-  because of the runtime check. */
-
-  if (c == OP_RECURSE)
-    {
-    PCRE2_SPTR scode, endgroup;
-    BOOL empty_branch;
-
-    if (!atend) goto ISTRUE;
-    scode = cb->start_code + GET(code, 1);
-    endgroup = scode;
-
-    /* We need to detect whether this is a recursive call, as otherwise there
-    will be an infinite loop. If it is a recursion, just skip over it. Simple
-    recursions are easily detected. For mutual recursions we keep a chain on
-    the stack. */
-
-    do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
-    if (code >= scode && code <= endgroup) continue;  /* Simple recursion */
-    else
-      {
-      recurse_check *r = recurses;
-      for (r = recurses; r != NULL; r = r->prev)
-        if (r->group == scode) break;
-      if (r != NULL) continue;   /* Mutual recursion */
-      }
-
-    /* Scan the referenced group, remembering it on the stack chain to detect
-    mutual recursions. */
-
-    empty_branch = FALSE;
-    this_recurse.prev = recurses;
-    this_recurse.group = scode;
-
-    do
-      {
-      int rc = could_be_empty_branch(scode, endcode, utf, cb, atend,
-        &this_recurse, countptr);
-      if (rc < 0) return rc;
-      if (rc > 0)
-        {
-        empty_branch = TRUE;
-        break;
-        }
-      scode += GET(scode, 1);
-      }
-    while (*scode == OP_ALT);
-
-    if (!empty_branch) goto ISFALSE;  /* All branches are non-empty */
-    continue;
-    }
-
-  /* Groups with zero repeats can of course be empty; skip them. */
-
-  if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO ||
-      c == OP_BRAPOSZERO)
-    {
-    code += PRIV(OP_lengths)[c];
-    do code += GET(code, 1); while (*code == OP_ALT);
-    c = *code;
-    continue;
-    }
-
-  /* A nested group that is already marked as "could be empty" can just be
-  skipped. */
-
-  if (c == OP_SBRA  || c == OP_SBRAPOS ||
-      c == OP_SCBRA || c == OP_SCBRAPOS)
-    {
-    do code += GET(code, 1); while (*code == OP_ALT);
-    c = *code;
-    continue;
-    }
-
-  /* For other groups, scan the branches. */
-
-  if (c == OP_BRA  || c == OP_BRAPOS ||
-      c == OP_CBRA || c == OP_CBRAPOS ||
-      c == OP_ONCE || c == OP_ONCE_NC ||
-      c == OP_COND || c == OP_SCOND)
-    {
-    BOOL empty_branch;
-    if (GET(code, 1) == 0) goto ISTRUE;    /* Hit unclosed bracket */
-
-    /* If a conditional group has only one branch, there is a second, implied,
-    empty branch, so just skip over the conditional, because it could be empty.
-    Otherwise, scan the individual branches of the group. */
-
-    if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
-      code += GET(code, 1);
-    else
-      {
-      empty_branch = FALSE;
-      do
-        {
-        if (!empty_branch)
-          {
-          int rc = could_be_empty_branch(code, endcode, utf, cb, atend,
-            recurses, countptr);
-          if (rc < 0) return rc;
-          if (rc > 0) empty_branch = TRUE;
-          }
-        code += GET(code, 1);
-        }
-      while (*code == OP_ALT);
-      if (!empty_branch) goto ISFALSE;   /* All branches are non-empty */
-      }
-
-    c = *code;
-    continue;
-    }
-
-  /* Handle the other opcodes */
-
-  switch (c)
-    {
-    /* Check for quantifiers after a class. XCLASS is used for classes that
-    cannot be represented just by a bit map. This includes negated single
-    high-valued characters. The length in PRIV(OP_lengths)[] is zero; the
-    actual length is stored in the compiled code, so we must update "code"
-    here. */
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
-    case OP_XCLASS:
-    ccode = code += GET(code, 1);
-    goto CHECK_CLASS_REPEAT;
-#endif
-
-    case OP_CLASS:
-    case OP_NCLASS:
-    ccode = code + PRIV(OP_lengths)[OP_CLASS];
-
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
-    CHECK_CLASS_REPEAT:
-#endif
-
-    switch (*ccode)
-      {
-      case OP_CRSTAR:            /* These could be empty; continue */
-      case OP_CRMINSTAR:
-      case OP_CRQUERY:
-      case OP_CRMINQUERY:
-      case OP_CRPOSSTAR:
-      case OP_CRPOSQUERY:
-      break;
-
-      default:                   /* Non-repeat => class must match */
-      case OP_CRPLUS:            /* These repeats aren't empty */
-      case OP_CRMINPLUS:
-      case OP_CRPOSPLUS:
-      goto ISFALSE;
-
-      case OP_CRRANGE:
-      case OP_CRMINRANGE:
-      case OP_CRPOSRANGE:
-      if (GET2(ccode, 1) > 0) goto ISFALSE;  /* Minimum > 0 */
-      break;
-      }
-    break;
-
-    /* Opcodes that must match a character */
-
-    case OP_ANY:
-    case OP_ALLANY:
-    case OP_ANYBYTE:
-
-    case OP_PROP:
-    case OP_NOTPROP:
-    case OP_ANYNL:
-
-    case OP_NOT_HSPACE:
-    case OP_HSPACE:
-    case OP_NOT_VSPACE:
-    case OP_VSPACE:
-    case OP_EXTUNI:
-
-    case OP_NOT_DIGIT:
-    case OP_DIGIT:
-    case OP_NOT_WHITESPACE:
-    case OP_WHITESPACE:
-    case OP_NOT_WORDCHAR:
-    case OP_WORDCHAR:
-
-    case OP_CHAR:
-    case OP_CHARI:
-    case OP_NOT:
-    case OP_NOTI:
-
-    case OP_PLUS:
-    case OP_PLUSI:
-    case OP_MINPLUS:
-    case OP_MINPLUSI:
-
-    case OP_NOTPLUS:
-    case OP_NOTPLUSI:
-    case OP_NOTMINPLUS:
-    case OP_NOTMINPLUSI:
-
-    case OP_POSPLUS:
-    case OP_POSPLUSI:
-    case OP_NOTPOSPLUS:
-    case OP_NOTPOSPLUSI:
-
-    case OP_EXACT:
-    case OP_EXACTI:
-    case OP_NOTEXACT:
-    case OP_NOTEXACTI:
-
-    case OP_TYPEPLUS:
-    case OP_TYPEMINPLUS:
-    case OP_TYPEPOSPLUS:
-    case OP_TYPEEXACT:
-    goto ISFALSE;
-
-    /* These are going to continue, as they may be empty, but we have to
-    fudge the length for the \p and \P cases. */
-
-    case OP_TYPESTAR:
-    case OP_TYPEMINSTAR:
-    case OP_TYPEPOSSTAR:
-    case OP_TYPEQUERY:
-    case OP_TYPEMINQUERY:
-    case OP_TYPEPOSQUERY:
-    if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
-    break;
-
-    /* Same for these */
-
-    case OP_TYPEUPTO:
-    case OP_TYPEMINUPTO:
-    case OP_TYPEPOSUPTO:
-    if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
-      code += 2;
-    break;
-
-    /* End of branch */
-
-    case OP_KET:
-    case OP_KETRMAX:
-    case OP_KETRMIN:
-    case OP_KETRPOS:
-    case OP_ALT:
-    goto ISTRUE;
-
-    /* In UTF-8 or UTF-16 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY,
-    POSQUERY, UPTO, MINUPTO, and POSUPTO and their caseless and negative
-    versions may be followed by a multibyte character. */
-
-#ifdef MAYBE_UTF_MULTI
-    case OP_STAR:
-    case OP_STARI:
-    case OP_NOTSTAR:
-    case OP_NOTSTARI:
-
-    case OP_MINSTAR:
-    case OP_MINSTARI:
-    case OP_NOTMINSTAR:
-    case OP_NOTMINSTARI:
-
-    case OP_POSSTAR:
-    case OP_POSSTARI:
-    case OP_NOTPOSSTAR:
-    case OP_NOTPOSSTARI:
-
-    case OP_QUERY:
-    case OP_QUERYI:
-    case OP_NOTQUERY:
-    case OP_NOTQUERYI:
-
-    case OP_MINQUERY:
-    case OP_MINQUERYI:
-    case OP_NOTMINQUERY:
-    case OP_NOTMINQUERYI:
-
-    case OP_POSQUERY:
-    case OP_POSQUERYI:
-    case OP_NOTPOSQUERY:
-    case OP_NOTPOSQUERYI:
-    if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
-    break;
-
-    case OP_UPTO:
-    case OP_UPTOI:
-    case OP_NOTUPTO:
-    case OP_NOTUPTOI:
-
-    case OP_MINUPTO:
-    case OP_MINUPTOI:
-    case OP_NOTMINUPTO:
-    case OP_NOTMINUPTOI:
-
-    case OP_POSUPTO:
-    case OP_POSUPTOI:
-    case OP_NOTPOSUPTO:
-    case OP_NOTPOSUPTOI:
-    if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
-    break;
-#endif  /* MAYBE_UTF_MULTI */
-
-    /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument
-    string. */
-
-    case OP_MARK:
-    case OP_PRUNE_ARG:
-    case OP_SKIP_ARG:
-    case OP_THEN_ARG:
-    code += code[1];
-    break;
-
-    /* None of the remaining opcodes are required to match a character. */
-
-    default:
-    break;
-    }
+  if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break;
+  next++;
   }
 
-ISTRUE:
-groupinfo |= GI_COULD_BE_EMPTY;
-
-ISFALSE:
-if (group > 0) cb->groupinfo[group] = groupinfo | GI_SET_COULD_BE_EMPTY;
-
-return ((groupinfo & GI_COULD_BE_EMPTY) != 0)? CBE_EMPTY : CBE_NOTEMPTY;
+*odptr = next - 1;     /* End of othercase range */
+*cptr = c;             /* Rest of input range */
+return 0;
 }
+#endif  /* SUPPORT_UNICODE */
 
 
 
 /*************************************************
-*            Check for counted repeat            *
+* Add a character or range to a class (internal) *
 *************************************************/
 
-/* This function is called when a '{' is encountered in a place where it might
-start a quantifier. It looks ahead to see if it really is a quantifier, that
-is, one of the forms {ddd} {ddd,} or {ddd,ddd} where the ddds are digits.
-
-Argument:   pointer to the first char after '{'
-Returns:    TRUE or FALSE
-*/
-
-static BOOL
-is_counted_repeat(PCRE2_SPTR p)
-{
-if (!IS_DIGIT(*p)) return FALSE;
-p++;
-while (IS_DIGIT(*p)) p++;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if (*p++ != CHAR_COMMA) return FALSE;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if (!IS_DIGIT(*p)) return FALSE;
-p++;
-while (IS_DIGIT(*p)) p++;
-
-return (*p == CHAR_RIGHT_CURLY_BRACKET);
-}
-
-
-
-/*************************************************
-*            Handle escapes                      *
-*************************************************/
-
-/* 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
-entry, ptr is pointing at the \. On exit, it points 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 only
-sequences that define a data character are recognised. The isclass argument is
-not relevant, but the options argument is the final value of the compiled
-pattern's options.
-
-There is one "trick" case: when a sequence such as [[:>:]] or \s in UCP mode is
-processed, it is replaced by a nested alternative sequence. If this contains a
-backslash (which is usually does), ptrend does not point to its end - it still
-points to the end of the whole pattern. However, we can detect this case
-because cb->nestptr[0] will be non-NULL. The nested sequences are all zero-
-terminated and there are only ever two levels of nesting.
+/* 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:
-  ptrptr         points to the input position pointer
-  ptrend         points to the end of the input
-  chptr          points to a returned data character
-  errorcodeptr   points to the errorcode variable (containing zero)
-  options        the current options bits
-  isclass        TRUE if inside a character class
-  cb             compile data block
+  classbits     the bit map for characters < 256
+  uchardptr     points to the pointer for extra data
+  options       the options word
+  cb            compile data
+  start         start of range character
+  end           end of range character
 
-Returns:         zero => a data character
-                 positive => a special escape sequence
-                 negative => a back reference
-                 on error, errorcodeptr is set non-zero
+Returns:        the number of < 256 characters added
+                the pointer to extra data is updated
 */
 
-int
-PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr,
-  int *errorcodeptr, uint32_t options, BOOL isclass, compile_block *cb)
+static unsigned int
+add_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
+  uint32_t options, compile_block *cb, uint32_t start, uint32_t end)
 {
-BOOL utf = (options & PCRE2_UTF) != 0;
-PCRE2_SPTR ptr = *ptrptr + 1;
-register uint32_t c, cc;
-int escape = 0;
-int i;
+uint32_t c;
+uint32_t classbits_end = (end <= 0xff ? end : 0xff);
+unsigned int n8 = 0;
 
-/* Find the end of a nested insert. */
+/* 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. Sometimes we can just extend the original
+range. */
 
-if (cb != NULL && cb->nestptr[0] != NULL)
-  ptrend = ptr + PRIV(strlen)(ptr);
-
-/* If backslash is at the end of the string, it's an error. */
-
-if (ptr >= ptrend)
+if ((options & PCRE2_CASELESS) != 0)
   {
-  *errorcodeptr = ERR1;
-  return 0;
-  }
-
-GETCHARINCTEST(c, ptr);         /* Get character value, increment pointer */
-ptr--;                          /* Set pointer back to the last code unit */
-
-/* Non-alphanumerics are literals, so we just leave the value in c. An initial
-value test saves a memory lookup for code points outside the alphanumeric
-range. Otherwise, do a table lookup. A non-zero result is something that can be
-returned immediately. Otherwise further processing is required. */
-
-if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {}  /* Definitely literal */
-
-else if ((i = escapes[c - ESCAPES_FIRST]) != 0)
-  {
-  if (i > 0) c = (uint32_t)i; else  /* Positive is a data character */
+#ifdef SUPPORT_UNICODE
+  if ((options & PCRE2_UTF) != 0)
     {
-    escape = -i;                    /* Else return a special escape */
-    if (escape == ESC_P || escape == ESC_p || escape == ESC_X)
-      cb->external_flags |= PCRE2_HASBKPORX;   /* Note \P, \p, or \X */
+    int rc;
+    uint32_t oc, od;
+
+    options &= ~PCRE2_CASELESS;   /* Remove for recursive calls */
+    c = start;
+
+    while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0)
+      {
+      /* Handle a single character that has more than one other case. */
+
+      if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, options, 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, cb, oc, od);
+      }
+    }
+  else
+#endif  /* SUPPORT_UNICODE */
+
+  /* Not UTF mode */
+
+  for (c = start; c <= classbits_end; c++)
+    {
+    SETBIT(classbits, cb->fcc[c]);
+    n8++;
     }
   }
 
-/* Escapes that need further processing, including those that are unknown.
-When called from pcre2_substitute(), only \c, \o, and \x are recognized (and \u
-when BSUX is set). */
+/* 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. */
 
-else
+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++)
   {
-  PCRE2_SPTR oldptr;
-  BOOL braced, negated, overflow;
-  unsigned int s;
+  /* Regardless of start, c will always be <= 255. */
+  SETBIT(classbits, c);
+  n8++;
+  }
 
-  /* Filter calls from pcre2_substitute(). */
+#ifdef SUPPORT_WIDE_CHARS
+if (start <= 0xff) start = 0xff + 1;
 
-  if (cb == NULL && c != CHAR_c && c != CHAR_o && c != CHAR_x &&
-      (c != CHAR_u || (options & PCRE2_ALT_BSUX) != 0))
+if (end >= start)
+  {
+  PCRE2_UCHAR *uchardata = *uchardptr;
+
+#ifdef SUPPORT_UNICODE
+  if ((options & PCRE2_UTF) != 0)
     {
-    *errorcodeptr = ERR3;
-    return 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 */
 
-  switch (c)
-    {
-    /* A number of Perl escapes are not handled by PCRE. We give an explicit
-    error. */
+  /* Without UTF support, character values are constrained by the bit length,
+  and can only be > 256 for 16-bit and 32-bit libraries. */
 
-    case CHAR_l:
-    case CHAR_L:
-    *errorcodeptr = ERR37;
-    break;
-
-    /* \u is unrecognized when PCRE2_ALT_BSUX is not set. When it is treated
-    specially, \u must be followed by four hex digits. Otherwise it is a
-    lowercase u letter. */
-
-    case CHAR_u:
-    if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; else
-      {
-      uint32_t xc;
-      if ((cc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */
-      if ((xc = XDIGIT(ptr[2])) == 0xff) break;  /* Not a hex digit */
-      cc = (cc << 4) | xc;
-      if ((xc = XDIGIT(ptr[3])) == 0xff) break;  /* Not a hex digit */
-      cc = (cc << 4) | xc;
-      if ((xc = XDIGIT(ptr[4])) == 0xff) break;  /* Not a hex digit */
-      c = (cc << 4) | xc;
-      ptr += 4;
-      if (utf)
-        {
-        if (c > 0x10ffffU) *errorcodeptr = ERR77;
-          else if (c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
-        }
-      else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77;
-      }
-    break;
-
-    case CHAR_U:
-    /* \U is unrecognized unless PCRE2_ALT_BSUX is set, in which case it is an
-    upper case letter. */
-    if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37;
-    break;
-
-    /* In a character class, \g is just a literal "g". Outside a character
-    class, \g must be followed by one of a number of specific things:
-
-    (1) A number, either plain or braced. If positive, it is an absolute
-    backreference. If negative, it is a relative backreference. This is a Perl
-    5.10 feature.
-
-    (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
-    is part of Perl's movement towards a unified syntax for back references. As
-    this is synonymous with \k{name}, we fudge it up by pretending it really
-    was \k.
-
-    (3) For Oniguruma compatibility we also support \g followed by a name or a
-    number either in angle brackets or in single quotes. However, these are
-    (possibly recursive) subroutine calls, _not_ backreferences. Just return
-    the ESC_g code (cf \k). */
-
-    case CHAR_g:
-    if (isclass) break;
-    if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE)
-      {
-      escape = ESC_g;
-      break;
-      }
-
-    /* Handle the Perl-compatible cases */
-
-    if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
-      {
-      PCRE2_SPTR p;
-      for (p = ptr+2; *p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET; p++)
-        if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break;
-      if (*p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET)
-        {
-        escape = ESC_k;
-        break;
-        }
-      braced = TRUE;
-      ptr++;
-      }
-    else braced = FALSE;
-
-    if (ptr[1] == CHAR_MINUS)
-      {
-      negated = TRUE;
-      ptr++;
-      }
-    else negated = FALSE;
-
-    /* The integer range is limited by the machine's int representation. */
-    s = 0;
-    overflow = FALSE;
-    while (IS_DIGIT(ptr[1]))
-      {
-      if (s > INT_MAX / 10 - 1) /* Integer overflow */
-        {
-        overflow = TRUE;
-        break;
-        }
-      s = s * 10 + (unsigned int)(*(++ptr) - CHAR_0);
-      }
-    if (overflow) /* Integer overflow */
-      {
-      while (IS_DIGIT(ptr[1])) ptr++;
-      *errorcodeptr = ERR61;
-      break;
-      }
-
-    if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET)
-      {
-      *errorcodeptr = ERR57;
-      break;
-      }
-
-    if (s == 0)
-      {
-      *errorcodeptr = ERR58;
-      break;
-      }
-
-    if (negated)
-      {
-      if (s > cb->bracount)
-        {
-        *errorcodeptr = ERR15;
-        break;
-        }
-      s = cb->bracount - (s - 1);
-      }
-
-    escape = -(int)s;
-    break;
-
-    /* The handling of escape sequences consisting of a string of digits
-    starting with one that is not zero is not straightforward. Perl has changed
-    over the years. Nowadays \g{} for backreferences and \o{} for octal are
-    recommended to avoid the ambiguities in the old syntax.
-
-    Outside a character class, the digits are read as a decimal number. If the
-    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).
-
-    Inside a character class, \ followed by a digit is always either a literal
-    8 or 9 or an octal number. */
-
-    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)
-      {
-      oldptr = ptr;
-      /* The integer range is limited by the machine's int representation. */
-      s = c - CHAR_0;
-      overflow = FALSE;
-      while (IS_DIGIT(ptr[1]))
-        {
-        if (s > INT_MAX / 10 - 1) /* Integer overflow */
-          {
-          overflow = TRUE;
-          break;
-          }
-        s = s * 10 + (unsigned int)(*(++ptr) - CHAR_0);
-        }
-      if (overflow) /* Integer overflow */
-        {
-        while (IS_DIGIT(ptr[1])) ptr++;
-        *errorcodeptr = ERR61;
-        break;
-        }
-
-      /* \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 (s < 10 || *oldptr >= CHAR_8 || s <= cb->bracount)
-        {
-        escape = -(int)s;     /* Indicates a back reference */
-        break;
-        }
-      ptr = oldptr;      /* Put the pointer back and fall through */
-      }
-
-    /* Handle a digit following \ when the number is not a back reference, or
-    we are within a character class. If the first digit is 8 or 9, Perl used to
-    generate a binary zero byte and then treat the digit as a following
-    literal. At least by Perl 5.18 this changed so as not to insert the binary
-    zero. */
-
-    if ((c = *ptr) >= CHAR_8) break;
-
-    /* Fall through with a digit less than 8 */
-
-    /* \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,
-    but no more than 3 octal digits. */
-
-    case CHAR_0:
-    c -= CHAR_0;
-    while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)
-        c = c * 8 + *(++ptr) - CHAR_0;
 #if PCRE2_CODE_UNIT_WIDTH == 8
-    if (!utf && c > 0xff) *errorcodeptr = ERR51;
-#endif
-    break;
-
-    /* \o is a relatively new Perl feature, supporting a more general way of
-    specifying character codes in octal. The only supported form is \o{ddd}. */
-
-    case CHAR_o:
-    if (ptr[1] != CHAR_LEFT_CURLY_BRACKET) *errorcodeptr = ERR55; else
-    if (ptr[2] == CHAR_RIGHT_CURLY_BRACKET) *errorcodeptr = ERR78; else
-      {
-      ptr += 2;
-      c = 0;
-      overflow = FALSE;
-      while (*ptr >= CHAR_0 && *ptr <= CHAR_7)
-        {
-        cc = *ptr++;
-        if (c == 0 && cc == CHAR_0) continue;     /* Leading zeroes */
-#if PCRE2_CODE_UNIT_WIDTH == 32
-        if (c >= 0x20000000l) { overflow = TRUE; break; }
-#endif
-        c = (c << 3) + (cc - CHAR_0);
-#if PCRE2_CODE_UNIT_WIDTH == 8
-        if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-        if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-        if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
-#endif
-        }
-      if (overflow)
-        {
-        while (*ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;
-        *errorcodeptr = ERR34;
-        }
-      else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
-        {
-        if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
-        }
-      else *errorcodeptr = ERR64;
-      }
-    break;
-
-    /* \x is complicated. When PCRE2_ALT_BSUX is set, \x must be followed by
-    two hexadecimal digits. Otherwise it is a lowercase x letter. */
-
-    case CHAR_x:
-    if ((options & PCRE2_ALT_BSUX) != 0)
-      {
-      uint32_t xc;
-      if ((cc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */
-      if ((xc = XDIGIT(ptr[2])) == 0xff) break;  /* Not a hex digit */
-      c = (cc << 4) | xc;
-      ptr += 2;
-      }    /* End PCRE2_ALT_BSUX handling */
-
-    /* Handle \x in Perl's style. \x{ddd} is a character number which can be
-    greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex
-    digits. If not, { used to be treated as a data character. However, Perl
-    seems to read hex digits up to the first non-such, and ignore the rest, so
-    that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE
-    now gives an error. */
-
-    else
-      {
-      if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
-        {
-        ptr += 2;
-        if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
-          {
-          *errorcodeptr = ERR78;
-          break;
-          }
-        c = 0;
-        overflow = FALSE;
-
-        while ((cc = XDIGIT(*ptr)) != 0xff)
-          {
-          ptr++;
-          if (c == 0 && cc == 0) continue;   /* Leading zeroes */
-#if PCRE2_CODE_UNIT_WIDTH == 32
-          if (c >= 0x10000000l) { overflow = TRUE; break; }
-#endif
-          c = (c << 4) | cc;
-          if ((utf && c > 0x10ffffU) || (!utf && c > MAX_NON_UTF_CHAR))
-            {
-            overflow = TRUE;
-            break;
-            }
-          }
-
-        if (overflow)
-          {
-          while (XDIGIT(*ptr) != 0xff) ptr++;
-          *errorcodeptr = ERR34;
-          }
-        else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
-          {
-          if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
-          }
-
-        /* If the sequence of hex digits does not end with '}', give an error.
-        We used just to recognize this construct and fall through to the normal
-        \x handling, but nowadays Perl gives an error, which seems much more
-        sensible, so we do too. */
-
-        else *errorcodeptr = ERR67;
-        }   /* End of \x{} processing */
-
-      /* Read a single-byte hex-defined char (up to two hex digits after \x) */
-
-      else
-        {
-        c = 0;
-        if ((cc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */
-        ptr++;
-        c = cc;
-        if ((cc = XDIGIT(ptr[1])) == 0xff) break;  /* Not a hex digit */
-        ptr++;
-        c = (c << 4) | cc;
-        }     /* End of \xdd handling */
-      }       /* End of Perl-style \x handling */
-    break;
-
-    /* The handling of \c is different in ASCII and EBCDIC environments. In an
-    ASCII (or Unicode) environment, an error is given if the character
-    following \c is not a printable ASCII character. Otherwise, the following
-    character is upper-cased if it is a letter, and after that the 0x40 bit is
-    flipped. The result is the value of the escape.
-
-    In an EBCDIC environment the handling of \c is compatible with the
-    specification in the perlebcdic document. The following character must be
-    a letter or one of small number of special characters. These provide a
-    means of defining the character values 0-31.
-
-    For testing the EBCDIC handling of \c in an ASCII environment, recognize
-    the EBCDIC value of 'c' explicitly. */
-
-#if defined EBCDIC && 'a' != 0x81
-    case 0x83:
+    {}
 #else
-    case CHAR_c:
-#endif
-
-    c = *(++ptr);
-    if (c >= CHAR_a && c <= CHAR_z) c = UPPER_CASE(c);
-    if (c == CHAR_NULL && ptr >= ptrend)
-      {
-      *errorcodeptr = ERR2;
-      break;
-      }
-
-    /* Handle \c in an ASCII/Unicode environment. */
-
-#ifndef EBCDIC    /* ASCII/UTF-8 coding */
-    if (c < 32 || c > 126)  /* Excludes all non-printable ASCII */
-      {
-      *errorcodeptr = ERR68;
-      break;
-      }
-    c ^= 0x40;
-
-    /* Handle \c in an EBCDIC environment. The special case \c? is converted to
-    255 (0xff) or 95 (0x5f) if other character suggest we are using th POSIX-BC
-    encoding. (This is the way Perl indicates that it handles \c?.) The other
-    valid sequences correspond to a list of specific characters. */
-
-#else
-    if (c == CHAR_QUESTION_MARK)
-      c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
-    else
-      {
-      for (i = 0; i < 32; i++)
-        {
-        if (c == ebcdic_escape_c[i]) break;
-        }
-      if (i < 32) c = i; else *errorcodeptr = ERR68;
-      }
-#endif  /* EBCDIC */
-
-    break;
-
-    /* Any other alphanumeric following \ is an error. Perl gives an error only
-    if in warning mode, but PCRE doesn't have a warning mode. */
-
-    default:
-    *errorcodeptr = ERR3;
-    break;
+  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 */
 
-/* Perl supports \N{name} for character names, as well as plain \N for "not
-newline". PCRE does not support \N{name}. However, it does support
-quantification such as \N{2,3}. */
-
-if (escape == ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET &&
-     !is_counted_repeat(ptr+2))
-  *errorcodeptr = ERR37;
-
-/* If PCRE2_UCP is set, we change the values for \d etc. */
-
-if ((options & PCRE2_UCP) != 0 && escape >= ESC_D && escape <= ESC_w)
-  escape += (ESC_DU - ESC_D);
-
-/* Set the pointer to the final character before returning. */
-
-*ptrptr = ptr;
-*chptr = c;
-return escape;
+return n8;    /* Number of 8-bit characters */
 }
 
 
 
 #ifdef SUPPORT_UNICODE
 /*************************************************
-*               Handle \P and \p                 *
+* Add a list of characters to a class (internal) *
 *************************************************/
 
-/* This function is called after \P or \p has been encountered, provided that
-PCRE2 is compiled with support for UTF and Unicode properties. On entry, the
-contents of ptrptr are pointing at the P or p. On exit, it is left pointing at
-the final code unit of the escape sequence.
+/* 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:
-  ptrptr         the pattern position pointer
-  negptr         a boolean that is set TRUE for negation else FALSE
-  ptypeptr       an unsigned int that is set to the type value
-  pdataptr       an unsigned int that is set to the detailed property value
-  errorcodeptr   the error code variable
-  cb             the compile data
+  classbits     the bit map for characters < 256
+  uchardptr     points to the pointer for extra data
+  options       the options word
+  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:         TRUE if the type value was found, or FALSE for an invalid type
+Returns:        the number of < 256 characters added
+                the pointer to extra data is updated
 */
 
-static BOOL
-get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, unsigned int *ptypeptr,
-  unsigned int *pdataptr, int *errorcodeptr, compile_block *cb)
+static unsigned int
+add_list_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr,
+  uint32_t options, compile_block *cb, const uint32_t *p, unsigned int except)
 {
-register PCRE2_UCHAR c;
-size_t i, bot, top;
-PCRE2_SPTR ptr = *ptrptr;
-PCRE2_UCHAR name[32];
-
-*negptr = FALSE;
-c = *(++ptr);
-
-/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
-negation. */
-
-if (c == CHAR_LEFT_CURLY_BRACKET)
+unsigned int n8 = 0;
+while (p[0] < NOTACHAR)
   {
-  if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
+  unsigned int n = 0;
+  if (p[0] != except)
     {
-    *negptr = TRUE;
-    ptr++;
+    while(p[n+1] == p[0] + n + 1) n++;
+    n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]);
     }
-  for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++)
-    {
-    c = *(++ptr);
-    if (c == CHAR_NULL) goto ERROR_RETURN;
-    if (c == CHAR_RIGHT_CURLY_BRACKET) break;
-    name[i] = c;
-    }
-  if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
-  name[i] = 0;
+  p += n + 1;
   }
-
-/* Otherwise there is just one following character, which must be an ASCII
-letter. */
-
-else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0)
-  {
-  name[0] = c;
-  name[1] = 0;
-  }
-else goto ERROR_RETURN;
-
-*ptrptr = ptr;
-
-/* Search for a recognized property name using binary chop. */
-
-bot = 0;
-top = PRIV(utt_size);
-
-while (bot < top)
-  {
-  int r;
-  i = (bot + top) >> 1;
-  r = PRIV(strcmp_c8)(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
-  if (r == 0)
-    {
-    *ptypeptr = PRIV(utt)[i].type;
-    *pdataptr = PRIV(utt)[i].value;
-    return TRUE;
-    }
-  if (r > 0) bot = i + 1; else top = i;
-  }
-*errorcodeptr = ERR47;   /* Unrecognized name */
-return FALSE;
-
-ERROR_RETURN:            /* Malformed \P or \p */
-*errorcodeptr = ERR46;
-*ptrptr = ptr;
-return FALSE;
+return n8;
 }
 #endif
 
 
 
 /*************************************************
-*         Read repeat counts                     *
+*   External entry point for add range to class  *
 *************************************************/
 
-/* Read an item of the form {n,m} and return the values. This is called only
-after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
-so the syntax is guaranteed to be correct, but we need to check the values.
+/* This function sets the overall range so that the internal functions can try
+to avoid duplication when handling case-independence.
 
 Arguments:
-  p              pointer to first char after '{'
-  minp           pointer to int for min
-  maxp           pointer to int for max
-                 returned as -1 if no max
-  errorcodeptr   points to error code variable
+  classbits     the bit map for characters < 256
+  uchardptr     points to the pointer for extra data
+  options       the options word
+  cb            compile data
+  start         start of range character
+  end           end of range character
 
-Returns:         pointer to '}' on success;
-                 current ptr on error, with errorcodeptr set non-zero
+Returns:        the number of < 256 characters added
+                the pointer to extra data is updated
 */
 
-static PCRE2_SPTR
-read_repeat_counts(PCRE2_SPTR p, int *minp, int *maxp, int *errorcodeptr)
+static unsigned int
+add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options,
+  compile_block *cb, uint32_t start, uint32_t end)
 {
-int min = 0;
-int max = -1;
+cb->class_range_start = start;
+cb->class_range_end = end;
+return add_to_class_internal(classbits, uchardptr, options, cb, start, end);
+}
 
-while (IS_DIGIT(*p))
+
+/*************************************************
+*   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 word
+  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,
+  compile_block *cb, const uint32_t *p, unsigned int except)
+{
+unsigned int n8 = 0;
+while (p[0] < NOTACHAR)
   {
-  min = min * 10 + (int)(*p++ - CHAR_0);
-  if (min > 65535)
+  unsigned int n = 0;
+  if (p[0] != except)
     {
-    *errorcodeptr = ERR5;
-    return p;
+    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, cb, p[0], p[n]);
     }
+  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 word
+  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, 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, cb, 0, p[0] - 1);
+while (p[0] < NOTACHAR)
+  {
+  while (p[1] == p[0] + 1) p++;
+  n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1,
+    (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1);
+  p++;
+  }
+return n8;
+}
+
+
+
+/*************************************************
+*    Find details of duplicate group names       *
+*************************************************/
+
+/* This is called from compile_branch() when it needs to know the index and
+count of duplicates in the names table when processing named backreferences,
+either directly, or as conditions.
+
+Arguments:
+  name          points to the name
+  length        the length of the name
+  indexptr      where to put the index
+  countptr      where to put the count of duplicates
+  errorcodeptr  where to put an error code
+  cb            the compile block
+
+Returns:        TRUE if OK, FALSE if not, error code set
+*/
+
+static BOOL
+find_dupname_details(PCRE2_SPTR name, uint32_t length, int *indexptr,
+  int *countptr, int *errorcodeptr, compile_block *cb)
+{
+uint32_t i, groupnumber;
+int count;
+PCRE2_UCHAR *slot = cb->name_table;
+
+/* Find the first entry in the table */
+
+for (i = 0; i < cb->names_found; i++)
+  {
+  if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) == 0 &&
+      slot[IMM2_SIZE+length] == 0) break;
+  slot += cb->name_entry_size;
   }
 
-if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
+/* This should not occur, because this function is called only when we know we
+have duplicate names. Give an internal error. */
+
+if (i >= cb->names_found)
   {
-  if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
+  *errorcodeptr = ERR53;
+  cb->erroroffset = name - cb->start_pattern;
+  return FALSE;
+  }
+
+/* Record the index and then see how many duplicates there are, updating the
+backref map and maximum back reference as we do. */
+
+*indexptr = i;
+count = 0;
+
+for (;;)
+  {
+  count++;
+  groupnumber = GET2(slot,0);
+  cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
+  if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
+  if (++i >= cb->names_found) break;
+  slot += cb->name_entry_size;
+  if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) != 0 ||
+    (slot+IMM2_SIZE)[length] != 0) break;
+  }
+
+*countptr = count;
+return TRUE;
+}
+
+
+
+/*************************************************
+*           Compile one branch                   *
+*************************************************/
+
+/* Scan the parsed pattern, compiling it into the a vector of PCRE2_UCHAR. If
+the options are changed during the branch, the pointer is used to change the
+external options bits. This function is used during the pre-compile phase when
+we are trying to find out the amount of memory needed, as well as during the
+real compile phase. The value of lengthptr distinguishes the two phases.
+
+Arguments:
+  optionsptr        pointer to the option bits
+  codeptr           points to the pointer to the current code point
+  pptrptr           points to the current parsed pattern pointer
+  errorcodeptr      points to error code variable
+  firstcuptr        place to put the first required code unit
+  firstcuflagsptr   place to put the first code unit flags, or a negative number
+  reqcuptr          place to put the last required code unit
+  reqcuflagsptr     place to put the last required code unit flags, or a negative number
+  bcptr             points to current branch chain
+  cb                contains pointers to tables etc.
+  lengthptr         NULL during the real compile phase
+                    points to length accumulator during pre-compile phase
+
+Returns:            0 There's been an error, *errorcodeptr is non-zero
+                   +1 Success, this branch must match at least one character
+                   -1 Success, this branch may match an empty string
+*/
+
+static int
+compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr, uint32_t **pptrptr,
+  int *errorcodeptr, uint32_t *firstcuptr, int32_t *firstcuflagsptr,
+  uint32_t *reqcuptr, int32_t *reqcuflagsptr, branch_chain *bcptr,
+  compile_block *cb, PCRE2_SIZE *lengthptr)
+{
+int bravalue = 0;
+int okreturn = -1;
+int group_return = 0;
+uint32_t repeat_min = 0, repeat_max = 0;      /* To please picky compilers */
+uint32_t greedy_default, greedy_non_default;
+uint32_t repeat_type, op_type;
+uint32_t options = *optionsptr;               /* May change dynamically */
+uint32_t firstcu, reqcu;
+uint32_t zeroreqcu, zerofirstcu;
+uint32_t escape;
+uint32_t *pptr = *pptrptr;
+uint32_t meta, meta_arg;
+int32_t firstcuflags, reqcuflags;
+int32_t zeroreqcuflags, zerofirstcuflags;
+int32_t req_caseopt, reqvary, tempreqvary;
+PCRE2_SIZE offset = 0;
+PCRE2_SIZE length_prevgroup = 0;
+PCRE2_UCHAR *code = *codeptr;
+PCRE2_UCHAR *last_code = code;
+PCRE2_UCHAR *orig_code = code;
+PCRE2_UCHAR *tempcode;
+PCRE2_UCHAR *previous = NULL;
+PCRE2_UCHAR op_previous;
+BOOL groupsetfirstcu = FALSE;
+BOOL matched_char = FALSE;
+BOOL previous_matched_char = 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) because they may change
+dynamically as we process the pattern. */
+
+#ifdef SUPPORT_UNICODE
+BOOL utf = (options & PCRE2_UTF) != 0;
+#else  /* No UTF support */
+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);
+greedy_non_default = greedy_default ^ 1;
+
+/* Initialize no first unit, no required unit. REQ_UNSET means "no char
+matching encountered yet". It gets changed to REQ_NONE if we hit something that
+matches a non-fixed first unit; reqcu just remains unset if we never find one.
+
+When we hit a repeat whose minimum is zero, we may have to adjust these values
+to take the zero repeat into account. This is implemented by setting them to
+zerofirstcu and zeroreqcu when such a repeat is encountered. The individual
+item types that can be repeated set these backoff variables appropriately. */
+
+firstcu = reqcu = zerofirstcu = zeroreqcu = 0;
+firstcuflags = reqcuflags = zerofirstcuflags = zeroreqcuflags = REQ_UNSET;
+
+/* The variable req_caseopt contains either the REQ_CASELESS value or zero,
+according to the current setting of the caseless flag. The REQ_CASELESS value
+leaves the lower 28 bit empty. It is added into the firstcu or reqcu variables
+to record the case status of the value. This is used only for ASCII characters.
+*/
+
+req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS:0;
+
+/* Switch on next META item until the end of the branch */
+
+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;
+  int i;
+  uint32_t mclength;
+  uint32_t skipunits;
+  uint32_t subreqcu, subfirstcu;
+  uint32_t groupnumber;
+  uint32_t verbarglen, verbculen;
+  int32_t subreqcuflags, subfirstcuflags;  /* Must be signed */
+  open_capitem *oc;
+  PCRE2_UCHAR mcbuffer[8];
+
+  /* Get next META item in the pattern and its potential argument. */
+
+  meta = META_CODE(*pptr);
+  meta_arg = META_DATA(*pptr);
+
+  /* If we are in the pre-compile phase, accumulate the length used for the
+  previous cycle of this loop, unless the next item is a quantifier. */
+
+  if (lengthptr != NULL)
     {
-    max = 0;
-    while(IS_DIGIT(*p))
+    if (code > cb->start_workspace + cb->workspace_size -
+        WORK_SIZE_SAFETY_MARGIN)                       /* Check for overrun */
       {
-      max = max * 10 + (int)(*p++ - CHAR_0);
-      if (max > 65535)
+      *errorcodeptr = (code >= cb->start_workspace + cb->workspace_size)?
+        ERR52 : ERR86;
+      return 0;
+      }
+
+    /* There is at least one situation where code goes backwards: this is the
+    case of a zero quantifier after a class (e.g. [ab]{0}). When the quantifier
+    is processed, the whole class is eliminated. However, it is created first,
+    so we have to allow memory for it. Therefore, don't ever reduce the length
+    at this point. */
+
+    if (code < last_code) code = last_code;
+
+    /* If the next thing is not a quantifier, we add the length of the previous
+    item into the total, and reset the code pointer to the start of the
+    workspace. Otherwise leave the previous item available to be quantified. */
+
+    if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
+      {
+      if (OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
         {
-        *errorcodeptr = ERR5;
-        return p;
+        *errorcodeptr = ERR20;   /* Integer overflow */
+        return 0;
+        }
+      *lengthptr += (PCRE2_SIZE)(code - orig_code);
+      if (*lengthptr > MAX_PATTERN_SIZE)
+        {
+        *errorcodeptr = ERR20;   /* Pattern is too large */
+        return 0;
+        }
+      code = orig_code;
+      }
+
+    /* Remember where this code item starts so we can catch the "backwards"
+    case above next time round. */
+
+    last_code = code;
+    }
+
+  /* Process the next parsed pattern item. If it is not a quantifier, remember
+  where it starts so that it can be quantified when a quantifier follows.
+  Checking for the legality of quantifiers happens in parse_regex(), except for
+  a quantifier after an assertion that is a condition. */
+
+  if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
+    {
+    previous = code;
+    if (matched_char) okreturn = 1;
+    }
+
+  previous_matched_char = matched_char;
+  matched_char = FALSE;
+  note_group_empty = FALSE;
+  skipunits = 0;         /* Default value for most subgroups */
+
+  switch(meta)
+    {
+    /* ===================================================================*/
+    /* The branch terminates at pattern end or | or ) */
+
+    case META_END:
+    case META_ALT:
+    case META_KET:
+    *firstcuptr = firstcu;
+    *firstcuflagsptr = firstcuflags;
+    *reqcuptr = reqcu;
+    *reqcuflagsptr = reqcuflags;
+    *codeptr = code;
+    *pptrptr = pptr;
+    return okreturn;
+
+
+    /* ===================================================================*/
+    /* Handle single-character metacharacters. In multiline mode, ^ disables
+    the setting of any following char as a first character. */
+
+    case META_CIRCUMFLEX:
+    if ((options & PCRE2_MULTILINE) != 0)
+      {
+      if (firstcuflags == REQ_UNSET)
+        zerofirstcuflags = firstcuflags = REQ_NONE;
+      *code++ = OP_CIRCM;
+      }
+    else *code++ = OP_CIRC;
+    break;
+
+    case META_DOLLAR:
+    *code++ = ((options & PCRE2_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
+    break;
+
+    /* There can never be a first char if '.' is first, whatever happens about
+    repeats. The value of reqcu doesn't change either. */
+
+    case META_DOT:
+    matched_char = TRUE;
+    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+    zerofirstcu = firstcu;
+    zerofirstcuflags = firstcuflags;
+    zeroreqcu = reqcu;
+    zeroreqcuflags = reqcuflags;
+    *code++ = ((options & PCRE2_DOTALL) != 0)? OP_ALLANY: OP_ANY;
+    break;
+
+
+    /* ===================================================================*/
+    /* 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. */
+
+    case META_CLASS_EMPTY:
+    case META_CLASS_EMPTY_NOT:
+    matched_char = TRUE;
+    *code++ = (meta == META_CLASS_EMPTY_NOT)? OP_ALLANY : OP_FAIL;
+    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+    zerofirstcu = firstcu;
+    zerofirstcuflags = firstcuflags;
+    break;
+
+
+    /* ===================================================================*/
+    /* Non-empty character class. If the included characters are all < 256, we
+    build a 32-byte bitmap of the permitted characters, except in the special
+    case where there is only one such character. For negated classes, we build
+    the map as usual, then invert it at the end. However, we use a different
+    opcode so that data characters > 255 can be handled correctly.
+
+    If the class contains characters outside the 0-255 range, a different
+    opcode is compiled. It may optionally have a bit map for characters < 256,
+    but those above are are explicitly listed afterwards. A flag code unit
+    tells whether the bitmap is present, and whether this is a negated class or
+    not. */
+
+    case META_CLASS_NOT:
+    case META_CLASS:
+    matched_char = TRUE;
+    negate_class = meta == META_CLASS_NOT;
+
+    /* 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
+    negative. In the negative case there can be no first char if this item is
+    first, whatever repeat count may follow. In the case of reqcu, save the
+    previous value for reinstating. */
+
+    /* NOTE: at present this optimization is not effective if the only
+    character in a class in 32-bit, non-UCP mode has its top bit set. */
+
+    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 mode, check whether this character has more than
+      one other case. If so, generate a special OP_NOTPROP item instead of
+      OP_NOTI. */
+
+#ifdef SUPPORT_UNICODE
+      if (utf && (options & PCRE2_CASELESS) != 0 &&
+          (d = UCD_CASESET(c)) != 0)
+        {
+        *code++ = OP_NOTPROP;
+        *code++ = PT_CLIST;
+        *code++ = d;
+        break;   /* We are finished with this class */
+        }
+#endif
+      /* Char has only one other 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 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) 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 (ascii, xdigit) 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 [^[:^xdigit:]...
+          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 (i = 0; i < 32; i++) pbits[i] |= cbits[(int)i + taboffset];
+          else
+            for (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 (i = 0; i < 32; i++) classbits[i] |= ~pbits[i];
+        else
+          for (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 (i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit];
+          break;
+
+          case ESC_D:
+          should_flip_negation = TRUE;
+          for (i = 0; i < 32; i++) classbits[i] |= ~cbits[i+cbit_digit];
+          break;
+
+          case ESC_w:
+          for (i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word];
+          break;
+
+          case ESC_W:
+          should_flip_negation = TRUE;
+          for (i = 0; i < 32; i++) classbits[i] |= ~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 (i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space];
+          break;
+
+          case ESC_S:
+          should_flip_negation = TRUE;
+          for (i = 0; i < 32; i++) classbits[i] |= ~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, cb, PRIV(hspace_list), NOTACHAR);
+          break;
+
+          case ESC_H:
+          (void)add_not_list_to_class(classbits, &class_uchardata,
+            options & ~PCRE2_CASELESS, cb, PRIV(hspace_list));
+          break;
+
+          case ESC_v:
+          (void)add_list_to_class(classbits, &class_uchardata,
+            options & ~PCRE2_CASELESS, cb, PRIV(vspace_list), NOTACHAR);
+          break;
+
+          case ESC_V:
+          (void)add_not_list_to_class(classbits, &class_uchardata,
+            options & ~PCRE2_CASELESS, 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 &&
+               (d <= CHAR_z) == (d <= CHAR_z))
+            {
+            uint32_t uc = (d <= CHAR_z)? 0 : 64;
+            uint32_t C = d - uc;
+            uint32_t D = d - uc;
+
+            if (C <= CHAR_i)
+              {
+              class_has_8bitchar +=
+                add_to_class(classbits, &class_uchardata, options, 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, 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, cb, C + uc,
+                  D + uc);
+              }
+            }
+          else
+#endif
+          /* Not an EBCDIC special range */
+
+          class_has_8bitchar +=
+            add_to_class(classbits, &class_uchardata, options, 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, cb, meta, meta);
+        }
+
+      /* Continue to the next item in the class. */
+
+      CONTINUE_CLASS:
+
+#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 work space (which is on the stack). */
+
+      if (class_uchardata > class_uchardata_base)
+        {
+        xclass = TRUE;
+        if (lengthptr != NULL)
+          {
+          *lengthptr += class_uchardata - class_uchardata_base;
+          class_uchardata = class_uchardata_base;
+          }
+        }
+#endif
+
+      continue;  /* Needed to avoid error when not supporting wide chars */
+      }   /* End of main class-processing loop */
+
+    /* 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;
+
+    /* 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 ([:^ascii:] or
+    [^:xdigit:]) 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 &&
+#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 */
+          {
+#if PCRE2_CODE_UNIT_WIDTH == 16
+          *class_uchardata++ = 0x100;
+          *class_uchardata++ = 0xffffu;
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+          *class_uchardata++ = 0x100;
+          *class_uchardata++ = 0xffffffffu;
+#endif
+          }
+        }
+      *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;
+        memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,
+          CU2BYTES(class_uchardata - code));
+        if (negate_class && !xclass_has_prop)
+          for (i = 0; i < 32; i++) classbits[i] = ~classbits[i];
+        memcpy(code, classbits, 32);
+        code = class_uchardata + (32 / sizeof(PCRE2_UCHAR));
+        }
+      else code = class_uchardata;
+
+      /* Now fill in the complete length of the item */
+
+      PUT(previous, 1, (int)(code - previous));
+      break;   /* 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. */
+
+    *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
+    if (lengthptr == NULL)    /* Save time in the pre-compile phase */
+      {
+      if (negate_class)
+        for (i = 0; i < 32; i++) classbits[i] = ~classbits[i];
+      memcpy(code, classbits, 32);
+      }
+    code += 32 / sizeof(PCRE2_UCHAR);
+    break;  /* End of class processing */
+
+
+    /* ===================================================================*/
+    /* Deal with (*VERB)s. */
+
+    /* Check for open captures before ACCEPT and close those that are within
+    the same assertion level, also converting ACCEPT to ASSERT_ACCEPT in an
+    assertion. In the first pass, just accumulate the length required;
+    otherwise hitting (*ACCEPT) inside many nested parentheses can cause
+    workspace overflow. Do not set firstcu after *ACCEPT. */
+
+    case META_ACCEPT:
+    cb->had_accept = TRUE;
+    for (oc = cb->open_caps;
+         oc != NULL && oc->assert_depth >= cb->assert_depth;
+         oc = oc->next)
+      {
+      if (lengthptr != NULL)
+        {
+        *lengthptr += CU2BYTES(1) + IMM2_SIZE;
+        }
+      else
+        {
+        *code++ = OP_CLOSE;
+        PUT2INC(code, 0, oc->number);
         }
       }
-    if (max < min)
+    *code++ = (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
+    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+    break;
+
+    case META_PRUNE:
+    case META_SKIP:
+    cb->had_pruneorskip = TRUE;
+    /* Fall through */
+    case META_COMMIT:
+    case META_FAIL:
+    *code++ = verbops[(meta - META_MARK) >> 16];
+    break;
+
+    case META_THEN:
+    cb->external_flags |= PCRE2_HASTHEN;
+    *code++ = OP_THEN;
+    break;
+
+    /* Handle verbs with arguments. Arguments can be very long, especially in
+    16- and 32-bit modes, and can overflow the workspace in the first pass.
+    However, the argument length is constrained to be small enough to fit in
+    one code unit. This check happens in parse_regex(). In the first pass,
+    instead of putting the argument into memory, we just update the length
+    counter and set up an empty argument. */
+
+    case META_THEN_ARG:
+    cb->external_flags |= PCRE2_HASTHEN;
+    goto VERB_ARG;
+
+    case META_PRUNE_ARG:
+    case META_SKIP_ARG:
+    cb->had_pruneorskip = TRUE;
+    /* Fall through */
+    case META_MARK:
+    VERB_ARG:
+    *code++ = verbops[(meta - META_MARK) >> 16];
+    /* The length is in characters. */
+    verbarglen = *(++pptr);
+    verbculen = 0;
+    tempcode = code++;
+    for (i = 0; i < (int)verbarglen; i++)
       {
-      *errorcodeptr = ERR4;
-      return p;
+      meta = *(++pptr);
+#ifdef SUPPORT_UNICODE
+      if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else
+#endif
+        {
+        mclength = 1;
+        mcbuffer[0] = meta;
+        }
+      if (lengthptr != NULL) *lengthptr += mclength; else
+        {
+        memcpy(code, mcbuffer, CU2BYTES(mclength));
+        code += mclength;
+        verbculen += mclength;
+        }
       }
-    }
+
+    *tempcode = verbculen;   /* Fill in the code unit length */
+    *code++ = 0;             /* Terminating zero */
+    break;
+
+
+    /* ===================================================================*/
+    /* Handle options change. The new setting must be passed back for use in
+    subsequent branches. Reset the greedy defaults and the case value for
+    firstcu and reqcu. */
+
+    case META_OPTIONS:
+    *optionsptr = options = *(++pptr);
+    greedy_default = ((options & PCRE2_UNGREEDY) != 0);
+    greedy_non_default = greedy_default ^ 1;
+    req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0;
+    break;
+
+
+    /* ===================================================================*/
+    /* Handle conditional subpatterns. The case of (?(Rdigits) is ambiguous
+    because it could be a numerical check on recursion, or a name check on a
+    group's being set. The pre-pass sets up META_COND_RNUMBER as a name so that
+    we can handle it either way. We first try for a name; if not found, process
+    the number. */
+
+    case META_COND_RNUMBER:   /* (?(Rdigits) */
+    case META_COND_NAME:      /* (?(name) or (?'name') or ?(<name>) */
+    case META_COND_RNAME:     /* (?(R&name) - test for recursion */
+    bravalue = OP_COND;
+      {
+      int count, index;
+      PCRE2_SPTR name;
+      named_group *ng = cb->named_groups;
+      uint32_t length = *(++pptr);
+
+      GETPLUSOFFSET(offset, pptr);
+      name = cb->start_pattern + offset;
+
+      /* In the first pass, the names generated in the pre-pass are available,
+      but the main name table has not yet been created. Scan the list of names
+      generated in the pre-pass in order to get a number and whether or not
+      this name is duplicated. If it is not duplicated, we can handle it as a
+      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<digits>, which is treated as a recursion test by number.
+      */
+
+      if (i >= cb->names_found)
+        {
+        groupnumber = 0;
+        if (meta == META_COND_RNUMBER)
+          {
+          for (i = 1; i < (int)length; i++)
+            {
+            groupnumber = groupnumber * 10 + name[i] - CHAR_0;
+            if (groupnumber > MAX_GROUP_NUMBER)
+              {
+              *errorcodeptr = ERR61;
+              cb->erroroffset = offset + i;
+              return 0;
+              }
+            }
+          }
+
+        if (meta != META_COND_RNUMBER || groupnumber > cb->bracount)
+          {
+          *errorcodeptr = ERR15;
+          cb->erroroffset = offset;
+          return 0;
+          }
+
+        /* (?Rdigits) treated as a recursion reference by number. A value of
+        zero (which is the result of both (?R) and (?R0)) means "any", and is
+        translated into RREF_ANY (which is 0xffff). */
+
+        if (groupnumber == 0) groupnumber = RREF_ANY;
+        code[1+LINK_SIZE] = OP_RREF;
+        PUT2(code, 2+LINK_SIZE, groupnumber);
+        skipunits = 1+IMM2_SIZE;
+        goto GROUP_PROCESS_NOTE_EMPTY;
+        }
+
+      /* A duplicated name was found. Note that if an R<digits> name is found
+      (META_COND_RNUMBER), it is a reference test, not a recursion test. */
+
+      code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;
+
+      /* 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. */
+
+      count = 0;  /* Values for first pass (avoids compiler warning) */
+      index = 0;
+      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. */
+
+      code[1+LINK_SIZE]++;
+      skipunits = 1+2*IMM2_SIZE;
+      PUT2(code, 2+LINK_SIZE, index);
+      PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count);
+      }
+    goto GROUP_PROCESS_NOTE_EMPTY;
+
+    /* The DEFINE condition is always false. It's internal groups may never
+    be called, so matched_char must remain false, hence the jump to
+    GROUP_PROCESS rather than GROUP_PROCESS_NOTE_EMPTY. */
+
+    case META_COND_DEFINE:
+    bravalue = OP_COND;
+    GETPLUSOFFSET(offset, pptr);
+    code[1+LINK_SIZE] = OP_DEFINE;
+    skipunits = 1;
+    goto GROUP_PROCESS;
+
+    /* Conditional test of a group's being set. */
+
+    case META_COND_NUMBER:
+    bravalue = OP_COND;
+    GETPLUSOFFSET(offset, pptr);
+    groupnumber = *(++pptr);
+    if (groupnumber > cb->bracount)
+      {
+      *errorcodeptr = ERR15;
+      cb->erroroffset = offset;
+      return 0;
+      }
+    if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
+    offset -= 2;   /* Point at initial ( for too many branches error */
+    code[1+LINK_SIZE] = OP_CREF;
+    skipunits = 1+IMM2_SIZE;
+    PUT2(code, 2+LINK_SIZE, groupnumber);
+    goto GROUP_PROCESS_NOTE_EMPTY;
+
+    /* Test for the PCRE2 version. */
+
+    case META_COND_VERSION:
+    bravalue = OP_COND;
+    if (pptr[1] > 0)
+      code[1+LINK_SIZE] = ((PCRE2_MAJOR > pptr[2]) ||
+        (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR >= pptr[3]))?
+          OP_TRUE : OP_FALSE;
+    else
+      code[1+LINK_SIZE] = (PCRE2_MAJOR == pptr[2] && PCRE2_MINOR == pptr[3])?
+        OP_TRUE : OP_FALSE;
+    skipunits = 1;
+    pptr += 3;
+    goto GROUP_PROCESS_NOTE_EMPTY;
+
+    /* The condition is an assertion, possibly preceded by a callout. */
+
+    case META_COND_ASSERT:
+    bravalue = OP_COND;
+    goto GROUP_PROCESS_NOTE_EMPTY;
+
+
+    /* ===================================================================*/
+    /* Handle all kinds of nested bracketed groups. The non-capturing,
+    non-conditional cases are here; others come to GROUP_PROCESS via goto. */
+
+    case META_LOOKAHEAD:
+    bravalue = OP_ASSERT;
+    cb->assert_depth += 1;
+    goto GROUP_PROCESS;
+
+    /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird
+    thing to do, but Perl allows all assertions to be quantified, and when
+    they contain capturing parentheses there may be a potential use for
+    this feature. Not that that applies to a quantified (?!) but we allow
+    it for uniformity. */
+
+    case META_LOOKAHEADNOT:
+    if (pptr[1] == META_KET &&
+         (pptr[2] < META_ASTERISK || pptr[2] > META_MINMAX_QUERY))
+      {
+      *code++ = OP_FAIL;
+      pptr++;
+      }
+    else
+      {
+      bravalue = OP_ASSERT_NOT;
+      cb->assert_depth += 1;
+      goto GROUP_PROCESS;
+      }
+    break;
+
+    case META_LOOKBEHIND:
+    bravalue = OP_ASSERTBACK;
+    cb->assert_depth += 1;
+    goto GROUP_PROCESS;
+
+    case META_LOOKBEHINDNOT:
+    bravalue = OP_ASSERTBACK_NOT;
+    cb->assert_depth += 1;
+    goto GROUP_PROCESS;
+
+    case META_ATOMIC:
+    bravalue = OP_ONCE;
+    goto GROUP_PROCESS_NOTE_EMPTY;
+
+    case META_NOCAPTURE:
+    bravalue = OP_BRA;
+    /* Fall through */
+
+    /* Process nested bracketed regex. The nesting depth is maintained for the
+    benefit of the stackguard function. The test for too deep nesting is now
+    done in parse_regex(). Assertion and DEFINE groups come to GROUP_PROCESS;
+    others come to GROUP_PROCESS_NOTE_EMPTY, to indicate that we need to take
+    note of whether or not they may match an empty string. */
+
+    GROUP_PROCESS_NOTE_EMPTY:
+    note_group_empty = TRUE;
+
+    GROUP_PROCESS:
+    cb->parens_depth += 1;
+    *code = bravalue;
+    pptr++;
+    tempcode = code;
+    tempreqvary = cb->req_varyopt;        /* Save value before group */
+    length_prevgroup = 0;                 /* Initialize for pre-compile phase */
+
+    if ((group_return =
+         compile_regex(
+         options,                         /* The option state */
+         &tempcode,                       /* Where to put code (updated) */
+         &pptr,                           /* Input pointer (updated) */
+         errorcodeptr,                    /* Where to put an error message */
+         skipunits,                       /* Skip over bracket number */
+         &subfirstcu,                     /* For possible first char */
+         &subfirstcuflags,
+         &subreqcu,                       /* For possible last char */
+         &subreqcuflags,
+         bcptr,                           /* Current branch chain */
+         cb,                              /* Compile data block */
+         (lengthptr == NULL)? NULL :      /* Actual compile phase */
+           &length_prevgroup              /* Pre-compile phase */
+         )) == 0)
+      return 0;  /* Error */
+
+    cb->parens_depth -= 1;
+
+    /* If that was a non-conditional significant group (not an assertion, not a
+    DEFINE) that matches at least one character, then the current item matches
+    a character. Conditionals are handled below. */
+
+    if (note_group_empty && bravalue != OP_COND && group_return > 0)
+      matched_char = TRUE;
+
+    /* If we've just compiled an assertion, pop the assert depth. */
+
+    if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
+      cb->assert_depth -= 1;
+
+    /* At the end of compiling, code is still pointing to the start of the
+    group, while tempcode has been updated to point past the end of the group.
+    The parsed pattern pointer (pptr) is on the closing META_KET.
+
+    If this is a conditional bracket, check that there are no more than
+    two branches in the group, or just one if it's a DEFINE group. We do this
+    in the real compile phase, not in the pre-pass, where the whole group may
+    not be available. */
+
+    if (bravalue == OP_COND && lengthptr == NULL)
+      {
+      PCRE2_UCHAR *tc = code;
+      int condcount = 0;
+
+      do {
+         condcount++;
+         tc += GET(tc,1);
+         }
+      while (*tc != OP_KET);
+
+      /* A DEFINE group is never obeyed inline (the "condition" is always
+      false). It must have only one branch. Having checked this, change the
+      opcode to OP_FALSE. */
+
+      if (code[LINK_SIZE+1] == OP_DEFINE)
+        {
+        if (condcount > 1)
+          {
+          cb->erroroffset = offset;
+          *errorcodeptr = ERR54;
+          return 0;
+          }
+        code[LINK_SIZE+1] = OP_FALSE;
+        bravalue = OP_DEFINE;   /* A flag to suppress char handling below */
+        }
+
+      /* A "normal" conditional group. If there is just one branch, we must not
+      make use of its firstcu or reqcu, because this is equivalent to an
+      empty second branch. Also, it may match an empty string. If there are two
+      branches, this item must match a character if the group must. */
+
+      else
+        {
+        if (condcount > 2)
+          {
+          cb->erroroffset = offset;
+          *errorcodeptr = ERR27;
+          return 0;
+          }
+        if (condcount == 1) subfirstcuflags = subreqcuflags = REQ_NONE;
+          else if (group_return > 0) matched_char = TRUE;
+        }
+      }
+
+    /* In the pre-compile phase, update the length by the length of the group,
+    less the brackets at either end. Then reduce the compiled code to just a
+    set of non-capturing brackets so that it doesn't use much memory if it is
+    duplicated by a quantifier.*/
+
+    if (lengthptr != NULL)
+      {
+      if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
+        {
+        *errorcodeptr = ERR20;
+        return 0;
+        }
+      *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
+      code++;   /* This already contains bravalue */
+      PUTINC(code, 0, 1 + LINK_SIZE);
+      *code++ = OP_KET;
+      PUTINC(code, 0, 1 + LINK_SIZE);
+      break;    /* No need to waste time with special character handling */
+      }
+
+    /* Otherwise update the main code pointer to the end of the group. */
+
+    code = tempcode;
+
+    /* For a DEFINE group, required and first character settings are not
+    relevant. */
+
+    if (bravalue == OP_DEFINE) break;
+
+    /* Handle updating of the required and first code units for other types of
+    group. Update for normal brackets of all kinds, and conditions with two
+    branches (see code above). If the bracket is followed by a quantifier with
+    zero repeat, we have to back off. Hence the definition of zeroreqcu and
+    zerofirstcu outside the main loop so that they can be accessed for the back
+    off. */
+
+    zeroreqcu = reqcu;
+    zeroreqcuflags = reqcuflags;
+    zerofirstcu = firstcu;
+    zerofirstcuflags = firstcuflags;
+    groupsetfirstcu = FALSE;
+
+    if (bravalue >= OP_ONCE)  /* Not an assertion */
+      {
+      /* If we have not yet set a firstcu in this branch, take it from the
+      subpattern, remembering that it was set here so that a repeat of more
+      than one can replicate it as reqcu if necessary. If the subpattern has
+      no firstcu, set "none" for the whole branch. In both cases, a zero
+      repeat forces firstcu to "none". */
+
+      if (firstcuflags == REQ_UNSET && subfirstcuflags != REQ_UNSET)
+        {
+        if (subfirstcuflags >= 0)
+          {
+          firstcu = subfirstcu;
+          firstcuflags = subfirstcuflags;
+          groupsetfirstcu = TRUE;
+          }
+        else firstcuflags = REQ_NONE;
+        zerofirstcuflags = REQ_NONE;
+        }
+
+      /* If firstcu was previously set, convert the subpattern's firstcu
+      into reqcu if there wasn't one, using the vary flag that was in
+      existence beforehand. */
+
+      else if (subfirstcuflags >= 0 && subreqcuflags < 0)
+        {
+        subreqcu = subfirstcu;
+        subreqcuflags = subfirstcuflags | tempreqvary;
+        }
+
+      /* If the subpattern set a required code unit (or set a first code unit
+      that isn't really the first code unit - see above), set it. */
+
+      if (subreqcuflags >= 0)
+        {
+        reqcu = subreqcu;
+        reqcuflags = subreqcuflags;
+        }
+      }
+
+    /* For a forward assertion, we take the reqcu, if set, provided that the
+    group has also set a firstcu. This can be helpful if the pattern that
+    follows the assertion doesn't set a different char. For example, it's
+    useful for /(?=abcde).+/. We can't set firstcu for an assertion, however
+    because it leads to incorrect effect for patterns such as /(?=a)a.+/ when
+    the "real" "a" would then become a reqcu instead of a firstcu. This is
+    overcome by a scan at the end if there's no firstcu, looking for an
+    asserted first char. A similar effect for patterns like /(?=.*X)X$/ means
+    we must only take the reqcu when the group also set a firstcu. Otherwise,
+    in that example, 'X' ends up set for both. */
+
+    else if (bravalue == OP_ASSERT && subreqcuflags >= 0 &&
+             subfirstcuflags >= 0)
+      {
+      reqcu = subreqcu;
+      reqcuflags = subreqcuflags;
+      }
+
+    break;  /* End of nested group handling */
+
+
+    /* ===================================================================*/
+    /* Handle named backreferences and recursions. */
+
+    case META_BACKREF_BYNAME:
+    case META_RECURSE_BYNAME:
+      {
+      int count, index;
+      PCRE2_SPTR name;
+      BOOL is_dupname = FALSE;
+      named_group *ng = cb->named_groups;
+      uint32_t length = *(++pptr);
+
+      GETPLUSOFFSET(offset, pptr);
+      name = cb->start_pattern + offset;
+
+      /* In the first pass, the names generated in the pre-pass are available,
+      but the main name table has not yet been created. Scan the list of names
+      generated in the pre-pass in order to get a number and whether or not
+      this name is duplicated. */
+
+      groupnumber = 0;
+      for (i = 0; i < cb->names_found; i++, ng++)
+        {
+        if (length == ng->length &&
+            PRIV(strncmp)(name, ng->name, length) == 0)
+          {
+          is_dupname = ng->isdup;
+          groupnumber = ng->number;
+
+          /* For a recursion, that's all that is needed. We can now go to
+          the code above that handles numerical recursion, applying it to
+          the first group with the given name. */
+
+          if (meta == META_RECURSE_BYNAME)
+            {
+            meta_arg = groupnumber;
+            goto HANDLE_NUMERICAL_RECURSION;
+            }
+
+          /* For a back reference, update the back reference map and the
+          maximum back reference. Then, for each group, we must check to
+          see if it is recursive, that is, it is inside the group that it
+          references. A flag is set so that the group can be made atomic.
+          */
+
+          cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
+          if (groupnumber > cb->top_backref)
+            cb->top_backref = groupnumber;
+
+          for (oc = cb->open_caps; oc != NULL; oc = oc->next)
+            {
+            if (oc->number == groupnumber)
+              {
+              oc->flag = TRUE;
+              break;
+              }
+            }
+          }
+        }
+
+      /* If the name was not found we have a bad reference. */
+
+      if (groupnumber == 0)
+        {
+        *errorcodeptr = ERR15;
+        cb->erroroffset = offset;
+        return 0;
+        }
+
+      /* If a back reference name is not duplicated, we can handle it as
+      a numerical reference. */
+
+      if (!is_dupname)
+        {
+        meta_arg = groupnumber;
+        goto HANDLE_SINGLE_REFERENCE;
+        }
+
+      /* If a back reference name is duplicated, we generate a different
+      opcode to a numerical back reference. In the second pass we must
+      search for the index and count in the final name table. */
+
+      count = 0;  /* Values for first pass (avoids compiler warning) */
+      index = 0;
+      if (lengthptr == NULL && !find_dupname_details(name, length, &index,
+            &count, errorcodeptr, cb)) return 0;
+
+      if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+      *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
+      PUT2INC(code, 0, index);
+      PUT2INC(code, 0, count);
+      }
+    break;
+
+
+    /* ===================================================================*/
+    /* Handle a numerical callout. */
+
+    case META_CALLOUT_NUMBER:
+    code[0] = OP_CALLOUT;
+    PUT(code, 1, pptr[1]);               /* Offset to next pattern item */
+    PUT(code, 1 + LINK_SIZE, pptr[2]);   /* Length of next pattern item */
+    code[1 + 2*LINK_SIZE] = pptr[3];
+    pptr += 3;
+    code += PRIV(OP_lengths)[OP_CALLOUT];
+    break;
+
+
+    /* ===================================================================*/
+    /* Handle a callout with a string argument. In the pre-pass we just compute
+    the length without generating anything. The length in pptr[3] includes both
+    delimiters; in the actual compile only the first one is copied, but a
+    terminating zero is added. Any doubled delimiters within the string make
+    this an overestimate, but it is not worth bothering about. */
+
+    case META_CALLOUT_STRING:
+    if (lengthptr != NULL)
+      {
+      *lengthptr += pptr[3] + (1 + 4*LINK_SIZE);
+      pptr += 3;
+      SKIPOFFSET(pptr);
+      }
+
+    /* In the real compile we can copy the string. The starting delimiter is
+     included so that the client can discover it if they want. We also pass the
+     start offset to help a script language give better error messages. */
+
+    else
+      {
+      PCRE2_SPTR pp;
+      uint32_t delimiter;
+      uint32_t length = pptr[3];
+      PCRE2_UCHAR *callout_string = code + (1 + 4*LINK_SIZE);
+
+      code[0] = OP_CALLOUT_STR;
+      PUT(code, 1, pptr[1]);               /* Offset to next pattern item */
+      PUT(code, 1 + LINK_SIZE, pptr[2]);   /* Length of next pattern item */
+
+      pptr += 3;
+      GETPLUSOFFSET(offset, pptr);         /* Offset to string in pattern */
+      pp = cb->start_pattern + offset;
+      delimiter = *callout_string++ = *pp++;
+      if (delimiter == CHAR_LEFT_CURLY_BRACKET)
+        delimiter = CHAR_RIGHT_CURLY_BRACKET;
+      PUT(code, 1 + 3*LINK_SIZE, (int)(offset + 1));  /* One after delimiter */
+
+      /* The syntax of the pattern was checked in the parsing scan. The length
+      includes both delimiters, but we have passed the opening one just above,
+      so we reduce length before testing it. The test is for > 1 because we do
+      not want to copy the final delimiter. This also ensures that pp[1] is
+      accessible. */
+
+      while (--length > 1)
+        {
+        if (*pp == delimiter && pp[1] == delimiter)
+          {
+          *callout_string++ = delimiter;
+          pp += 2;
+          length--;
+          }
+        else *callout_string++ = *pp++;
+        }
+      *callout_string++ = CHAR_NUL;
+
+      /* Set the length of the entire item, the advance to its end. */
+
+      PUT(code, 1 + 2*LINK_SIZE, (int)(callout_string - code));
+      code = callout_string;
+      }
+    break;
+
+
+    /* ===================================================================*/
+    /* Handle repetition. The different types are all sorted out in the parsing
+    pass. */
+
+    case META_MINMAX_PLUS:
+    case META_MINMAX_QUERY:
+    case META_MINMAX:
+    repeat_min = *(++pptr);
+    repeat_max = *(++pptr);
+    goto REPEAT;
+
+    case META_ASTERISK:
+    case META_ASTERISK_PLUS:
+    case META_ASTERISK_QUERY:
+    repeat_min = 0;
+    repeat_max = REPEAT_UNLIMITED;
+    goto REPEAT;
+
+    case META_PLUS:
+    case META_PLUS_PLUS:
+    case META_PLUS_QUERY:
+    repeat_min = 1;
+    repeat_max = REPEAT_UNLIMITED;
+    goto REPEAT;
+
+    case META_QUERY:
+    case META_QUERY_PLUS:
+    case META_QUERY_QUERY:
+    repeat_min = 0;
+    repeat_max = 1;
+
+    REPEAT:
+    if (previous_matched_char && repeat_min > 0) matched_char = TRUE;
+
+    /* Remember whether this is a variable length repeat, and default to
+    single-char opcodes. */
+
+    reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
+    op_type = 0;
+
+    /* If the repeat is {1} we can ignore it. */
+
+    if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
+
+    /* Adjust first and required code units for a zero repeat. */
+
+    if (repeat_min == 0)
+      {
+      firstcu = zerofirstcu;
+      firstcuflags = zerofirstcuflags;
+      reqcu = zeroreqcu;
+      reqcuflags = zeroreqcuflags;
+      }
+
+    /* Note the greediness and possessiveness. */
+
+    switch (meta)
+      {
+      case META_MINMAX_PLUS:
+      case META_ASTERISK_PLUS:
+      case META_PLUS_PLUS:
+      case META_QUERY_PLUS:
+      repeat_type = 0;                  /* Force greedy */
+      possessive_quantifier = TRUE;
+      break;
+
+      case META_MINMAX_QUERY:
+      case META_ASTERISK_QUERY:
+      case META_PLUS_QUERY:
+      case META_QUERY_QUERY:
+      repeat_type = greedy_non_default;
+      possessive_quantifier = FALSE;
+      break;
+
+      default:
+      repeat_type = greedy_default;
+      possessive_quantifier = FALSE;
+      break;
+      }
+
+    /* 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. */
+
+    tempcode = previous;
+    op_previous = *previous;
+
+    /* Now handle repetition for the different types of item. */
+
+    switch (op_previous)
+      {
+      /* If previous was a character or negated character match, abolish the
+      item and generate a repeat item instead. If a char item has a minimum of
+      more than one, ensure that it is set in reqcu - it might not be if a
+      sequence such as x{3} is the first thing in a branch because the x will
+      have gone into firstcu instead.  */
+
+      case OP_CHAR:
+      case OP_CHARI:
+      case OP_NOT:
+      case OP_NOTI:
+      op_type = chartypeoffset[op_previous - OP_CHAR];
+
+      /* Deal with UTF characters that take up more than one code unit. */
+
+#ifdef MAYBE_UTF_MULTI
+      if (utf && NOT_FIRSTCU(code[-1]))
+        {
+        PCRE2_UCHAR *lastchar = code - 1;
+        BACKCHAR(lastchar);
+        mclength = (uint32_t)(code - lastchar);   /* Length of UTF character */
+        memcpy(mcbuffer, lastchar, CU2BYTES(mclength));  /* Save the char */
+        }
+      else
+#endif  /* MAYBE_UTF_MULTI */
+
+      /* Handle the case of a single code unit - either with no UTF support, or
+      with UTF disabled, or for a single-code-unit UTF character. */
+        {
+        mcbuffer[0] = code[-1];
+        mclength = 1;
+        if (op_previous <= OP_CHARI && repeat_min > 1)
+          {
+          reqcu = mcbuffer[0];
+          reqcuflags = req_caseopt | cb->req_varyopt;
+          }
+        }
+      goto OUTPUT_SINGLE_REPEAT;  /* Code shared with single character types */
+
+      /* If previous was a character class or a back reference, we put the
+      repeat stuff after it, but just skip the item if the repeat was {0,0}. */
+
+#ifdef SUPPORT_WIDE_CHARS
+      case OP_XCLASS:
+#endif
+      case OP_CLASS:
+      case OP_NCLASS:
+      case OP_REF:
+      case OP_REFI:
+      case OP_DNREF:
+      case OP_DNREFI:
+
+      if (repeat_max == 0)
+        {
+        code = previous;
+        goto END_REPEAT;
+        }
+
+      if (repeat_min == 0 && repeat_max == REPEAT_UNLIMITED)
+        *code++ = OP_CRSTAR + repeat_type;
+      else if (repeat_min == 1 && repeat_max == REPEAT_UNLIMITED)
+        *code++ = OP_CRPLUS + repeat_type;
+      else if (repeat_min == 0 && repeat_max == 1)
+        *code++ = OP_CRQUERY + repeat_type;
+      else
+        {
+        *code++ = OP_CRRANGE + repeat_type;
+        PUT2INC(code, 0, repeat_min);
+        if (repeat_max == REPEAT_UNLIMITED) repeat_max = 0;  /* 2-byte encoding for max */
+        PUT2INC(code, 0, repeat_max);
+        }
+      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
+      to do this. However, we still need to replicate recursions as we do for
+      groups so as to have independent backtracking points. We can replicate
+      for the minimum number of repeats directly. For optional repeats we now
+      wrap the recursion in OP_BRA brackets and make use of the bracket
+      repetition. */
+
+      case OP_RECURSE:
+
+      /* Generate unwrapped repeats for a non-zero minimum, except when the
+      minimum is 1 and the maximum unlimited, because that can be handled with
+      OP_BRA terminated by OP_KETRMAX/MIN. When the maximum is equal to the
+      minimum, we just need to generate the appropriate additional copies.
+      Otherwise we need to generate one more, to simulate the situation when
+      the minimum is zero. */
+
+      if (repeat_min > 0 && (repeat_min != 1 || repeat_max != REPEAT_UNLIMITED))
+        {
+        int replicate = repeat_min;
+        if (repeat_min == repeat_max) replicate--;
+
+        /* In the pre-compile phase, we don't actually do the replication. We
+        just adjust the length as if we had. Do some paranoid checks for
+        potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
+        integer type when available, otherwise double. */
+
+        if (lengthptr != NULL)
+          {
+          PCRE2_SIZE delta = replicate*(1 + LINK_SIZE);
+          if ((INT64_OR_DOUBLE)replicate*
+                (INT64_OR_DOUBLE)(1 + LINK_SIZE) >
+                  (INT64_OR_DOUBLE)INT_MAX ||
+              OFLOW_MAX - *lengthptr < delta)
+            {
+            *errorcodeptr = ERR20;
+            return 0;
+            }
+          *lengthptr += delta;
+          }
+
+        else for (i = 0; i < replicate; i++)
+          {
+          memcpy(code, previous, CU2BYTES(1 + LINK_SIZE));
+          previous = code;
+          code += 1 + LINK_SIZE;
+          }
+
+        /* If the number of repeats is fixed, we are done. Otherwise, adjust
+        the counts and fall through. */
+
+        if (repeat_min == repeat_max) break;
+        if (repeat_max != REPEAT_UNLIMITED) repeat_max -= repeat_min;
+        repeat_min = 0;
+        }
+
+      /* Wrap the recursion call in OP_BRA brackets. */
+
+      memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE));
+      op_previous = *previous = OP_BRA;
+      PUT(previous, 1, 2 + 2*LINK_SIZE);
+      previous[2 + 2*LINK_SIZE] = OP_KET;
+      PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
+      code += 2 + 2 * LINK_SIZE;
+      length_prevgroup = 3 + 3*LINK_SIZE;
+      group_return = -1;  /* Set "may match empty string" */
+
+      /* Now treat as a repeated OP_BRA. */
+      /* Fall through */
+
+      /* If previous was a bracket group, we may have to replicate it in
+      certain cases. Note that at this point we can encounter only the "basic"
+      bracket opcodes such as BRA and CBRA, as this is the place where they get
+      converted into the more special varieties such as BRAPOS and SBRA.
+      Originally, PCRE did not allow repetition of assertions, but now it does,
+      for Perl compatibility. */
+
+      case OP_ASSERT:
+      case OP_ASSERT_NOT:
+      case OP_ASSERTBACK:
+      case OP_ASSERTBACK_NOT:
+      case OP_ONCE:
+      case OP_BRA:
+      case OP_CBRA:
+      case OP_COND:
+        {
+        int len = (int)(code - previous);
+        PCRE2_UCHAR *bralink = NULL;
+        PCRE2_UCHAR *brazeroptr = NULL;
+
+        /* Repeating a DEFINE group (or any group where the condition is always
+        FALSE and there is only one branch) is pointless, but Perl allows the
+        syntax, so we just ignore the repeat. */
+
+        if (op_previous == OP_COND && previous[LINK_SIZE+1] == OP_FALSE &&
+            previous[GET(previous, 1)] != OP_ALT)
+          goto END_REPEAT;
+
+        /* There is no sense in actually repeating assertions. The only
+        potential use of repetition is in cases when the assertion is optional.
+        Therefore, if the minimum is greater than zero, just ignore the repeat.
+        If the maximum is not zero or one, set it to 1. */
+
+        if (op_previous < OP_ONCE)    /* Assertion */
+          {
+          if (repeat_min > 0) goto END_REPEAT;
+          if (repeat_max > 1) repeat_max = 1;
+          }
+
+        /* The case of a zero minimum is special because of the need to stick
+        OP_BRAZERO in front of it, and because the group appears once in the
+        data, whereas in other cases it appears the minimum number of times. For
+        this reason, it is simplest to treat this case separately, as otherwise
+        the code gets far too messy. There are several special subcases when the
+        minimum is zero. */
+
+        if (repeat_min == 0)
+          {
+          /* If the maximum is also zero, we used to just omit the group from
+          the output altogether, like this:
+
+          ** if (repeat_max == 0)
+          **   {
+          **   code = previous;
+          **   goto END_REPEAT;
+          **   }
+
+          However, that fails when a group or a subgroup within it is
+          referenced as a subroutine from elsewhere in the pattern, so now we
+          stick in OP_SKIPZERO in front of it so that it is skipped on
+          execution. As we don't have a list of which groups are referenced, we
+          cannot do this selectively.
+
+          If the maximum is 1 or unlimited, we just have to stick in the
+          BRAZERO and do no more at this point. */
+
+          if (repeat_max <= 1 || repeat_max == REPEAT_UNLIMITED)
+            {
+            memmove(previous + 1, previous, CU2BYTES(len));
+            code++;
+            if (repeat_max == 0)
+              {
+              *previous++ = OP_SKIPZERO;
+              goto END_REPEAT;
+              }
+            brazeroptr = previous;    /* Save for possessive optimizing */
+            *previous++ = OP_BRAZERO + repeat_type;
+            }
+
+          /* If the maximum is greater than 1 and limited, we have to replicate
+          in a nested fashion, sticking OP_BRAZERO before each set of brackets.
+          The first one has to be handled carefully because it's the original
+          copy, which has to be moved up. The remainder can be handled by code
+          that is common with the non-zero minimum case below. We have to
+          adjust the value or repeat_max, since one less copy is required. */
+
+          else
+            {
+            int linkoffset;
+            memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len));
+            code += 2 + LINK_SIZE;
+            *previous++ = OP_BRAZERO + repeat_type;
+            *previous++ = OP_BRA;
+
+            /* We chain together the bracket link offset fields that have to be
+            filled in later when the ends of the brackets are reached. */
+
+            linkoffset = (bralink == NULL)? 0 : (int)(previous - bralink);
+            bralink = previous;
+            PUTINC(previous, 0, linkoffset);
+            }
+
+          if (repeat_max != REPEAT_UNLIMITED) repeat_max--;
+          }
+
+        /* If the minimum is greater than zero, replicate the group as many
+        times as necessary, and adjust the maximum to the number of subsequent
+        copies that we need. */
+
+        else
+          {
+          if (repeat_min > 1)
+            {
+            /* In the pre-compile phase, we don't actually do the replication.
+            We just adjust the length as if we had. Do some paranoid checks for
+            potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
+            integer type when available, otherwise double. */
+
+            if (lengthptr != NULL)
+              {
+              PCRE2_SIZE delta = (repeat_min - 1)*length_prevgroup;
+              if ((INT64_OR_DOUBLE)(repeat_min - 1)*
+                    (INT64_OR_DOUBLE)length_prevgroup >
+                      (INT64_OR_DOUBLE)INT_MAX ||
+                  OFLOW_MAX - *lengthptr < delta)
+                {
+                *errorcodeptr = ERR20;
+                return 0;
+                }
+              *lengthptr += delta;
+              }
+
+            /* This is compiling for real. If there is a set first code unit
+            for the group, and we have not yet set a "required code unit", set
+            it. */
+
+            else
+              {
+              if (groupsetfirstcu && reqcuflags < 0)
+                {
+                reqcu = firstcu;
+                reqcuflags = firstcuflags;
+                }
+              for (i = 1; (uint32_t)i < repeat_min; i++)
+                {
+                memcpy(code, previous, CU2BYTES(len));
+                code += len;
+                }
+              }
+            }
+
+          if (repeat_max != REPEAT_UNLIMITED) repeat_max -= repeat_min;
+          }
+
+        /* This code is common to both the zero and non-zero minimum cases. If
+        the maximum is limited, it replicates the group in a nested fashion,
+        remembering the bracket starts on a stack. In the case of a zero
+        minimum, the first one was set up above. In all cases the repeat_max
+        now specifies the number of additional copies needed. Again, we must
+        remember to replicate entries on the forward reference list. */
+
+        if (repeat_max != REPEAT_UNLIMITED)
+          {
+          /* In the pre-compile phase, we don't actually do the replication. We
+          just adjust the length as if we had. For each repetition we must add
+          1 to the length for BRAZERO and for all but the last repetition we
+          must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
+          paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type
+          is a 64-bit integer type when available, otherwise double. */
+
+          if (lengthptr != NULL && repeat_max > 0)
+            {
+            PCRE2_SIZE delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
+                        2 - 2*LINK_SIZE;   /* Last one doesn't nest */
+            if ((INT64_OR_DOUBLE)repeat_max *
+                  (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
+                    > (INT64_OR_DOUBLE)INT_MAX ||
+                OFLOW_MAX - *lengthptr < delta)
+              {
+              *errorcodeptr = ERR20;
+              return 0;
+              }
+            *lengthptr += delta;
+            }
+
+          /* This is compiling for real */
+
+          else for (i = repeat_max - 1; i >= 0; i--)
+            {
+            *code++ = OP_BRAZERO + repeat_type;
+
+            /* All but the final copy start a new nesting, maintaining the
+            chain of brackets outstanding. */
+
+            if (i != 0)
+              {
+              int linkoffset;
+              *code++ = OP_BRA;
+              linkoffset = (bralink == NULL)? 0 : (int)(code - bralink);
+              bralink = code;
+              PUTINC(code, 0, linkoffset);
+              }
+
+            memcpy(code, previous, CU2BYTES(len));
+            code += len;
+            }
+
+          /* Now chain through the pending brackets, and fill in their length
+          fields (which are holding the chain links pro tem). */
+
+          while (bralink != NULL)
+            {
+            int oldlinkoffset;
+            int linkoffset = (int)(code - bralink + 1);
+            PCRE2_UCHAR *bra = code - linkoffset;
+            oldlinkoffset = GET(bra, 1);
+            bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
+            *code++ = OP_KET;
+            PUTINC(code, 0, linkoffset);
+            PUT(bra, 1, linkoffset);
+            }
+          }
+
+        /* If the maximum is unlimited, set a repeater in the final copy. For
+        ONCE brackets, that's all we need to do. However, possessively repeated
+        ONCE brackets can be converted into non-capturing brackets, as the
+        behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
+        deal with possessive ONCEs specially.
+
+        Otherwise, when we are doing the actual compile phase, check to see
+        whether this group is one that could match an empty string. If so,
+        convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
+        that runtime checking can be done. [This check is also applied to ONCE
+        groups at runtime, but in a different way.]
+
+        Then, if the quantifier was possessive and the bracket is not a
+        conditional, we convert the BRA code to the POS form, and the KET code to
+        KETRPOS. (It turns out to be convenient at runtime to detect this kind of
+        subpattern at both the start and at the end.) The use of special opcodes
+        makes it possible to reduce greatly the stack usage in pcre2_match(). If
+        the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
+
+        Then, if the minimum number of matches is 1 or 0, cancel the possessive
+        flag so that the default action below, of wrapping everything inside
+        atomic brackets, does not happen. When the minimum is greater than 1,
+        there will be earlier copies of the group, and so we still have to wrap
+        the whole thing. */
+
+        else
+          {
+          PCRE2_UCHAR *ketcode = code - 1 - LINK_SIZE;
+          PCRE2_UCHAR *bracode = ketcode - GET(ketcode, 1);
+
+          /* Convert possessive ONCE brackets to non-capturing */
+
+          if (*bracode == OP_ONCE && possessive_quantifier) *bracode = OP_BRA;
+
+          /* For non-possessive ONCE brackets, all we need to do is to
+          set the KET. */
+
+          if (*bracode == OP_ONCE) *ketcode = OP_KETRMAX + repeat_type;
+
+          /* Handle non-ONCE brackets and possessive ONCEs (which have been
+          converted to non-capturing above). */
+
+          else
+            {
+            /* In the compile phase, adjust the opcode if the group can match
+            an empty string. For a conditional group with only one branch, the
+            value of group_return will not show "could be empty", so we must
+            check that separately. */
+
+            if (lengthptr == NULL)
+              {
+              if (group_return < 0) *bracode += OP_SBRA - OP_BRA;
+              if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)
+                *bracode = OP_SCOND;
+              }
+
+            /* Handle possessive quantifiers. */
+
+            if (possessive_quantifier)
+              {
+              /* For COND brackets, we wrap the whole thing in a possessively
+              repeated non-capturing bracket, because we have not invented POS
+              versions of the COND opcodes. */
+
+              if (*bracode == OP_COND || *bracode == OP_SCOND)
+                {
+                int nlen = (int)(code - bracode);
+                memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));
+                code += 1 + LINK_SIZE;
+                nlen += 1 + LINK_SIZE;
+                *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
+                *code++ = OP_KETRPOS;
+                PUTINC(code, 0, nlen);
+                PUT(bracode, 1, nlen);
+                }
+
+              /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
+
+              else
+                {
+                *bracode += 1;              /* Switch to xxxPOS opcodes */
+                *ketcode = OP_KETRPOS;
+                }
+
+              /* If the minimum is zero, mark it as possessive, then unset the
+              possessive flag when the minimum is 0 or 1. */
+
+              if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
+              if (repeat_min < 2) possessive_quantifier = FALSE;
+              }
+
+            /* Non-possessive quantifier */
+
+            else *ketcode = OP_KETRMAX + repeat_type;
+            }
+          }
+        }
+      break;
+
+      /* If previous was a character type match (\d or similar), abolish it and
+      create a suitable repeat item. The code is shared with single-character
+      repeats by setting op_type to add a suitable offset into repeat_type.
+      Note the the Unicode property types will be present only when
+      SUPPORT_UNICODE is defined, but we don't wrap the little bits of code
+      here because it just makes it horribly messy. */
+
+      default:
+      if (op_previous >= OP_EODN)   /* Not a character type - internal error */
+        {
+        *errorcodeptr = ERR10;
+        return 0;
+        }
+      else
+        {
+        int prop_type, prop_value;
+        PCRE2_UCHAR *oldcode;
+
+        op_type = OP_TYPESTAR - OP_STAR;      /* Use type opcodes */
+        mclength = 0;                         /* Not a character */
+
+        if (op_previous == OP_PROP || op_previous == OP_NOTPROP)
+          {
+          prop_type = previous[1];
+          prop_value = previous[2];
+          }
+        else
+          {
+          /* Come here from just above with a character in mcbuffer/mclength. */
+          OUTPUT_SINGLE_REPEAT:
+          prop_type = prop_value = -1;
+          }
+
+        /* At this point, if prop_type == prop_value == -1 we either have a
+        character in mcbuffer when mclength is greater than zero, or we have
+        mclength zero, in which case there is a non-property character type in
+        op_previous. If prop_type/value are not negative, we have a property
+        character type in op_previous. */
+
+        oldcode = code;                   /* Save where we were */
+        code = previous;                  /* Usually overwrite previous item */
+
+        /* If the maximum is zero then the minimum must also be zero; Perl allows
+        this case, so we do too - by simply omitting the item altogether. */
+
+        if (repeat_max == 0) goto END_REPEAT;
+
+        /* Combine the op_type with the repeat_type */
+
+        repeat_type += op_type;
+
+        /* A minimum of zero is handled either as the special case * or ?, or as
+        an UPTO, with the maximum given. */
+
+        if (repeat_min == 0)
+          {
+          if (repeat_max == REPEAT_UNLIMITED) *code++ = OP_STAR + repeat_type;
+            else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
+          else
+            {
+            *code++ = OP_UPTO + repeat_type;
+            PUT2INC(code, 0, repeat_max);
+            }
+          }
+
+        /* A repeat minimum of 1 is optimized into some special cases. If the
+        maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
+        left in place and, if the maximum is greater than 1, we use OP_UPTO with
+        one less than the maximum. */
+
+        else if (repeat_min == 1)
+          {
+          if (repeat_max == REPEAT_UNLIMITED)
+            *code++ = OP_PLUS + repeat_type;
+          else
+            {
+            code = oldcode;  /* Leave previous item in place */
+            if (repeat_max == 1) goto END_REPEAT;
+            *code++ = OP_UPTO + repeat_type;
+            PUT2INC(code, 0, repeat_max - 1);
+            }
+          }
+
+        /* The case {n,n} is just an EXACT, while the general case {n,m} is
+        handled as an EXACT followed by an UPTO or STAR or QUERY. */
+
+        else
+          {
+          *code++ = OP_EXACT + op_type;  /* NB EXACT doesn't have repeat_type */
+          PUT2INC(code, 0, repeat_min);
+
+          /* Unless repeat_max equals repeat_min, fill in the data for EXACT,
+          and then generate the second opcode. For a repeated Unicode property
+          match, there are two extra values that define the required property,
+          and mclength is set zero to indicate this. */
+
+          if (repeat_max != repeat_min)
+            {
+            if (mclength > 0)
+              {
+              memcpy(code, mcbuffer, CU2BYTES(mclength));
+              code += mclength;
+              }
+            else
+              {
+              *code++ = op_previous;
+              if (prop_type >= 0)
+                {
+                *code++ = prop_type;
+                *code++ = prop_value;
+                }
+              }
+
+            /* Now set up the following opcode */
+
+            if (repeat_max == REPEAT_UNLIMITED)
+              *code++ = OP_STAR + repeat_type;
+            else
+              {
+              repeat_max -= repeat_min;
+              if (repeat_max == 1)
+                {
+                *code++ = OP_QUERY + repeat_type;
+                }
+              else
+                {
+                *code++ = OP_UPTO + repeat_type;
+                PUT2INC(code, 0, repeat_max);
+                }
+              }
+            }
+          }
+
+        /* Fill in the character or character type for the final opcode. */
+
+        if (mclength > 0)
+          {
+          memcpy(code, mcbuffer, CU2BYTES(mclength));
+          code += mclength;
+          }
+        else
+          {
+          *code++ = op_previous;
+          if (prop_type >= 0)
+            {
+            *code++ = prop_type;
+            *code++ = prop_value;
+            }
+          }
+        }
+      break;
+      }  /* End of switch on different op_previous values */
+
+
+    /* If the character following a repeat is '+', possessive_quantifier is
+    TRUE. For some opcodes, there are special alternative opcodes for this
+    case. For anything else, we wrap the entire repeated item inside OP_ONCE
+    brackets. Logically, the '+' notation is just syntactic sugar, taken from
+    Sun's Java package, but the special opcodes can optimize it.
+
+    Some (but not all) possessively repeated subpatterns have already been
+    completely handled in the code just above. For them, possessive_quantifier
+    is always FALSE at this stage. Note that the repeated item starts at
+    tempcode, not at previous, which might be the first part of a string whose
+    (former) last char we repeated. */
+
+    if (possessive_quantifier)
+      {
+      int len;
+
+      /* Possessifying an EXACT quantifier has no effect, so we can ignore it.
+      However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6},
+      {5,}, or {5,10}). We skip over an EXACT item; if the length of what
+      remains is greater than zero, there's a further opcode that can be
+      handled. If not, do nothing, leaving the EXACT alone. */
+
+      switch(*tempcode)
+        {
+        case OP_TYPEEXACT:
+        tempcode += PRIV(OP_lengths)[*tempcode] +
+          ((tempcode[1 + IMM2_SIZE] == OP_PROP
+          || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+        break;
+
+        /* CHAR opcodes are used for exacts whose count is 1. */
+
+        case OP_CHAR:
+        case OP_CHARI:
+        case OP_NOT:
+        case OP_NOTI:
+        case OP_EXACT:
+        case OP_EXACTI:
+        case OP_NOTEXACT:
+        case OP_NOTEXACTI:
+        tempcode += PRIV(OP_lengths)[*tempcode];
+#ifdef SUPPORT_UNICODE
+        if (utf && HAS_EXTRALEN(tempcode[-1]))
+          tempcode += GET_EXTRALEN(tempcode[-1]);
+#endif
+        break;
+
+        /* For the class opcodes, the repeat operator appears at the end;
+        adjust tempcode to point to it. */
+
+        case OP_CLASS:
+        case OP_NCLASS:
+        tempcode += 1 + 32/sizeof(PCRE2_UCHAR);
+        break;
+
+#ifdef SUPPORT_WIDE_CHARS
+        case OP_XCLASS:
+        tempcode += GET(tempcode, 1);
+        break;
+#endif
+        }
+
+      /* If tempcode is equal to code (which points to the end of the repeated
+      item), it means we have skipped an EXACT item but there is no following
+      QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In
+      all other cases, tempcode will be pointing to the repeat opcode, and will
+      be less than code, so the value of len will be greater than 0. */
+
+      len = (int)(code - tempcode);
+      if (len > 0)
+        {
+        unsigned int repcode = *tempcode;
+
+        /* There is a table for possessifying opcodes, all of which are less
+        than OP_CALLOUT. A zero entry means there is no possessified version.
+        */
+
+        if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0)
+          *tempcode = opcode_possessify[repcode];
+
+        /* For opcode without a special possessified version, wrap the item in
+        ONCE brackets. */
+
+        else
+          {
+          memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len));
+          code += 1 + LINK_SIZE;
+          len += 1 + LINK_SIZE;
+          tempcode[0] = OP_ONCE;
+          *code++ = OP_KET;
+          PUTINC(code, 0, len);
+          PUT(tempcode, 1, len);
+          }
+        }
+      }
+
+    /* We set the "follows varying string" flag for subsequently encountered
+    reqcus if it isn't already set and we have just passed a varying length
+    item. */
+
+    END_REPEAT:
+    cb->req_varyopt |= reqvary;
+    break;
+
+
+    /* ===================================================================*/
+    /* Handle a 32-bit data character with a value greater than META_END. */
+
+    case META_BIGVALUE:
+    pptr++;
+    goto NORMAL_CHAR;
+
+
+    /* ===============================================================*/
+    /* Handle a back reference by number, which is the meta argument. The
+    pattern offsets for back references to group numbers less than 10 are held
+    in a special vector, to avoid using more than two parsed pattern elements
+    in 64-bit environments. We only need the offset to the first occurrence,
+    because if that doesn't fail, subsequent ones will also be OK. */
+
+    case META_BACKREF:
+    if (meta_arg < 10) offset = cb->small_ref_offset[meta_arg];
+      else GETPLUSOFFSET(offset, pptr);
+
+    if (meta_arg > cb->bracount)
+      {
+      cb->erroroffset = offset;
+      *errorcodeptr = ERR15;  /* Non-existent subpattern */
+      return 0;
+      }
+
+    /* Come here from named backref handling when the reference is to a
+    single group (that is, not to a duplicated name). The back reference
+    data will have already been updated. We must disable firstcu if not
+    set, to cope with cases like (?=(\w+))\1: which would otherwise set ':'
+    later. */
+
+    HANDLE_SINGLE_REFERENCE:
+    if (firstcuflags == REQ_UNSET) zerofirstcuflags = firstcuflags = REQ_NONE;
+    *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;
+    PUT2INC(code, 0, meta_arg);
+
+    /* Update the map of back references, and keep the highest one. We
+    could do this in parse_regex() for numerical back references, but not
+    for named back references, because we don't know the numbers to which
+    named back references refer. So we do it all in this function. */
+
+    cb->backref_map |= (meta_arg < 32)? (1u << meta_arg) : 1;
+    if (meta_arg > cb->top_backref) cb->top_backref = meta_arg;
+
+    /* Check to see if this back reference is recursive, that it, it
+    is inside the group that it references. A flag is set so that the
+    group can be made atomic. */
+
+    for (oc = cb->open_caps; oc != NULL; oc = oc->next)
+      {
+      if (oc->number == meta_arg)
+        {
+        oc->flag = TRUE;
+        break;
+        }
+      }
+    break;
+
+
+    /* ===============================================================*/
+    /* Handle recursion by inserting the number of the called group (which is
+    the meta argument) after OP_RECURSE. At the end of compiling the pattern is
+    scanned and these numbers are replaced by offsets within the pattern. It is
+    done like this to avoid problems with forward references and adjusting
+    offsets when groups are duplicated and moved (as discovered in previous
+    implementations). Note that a recursion does not have a set first character
+    (relevant if it is repeated, because it will then be wrapped with ONCE
+    brackets). */
+
+    case META_RECURSE:
+    GETPLUSOFFSET(offset, pptr);
+    if (meta_arg > cb->bracount)
+      {
+      cb->erroroffset = offset;
+      *errorcodeptr = ERR15;  /* Non-existent subpattern */
+      return 0;
+      }
+    HANDLE_NUMERICAL_RECURSION:
+    *code = OP_RECURSE;
+    PUT(code, 1, meta_arg);
+    code += 1 + LINK_SIZE;
+    groupsetfirstcu = FALSE;
+    cb->had_recurse = TRUE;
+    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+    break;
+
+
+    /* ===============================================================*/
+    /* Handle capturing parentheses; the number is the meta argument. */
+
+    case META_CAPTURE:
+    bravalue = OP_CBRA;
+    skipunits = IMM2_SIZE;
+    PUT2(code, 1+LINK_SIZE, meta_arg);
+    cb->lastcapture = meta_arg;
+    goto GROUP_PROCESS_NOTE_EMPTY;
+
+
+    /* ===============================================================*/
+    /* Handle escape sequence items. For ones like \d, the ESC_values are
+    arranged to be the same as the corresponding OP_values in the default case
+    when PCRE2_UCP is not set (which is the only case in which they will appear
+    here).
+
+    Note: \Q and \E are never seen here, as they were dealt with in
+    parse_pattern(). Neither are numerical back references or recursions, which
+    were turned into META_BACKREF or META_RECURSE items, respectively. \k and
+    \g, when followed by names, are turned into META_BACKREF_BYNAME or
+    META_RECURSE_BYNAME. */
+
+    case META_ESCAPE:
+
+    /* We can test for escape sequences that consume a character because their
+    values lie between ESC_b and ESC_Z; this may have to change if any new ones
+    are ever created. For these sequences, we disable the setting of a first
+    character if it hasn't already been set. */
+
+    if (meta_arg > ESC_b && meta_arg < ESC_Z)
+      {
+      matched_char = TRUE;
+      if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
+      }
+
+    /* Set values to reset to if this is followed by a zero repeat. */
+
+    zerofirstcu = firstcu;
+    zerofirstcuflags = firstcuflags;
+    zeroreqcu = reqcu;
+    zeroreqcuflags = reqcuflags;
+
+    /* 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
+    if (meta_arg == ESC_P || meta_arg == ESC_p)
+      {
+      uint32_t ptype = *(++pptr) >> 16;
+      uint32_t pdata = *pptr & 0xffff;
+      *code++ = (meta_arg == ESC_p)? OP_PROP : OP_NOTPROP;
+      *code++ = ptype;
+      *code++ = pdata;
+      break;  /* End META_ESCAPE */
+      }
+#endif
+
+    /* For the rest (including \X when Unicode is supported - if not it's
+    faulted at parse time), the OP value is the escape value when PCRE2_UCP is
+    not set; if it is set, these escapes do not show up here because they are
+    converted into Unicode property tests in parse_regex(). Note that \b and \B
+    do a one-character lookbehind, and \A also behaves as if it does. */
+
+    if (meta_arg == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */
+    if ((meta_arg == ESC_b || meta_arg == ESC_B || meta_arg == ESC_A) &&
+         cb->max_lookbehind == 0)
+      cb->max_lookbehind = 1;
+
+    /* In non-UTF mode, and for both 32-bit modes, we turn \C into OP_ALLANY
+    instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 32
+    *code++ = (meta_arg == ESC_C)? OP_ALLANY : meta_arg;
+#else
+    *code++ = (!utf && meta_arg == ESC_C)? OP_ALLANY : meta_arg;
+#endif
+    break;  /* End META_ESCAPE */
+
+
+    /* ===================================================================*/
+    /* Handle an unrecognized meta value. A parsed pattern value less than
+    META_END is a literal. Otherwise we have a problem. */
+
+    default:
+    if (meta >= META_END)
+      {
+#ifdef DEBUG_SHOW_PARSED
+      fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x\n", *pptr);
+#endif
+      *errorcodeptr = ERR89;  /* Internal error - unrecognized. */
+      return 0;
+      }
+
+    /* Handle a literal character. We come here by goto in the case of a
+    32-bit, non-UTF character whose value is greater than META_END. */
+
+    NORMAL_CHAR:
+    meta = *pptr;     /* Get the full 32 bits */
+    NORMAL_CHAR_SET:  /* Character is already in meta */
+    matched_char = TRUE;
+
+    /* For caseless UTF mode, check whether this character has more than one
+    other case. If so, generate a special OP_PROP item instead of OP_CHARI. */
+
+#ifdef SUPPORT_UNICODE
+    if (utf && (options & PCRE2_CASELESS) != 0)
+      {
+      uint32_t caseset = UCD_CASESET(meta);
+      if (caseset != 0)
+        {
+        *code++ = OP_PROP;
+        *code++ = PT_CLIST;
+        *code++ = caseset;
+        if (firstcuflags == REQ_UNSET)
+          firstcuflags = zerofirstcuflags = REQ_NONE;
+        break;  /* End handling this meta item */
+        }
+      }
+#endif
+
+    /* Caseful matches, or not one of the multicase characters. Get the
+    character's code units into mcbuffer, with the length in mclength. When not
+    in UTF mode, the length is always 1. */
+
+#ifdef SUPPORT_UNICODE
+    if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else
+#endif
+      {
+      mclength = 1;
+      mcbuffer[0] = meta;
+      }
+
+    /* Generate the appropriate code */
+
+    *code++ = ((options & PCRE2_CASELESS) != 0)? OP_CHARI : OP_CHAR;
+    memcpy(code, mcbuffer, CU2BYTES(mclength));
+    code += mclength;
+
+    /* Remember if \r or \n were seen */
+
+    if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
+      cb->external_flags |= PCRE2_HASCRORLF;
+
+    /* Set the first and required code units appropriately. If no previous
+    first code unit, set it from this character, but revert to none on a zero
+    repeat. Otherwise, leave the firstcu value alone, and don't change it on
+    a zero repeat. */
+
+    if (firstcuflags == REQ_UNSET)
+      {
+      zerofirstcuflags = REQ_NONE;
+      zeroreqcu = reqcu;
+      zeroreqcuflags = reqcuflags;
+
+      /* If the character is more than one code unit long, we can set firstcu
+      only if it is not to be matched caselessly. */
+
+      if (mclength == 1 || req_caseopt == 0)
+        {
+        firstcu = mcbuffer[0];
+        firstcuflags = req_caseopt;
+        if (mclength != 1)
+          {
+          reqcu = code[-1];
+          reqcuflags = cb->req_varyopt;
+          }
+        }
+      else firstcuflags = reqcuflags = REQ_NONE;
+      }
+
+    /* firstcu was previously set; we can set reqcu only if the length is
+    1 or the matching is caseful. */
+
+    else
+      {
+      zerofirstcu = firstcu;
+      zerofirstcuflags = firstcuflags;
+      zeroreqcu = reqcu;
+      zeroreqcuflags = reqcuflags;
+      if (mclength == 1 || req_caseopt == 0)
+        {
+        reqcu = code[-1];
+        reqcuflags = req_caseopt | cb->req_varyopt;
+        }
+      }
+    break;    /* End default meta handling */
+    }         /* End of big switch */
+  }           /* End of big loop */
+
+/* Control never reaches here. */
+}
+
+
+
+/*************************************************
+*   Compile regex: a sequence of alternatives    *
+*************************************************/
+
+/* On entry, pptr is pointing past the bracket meta, but on return it points to
+the closing bracket or META_END. The code variable is pointing at the code unit
+into which the BRA operator has been stored. This function is used during the
+pre-compile phase when we are trying to find out the amount of memory needed,
+as well as during the real compile phase. The value of lengthptr distinguishes
+the two phases.
+
+Arguments:
+  options           option bits, including any changes for this subpattern
+  codeptr           -> the address of the current code pointer
+  pptrptr           -> the address of the current parsed pattern pointer
+  errorcodeptr      -> pointer to error code variable
+  skipunits         skip this many code units at start (for brackets and OP_COND)
+  firstcuptr        place to put the first required code unit
+  firstcuflagsptr   place to put the first code unit flags, or a negative number
+  reqcuptr          place to put the last required code unit
+  reqcuflagsptr     place to put the last required code unit flags, or a negative number
+  bcptr             pointer to the chain of currently open branches
+  cb                points to the data block with tables pointers etc.
+  lengthptr         NULL during the real compile phase
+                    points to length accumulator during pre-compile phase
+
+Returns:            0 There has been an error
+                   +1 Success, this group must match at least one character
+                   -1 Success, this group may match an empty string
+*/
+
+static int
+compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, uint32_t **pptrptr,
+  int *errorcodeptr, uint32_t skipunits, uint32_t *firstcuptr,
+  int32_t *firstcuflagsptr, uint32_t *reqcuptr,int32_t *reqcuflagsptr,
+  branch_chain *bcptr, compile_block *cb, PCRE2_SIZE *lengthptr)
+{
+PCRE2_UCHAR *code = *codeptr;
+PCRE2_UCHAR *last_branch = code;
+PCRE2_UCHAR *start_bracket = code;
+BOOL lookbehind;
+open_capitem capitem;
+int capnumber = 0;
+int okreturn = 1;
+uint32_t *pptr = *pptrptr;
+uint32_t firstcu, reqcu;
+uint32_t lookbehindlength;
+int32_t firstcuflags, reqcuflags;
+uint32_t branchfirstcu, branchreqcu;
+int32_t branchfirstcuflags, branchreqcuflags;
+PCRE2_SIZE length;
+branch_chain bc;
+
+/* If set, call the external function that checks for stack availability. */
+
+if (cb->cx->stack_guard != NULL &&
+    cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data))
+  {
+  *errorcodeptr= ERR33;
+  return 0;
   }
 
-*minp = min;
-*maxp = max;
-return p;
+/* Miscellaneous initialization */
+
+bc.outer = bcptr;
+bc.current_branch = code;
+
+firstcu = reqcu = 0;
+firstcuflags = reqcuflags = REQ_UNSET;
+
+/* Accumulate the length for use in the pre-compile phase. Start with the
+length of the BRA and KET and any extra code units that are required at the
+beginning. We accumulate in a local variable to save frequent testing of
+lengthptr for NULL. We cannot do this by looking at the value of 'code' at the
+start and end of each alternative, because compiled items are discarded during
+the pre-compile phase so that the work space is not exceeded. */
+
+length = 2 + 2*LINK_SIZE + skipunits;
+
+/* Remember if this is a lookbehind assertion, and if it is, save its length
+and skip over the pattern offset. */
+
+lookbehind = *code == OP_ASSERTBACK || *code == OP_ASSERTBACK_NOT;
+if (lookbehind)
+  {
+  lookbehindlength = META_DATA(pptr[-1]);
+  pptr += SIZEOFFSET;
+  }
+else lookbehindlength = 0;
+
+/* If this is a capturing subpattern, add to the chain of open capturing items
+so that we can detect them if (*ACCEPT) is encountered. Note that only OP_CBRA
+need be tested here; changing this opcode to one of its variants, e.g.
+OP_SCBRAPOS, happens later, after the group has been compiled. */
+
+if (*code == OP_CBRA)
+  {
+  capnumber = GET2(code, 1 + LINK_SIZE);
+  capitem.number = capnumber;
+  capitem.next = cb->open_caps;
+  capitem.flag = FALSE;
+  capitem.assert_depth = cb->assert_depth;
+  cb->open_caps = &capitem;
+  }
+
+/* Offset is set zero to mark that this bracket is still open */
+
+PUT(code, 1, 0);
+code += 1 + LINK_SIZE + skipunits;
+
+/* Loop for each alternative branch */
+
+for (;;)
+  {
+  int branch_return;
+
+  /* Insert OP_REVERSE if this is as lookbehind assertion. */
+
+  if (lookbehind && lookbehindlength > 0)
+    {
+    *code++ = OP_REVERSE;
+    PUTINC(code, 0, lookbehindlength);
+    length += 1 + LINK_SIZE;
+    }
+
+  /* Now compile the branch; in the pre-compile phase its length gets added
+  into the length. */
+
+  if ((branch_return =
+        compile_branch(&options, &code, &pptr, errorcodeptr, &branchfirstcu,
+          &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc,
+          cb, (lengthptr == NULL)? NULL : &length)) == 0)
+    return 0;
+
+  /* If a branch can match an empty string, so can the whole group. */
+
+  if (branch_return < 0) okreturn = -1;
+
+  /* In the real compile phase, there is some post-processing to be done. */
+
+  if (lengthptr == NULL)
+    {
+    /* If this is the first branch, the firstcu and reqcu values for the
+    branch become the values for the regex. */
+
+    if (*last_branch != OP_ALT)
+      {
+      firstcu = branchfirstcu;
+      firstcuflags = branchfirstcuflags;
+      reqcu = branchreqcu;
+      reqcuflags = branchreqcuflags;
+      }
+
+    /* If this is not the first branch, the first char and reqcu have to
+    match the values from all the previous branches, except that if the
+    previous value for reqcu didn't have REQ_VARY set, it can still match,
+    and we set REQ_VARY for the regex. */
+
+    else
+      {
+      /* If we previously had a firstcu, but it doesn't match the new branch,
+      we have to abandon the firstcu for the regex, but if there was
+      previously no reqcu, it takes on the value of the old firstcu. */
+
+      if (firstcuflags != branchfirstcuflags || firstcu != branchfirstcu)
+        {
+        if (firstcuflags >= 0)
+          {
+          if (reqcuflags < 0)
+            {
+            reqcu = firstcu;
+            reqcuflags = firstcuflags;
+            }
+          }
+        firstcuflags = REQ_NONE;
+        }
+
+      /* If we (now or from before) have no firstcu, a firstcu from the
+      branch becomes a reqcu if there isn't a branch reqcu. */
+
+      if (firstcuflags < 0 && branchfirstcuflags >= 0 &&
+          branchreqcuflags < 0)
+        {
+        branchreqcu = branchfirstcu;
+        branchreqcuflags = branchfirstcuflags;
+        }
+
+      /* Now ensure that the reqcus match */
+
+      if (((reqcuflags & ~REQ_VARY) != (branchreqcuflags & ~REQ_VARY)) ||
+          reqcu != branchreqcu)
+        reqcuflags = REQ_NONE;
+      else
+        {
+        reqcu = branchreqcu;
+        reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY */
+        }
+      }
+    }
+
+  /* Handle reaching the end of the expression, either ')' or end of pattern.
+  In the real compile phase, go back through the alternative branches and
+  reverse the chain of offsets, with the field in the BRA item now becoming an
+  offset to the first alternative. If there are no alternatives, it points to
+  the end of the group. The length in the terminating ket is always the length
+  of the whole bracketed item. Return leaving the pointer at the terminating
+  char. */
+
+  if (META_CODE(*pptr) != META_ALT)
+    {
+    if (lengthptr == NULL)
+      {
+      PCRE2_SIZE branch_length = code - last_branch;
+      do
+        {
+        PCRE2_SIZE prev_length = GET(last_branch, 1);
+        PUT(last_branch, 1, branch_length);
+        branch_length = prev_length;
+        last_branch -= branch_length;
+        }
+      while (branch_length > 0);
+      }
+
+    /* Fill in the ket */
+
+    *code = OP_KET;
+    PUT(code, 1, (int)(code - start_bracket));
+    code += 1 + LINK_SIZE;
+
+    /* If it was a capturing subpattern, check to see if it contained any
+    recursive back references. If so, we must wrap it in atomic brackets. In
+    any event, remove the block from the chain. */
+
+    if (capnumber > 0)
+      {
+      if (cb->open_caps->flag)
+        {
+        memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+          CU2BYTES(code - start_bracket));
+        *start_bracket = OP_ONCE;
+        code += 1 + LINK_SIZE;
+        PUT(start_bracket, 1, (int)(code - start_bracket));
+        *code = OP_KET;
+        PUT(code, 1, (int)(code - start_bracket));
+        code += 1 + LINK_SIZE;
+        length += 2 + 2*LINK_SIZE;
+        }
+      cb->open_caps = cb->open_caps->next;
+      }
+
+    /* Set values to pass back */
+
+    *codeptr = code;
+    *pptrptr = pptr;
+    *firstcuptr = firstcu;
+    *firstcuflagsptr = firstcuflags;
+    *reqcuptr = reqcu;
+    *reqcuflagsptr = reqcuflags;
+    if (lengthptr != NULL)
+      {
+      if (OFLOW_MAX - *lengthptr < length)
+        {
+        *errorcodeptr = ERR20;
+        return 0;
+        }
+      *lengthptr += length;
+      }
+    return okreturn;
+    }
+
+  /* Another branch follows. In the pre-compile phase, we can move the code
+  pointer back to where it was for the start of the first branch. (That is,
+  pretend that each branch is the only one.)
+
+  In the real compile phase, insert an ALT node. Its length field points back
+  to the previous branch while the bracket remains open. At the end the chain
+  is reversed. It's done like this so that the start of the bracket has a
+  zero offset until it is closed, making it possible to detect recursion. */
+
+  if (lengthptr != NULL)
+    {
+    code = *codeptr + 1 + LINK_SIZE + skipunits;
+    length += 1 + LINK_SIZE;
+    }
+  else
+    {
+    *code = OP_ALT;
+    PUT(code, 1, (int)(code - last_branch));
+    bc.current_branch = last_branch = code;
+    code += 1 + LINK_SIZE;
+    }
+
+  /* Set the lookbehind length (if not in a lookbehind the value will be zero)
+  and then advance past the vertical bar. */
+
+  lookbehindlength = META_DATA(*pptr);
+  pptr++;
+  }
+/* Control never reaches here */
+}
+
+
+
+/*************************************************
+*          Check for anchored pattern            *
+*************************************************/
+
+/* Try to find out if this is an anchored regular expression. Consider each
+alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
+all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
+it's anchored. However, if this is a multiline pattern, then only OP_SOD will
+be found, because ^ generates OP_CIRCM in that mode.
+
+We can also consider a regex to be anchored if OP_SOM starts all its branches.
+This is the code for \G, which means "match at start of match position, taking
+into account the match offset".
+
+A branch is also implicitly anchored if it starts with .* and DOTALL is set,
+because that will try the rest of the pattern at all possible matching points,
+so there is no point trying again.... er ....
+
+.... except when the .* appears inside capturing parentheses, and there is a
+subsequent back reference to those parentheses. We haven't enough information
+to catch that case precisely.
+
+At first, the best we could do was to detect when .* was in capturing brackets
+and the highest back reference was greater than or equal to that level.
+However, by keeping a bitmap of the first 31 back references, we can catch some
+of the more common cases more precisely.
+
+... A second exception is when the .* appears inside an atomic group, because
+this prevents the number of characters it matches from being adjusted.
+
+Arguments:
+  code           points to start of the compiled pattern
+  bracket_map    a bitmap of which brackets we are inside while testing; this
+                   handles up to substring 31; after that we just have to take
+                   the less precise approach
+  cb             points to the compile data block
+  atomcount      atomic group level
+  inassert       TRUE if in an assertion
+
+Returns:     TRUE or FALSE
+*/
+
+static BOOL
+is_anchored(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb,
+  int atomcount, BOOL inassert)
+{
+do {
+   PCRE2_SPTR scode = first_significant_code(
+     code + PRIV(OP_lengths)[*code], FALSE);
+   int op = *scode;
+
+   /* Non-capturing brackets */
+
+   if (op == OP_BRA  || op == OP_BRAPOS ||
+       op == OP_SBRA || op == OP_SBRAPOS)
+     {
+     if (!is_anchored(scode, bracket_map, cb, atomcount, inassert))
+       return FALSE;
+     }
+
+   /* Capturing brackets */
+
+   else if (op == OP_CBRA  || op == OP_CBRAPOS ||
+            op == OP_SCBRA || op == OP_SCBRAPOS)
+     {
+     int n = GET2(scode, 1+LINK_SIZE);
+     int new_map = bracket_map | ((n < 32)? (1u << n) : 1);
+     if (!is_anchored(scode, new_map, cb, atomcount, inassert)) return FALSE;
+     }
+
+   /* Positive forward assertion */
+
+   else if (op == OP_ASSERT)
+     {
+     if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;
+     }
+
+   /* Condition */
+
+   else if (op == OP_COND)
+     {
+     if (!is_anchored(scode, bracket_map, cb, atomcount, inassert))
+       return FALSE;
+     }
+
+   /* Atomic groups */
+
+   else if (op == OP_ONCE)
+     {
+     if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert))
+       return FALSE;
+     }
+
+   /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
+   it isn't in brackets that are or may be referenced or inside an atomic
+   group or an assertion. Also the pattern must not contain *PRUNE or *SKIP,
+   because these break the feature. Consider, for example, /(?s).*?(*PRUNE)b/
+   with the subject "aab", which matches "b", i.e. not at the start of a line.
+   There is also an option that disables auto-anchoring. */
+
+   else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
+             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)
+       return FALSE;
+     }
+
+   /* Check for explicit anchoring */
+
+   else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
+
+   code += GET(code, 1);
+   }
+while (*code == OP_ALT);   /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+*         Check for starting with ^ or .*        *
+*************************************************/
+
+/* This is called to find out if every branch starts with ^ or .* so that
+"first char" processing can be done to speed things up in multiline
+matching and for non-DOTALL patterns that start with .* (which must start at
+the beginning or after \n). As in the case of is_anchored() (see above), we
+have to take account of back references to capturing brackets that contain .*
+because in that case we can't make the assumption. Also, the appearance of .*
+inside atomic brackets or in an assertion, or in a pattern that contains *PRUNE
+or *SKIP does not count, because once again the assumption no longer holds.
+
+Arguments:
+  code           points to start of the compiled pattern or a group
+  bracket_map    a bitmap of which brackets we are inside while testing; this
+                   handles up to substring 31; after that we just have to take
+                   the less precise approach
+  cb             points to the compile data
+  atomcount      atomic group level
+  inassert       TRUE if in an assertion
+
+Returns:         TRUE or FALSE
+*/
+
+static BOOL
+is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb,
+  int atomcount, BOOL inassert)
+{
+do {
+   PCRE2_SPTR scode = first_significant_code(
+     code + PRIV(OP_lengths)[*code], FALSE);
+   int op = *scode;
+
+   /* If we are at the start of a conditional assertion group, *both* the
+   conditional assertion *and* what follows the condition must satisfy the test
+   for start of line. Other kinds of condition fail. Note that there may be an
+   auto-callout at the start of a condition. */
+
+   if (op == OP_COND)
+     {
+     scode += 1 + LINK_SIZE;
+
+     if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
+       else if (*scode == OP_CALLOUT_STR) scode += GET(scode, 1 + 2*LINK_SIZE);
+
+     switch (*scode)
+       {
+       case OP_CREF:
+       case OP_DNCREF:
+       case OP_RREF:
+       case OP_DNRREF:
+       case OP_FAIL:
+       case OP_FALSE:
+       case OP_TRUE:
+       return FALSE;
+
+       default:     /* Assertion */
+       if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;
+       do scode += GET(scode, 1); while (*scode == OP_ALT);
+       scode += 1 + LINK_SIZE;
+       break;
+       }
+     scode = first_significant_code(scode, FALSE);
+     op = *scode;
+     }
+
+   /* Non-capturing brackets */
+
+   if (op == OP_BRA  || op == OP_BRAPOS ||
+       op == OP_SBRA || op == OP_SBRAPOS)
+     {
+     if (!is_startline(scode, bracket_map, cb, atomcount, inassert))
+       return FALSE;
+     }
+
+   /* Capturing brackets */
+
+   else if (op == OP_CBRA  || op == OP_CBRAPOS ||
+            op == OP_SCBRA || op == OP_SCBRAPOS)
+     {
+     int n = GET2(scode, 1+LINK_SIZE);
+     int new_map = bracket_map | ((n < 32)? (1u << n) : 1);
+     if (!is_startline(scode, new_map, cb, atomcount, inassert)) return FALSE;
+     }
+
+   /* Positive forward assertions */
+
+   else if (op == OP_ASSERT)
+     {
+     if (!is_startline(scode, bracket_map, cb, atomcount, TRUE))
+       return FALSE;
+     }
+
+   /* Atomic brackets */
+
+   else if (op == OP_ONCE)
+     {
+     if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert))
+       return FALSE;
+     }
+
+   /* .* means "start at start or after \n" if it isn't in atomic brackets or
+   brackets that may be referenced or an assertion, and as long as the pattern
+   does not contain *PRUNE or *SKIP, because these break the feature. Consider,
+   for example, /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab",
+   i.e. not at the start of a line. There is also an option that disables this
+   optimization. */
+
+   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)
+       return FALSE;
+     }
+
+   /* Check for explicit circumflex; anything else gives a FALSE result. Note
+   in particular that this includes atomic brackets OP_ONCE because the number
+   of characters matched by .* cannot be adjusted inside them. */
+
+   else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
+
+   /* Move on to the next alternative */
+
+   code += GET(code, 1);
+   }
+while (*code == OP_ALT);  /* Loop for each alternative */
+return TRUE;
 }
 
 
@@ -2479,7 +7961,7 @@
 {
 for (;;)
   {
-  register PCRE2_UCHAR c = *code;
+  PCRE2_UCHAR c = *code;
   if (c == OP_END) return NULL;
   if (c == OP_RECURSE) return code;
 
@@ -2493,8 +7975,8 @@
 
   /* 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
-  two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
-  must add in its length. */
+  two code units of parameters, and for MARK/PRUNE/SKIP/THEN with an argument,
+  we must add in its length. */
 
   else
     {
@@ -2608,5532 +8090,6 @@
 
 
 /*************************************************
-*           Check for POSIX class syntax         *
-*************************************************/
-
-/* This function is called when the sequence "[:" or "[." or "[=" is
-encountered in a character class. It checks whether this is followed by a
-sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
-reach an unescaped ']' without the special preceding character, return FALSE.
-
-Originally, this function only recognized a sequence of letters between the
-terminators, but it seems that Perl recognizes any sequence of characters,
-though of course unknown POSIX names are subsequently rejected. Perl gives an
-"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
-didn't consider this to be a POSIX class. Likewise for [:1234:].
-
-The problem in trying to be exactly like Perl is in the handling of escapes. We
-have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
-class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
-below handles the special cases \\ and \], but does not try to do any other
-escape processing. This makes it different from Perl for cases such as
-[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does
-not recognize "l\ower". This is a lesser evil than not diagnosing bad classes
-when Perl does, I think.
-
-A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
-It seems that the appearance of a nested POSIX class supersedes an apparent
-external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
-a digit. This is handled by returning FALSE if the start of a new group with
-the same terminator is encountered, since the next closing sequence must close
-the nested group, not the outer one.
-
-In Perl, unescaped square brackets may also appear as part of class names. For
-example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
-[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
-seem right at all. PCRE does not allow closing square brackets in POSIX class
-names.
-
-Arguments:
-  ptr      pointer to the initial [
-  endptr   where to return a pointer to the terminating ':', '.', or '='
-
-Returns:   TRUE or FALSE
-*/
-
-static BOOL
-check_posix_syntax(PCRE2_SPTR ptr, PCRE2_SPTR *endptr)
-{
-PCRE2_UCHAR terminator;  /* Don't combine these lines; the Solaris cc */
-terminator = *(++ptr);   /* compiler warns about "non-constant" initializer. */
-
-for (++ptr; *ptr != CHAR_NULL; ptr++)
-  {
-  if (*ptr == CHAR_BACKSLASH &&
-      (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET || ptr[1] == CHAR_BACKSLASH))
-    ptr++;
-  else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||
-            *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
-  else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
-    {
-    *endptr = ptr;
-    return TRUE;
-    }
-  }
-
-return FALSE;
-}
-
-
-
-/*************************************************
-*          Check POSIX class name                *
-*************************************************/
-
-/* This function is called to check the name given in a POSIX-style class entry
-such as [:alnum:].
-
-Arguments:
-  ptr        points to the first letter
-  len        the length of the name
-
-Returns:     a value representing the name, or -1 if unknown
-*/
-
-static int
-check_posix_name(PCRE2_SPTR ptr, int len)
-{
-const char *pn = posix_names;
-register int yield = 0;
-while (posix_name_lengths[yield] != 0)
-  {
-  if (len == posix_name_lengths[yield] &&
-    PRIV(strncmp_c8)(ptr, pn, (unsigned int)len) == 0) return yield;
-  pn += posix_name_lengths[yield] + 1;
-  yield++;
-  }
-return -1;
-}
-
-
-
-#ifdef SUPPORT_UNICODE
-/*************************************************
-*           Get othercase range                  *
-*************************************************/
-
-/* This function is passed the start and end of a class range in UCT mode. It
-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
-
-Yield:        -1 when no more
-               0 when a range is returned
-              >0 the CASESET offset for char with multiple other cases
-                in this case, ocptr contains the original
-*/
-
-static int
-get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr,
-  uint32_t *odptr)
-{
-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. */
-
-for (c = *cptr; c <= d; c++)
-  {
-  if ((co = UCD_CASESET(c)) != 0)
-    {
-    *ocptr = c++;   /* Character that has the set */
-    *cptr = c;      /* Rest of input range */
-    return (int)co;
-    }
-  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     *
-*************************************************/
-
-/* 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
-mutually recursive with the function immediately below.
-
-Arguments:
-  classbits     the bit map for characters < 256
-  uchardptr     points to the pointer for extra data
-  options       the options word
-  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,
-  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. Sometimes we can just extend the original
-range. */
-
-if ((options & PCRE2_CASELESS) != 0)
-  {
-#ifdef SUPPORT_UNICODE
-  if ((options & PCRE2_UTF) != 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)) >= 0)
-      {
-      /* Handle a single character that has more than one other case. */
-
-      if (rc > 0) n8 += add_list_to_class(classbits, uchardptr, options, cb,
-        PRIV(ucd_caseless_sets) + rc, oc);
-
-      /* Do nothing if the other case range is within the original range. */
-
-      else if (oc >= start && od <= 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(classbits, uchardptr, options, cb, oc, od);
-      }
-    }
-  else
-#endif  /* SUPPORT_UNICODE */
-
-  /* Not UTF mode */
-
-  for (c = start; c <= classbits_end; c++)
-    {
-    SETBIT(classbits, cb->fcc[c]);
-    n8++;
-    }
-  }
-
-/* Now handle the original 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;
-
-/* 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
-  *uchardptr = uchardata;   /* Updata extra data pointer */
-  }
-#else
-  (void)uchardptr;          /* Avoid compiler warning */
-#endif /* SUPPORT_WIDE_CHARS */
-
-return n8;    /* Number of 8-bit characters */
-}
-
-
-
-/*************************************************
-*        Add a list of characters to a class     *
-*************************************************/
-
-/* This function is used for adding a list of case-equivalent characters to a
-class, and also for adding a list of horizontal or vertical whitespace. If the
-list is in order (which it should be), ranges of characters are detected and
-handled appropriately. This function is mutually recursive with the function
-above.
-
-Arguments:
-  classbits     the bit map for characters < 256
-  uchardptr     points to the pointer for extra data
-  options       the options word
-  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,
-  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(classbits, uchardptr, options, cb, p[0], p[n]);
-    }
-  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 word
-  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, 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, cb, 0, p[0] - 1);
-while (p[0] < NOTACHAR)
-  {
-  while (p[1] == p[0] + 1) p++;
-  n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1,
-    (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1);
-  p++;
-  }
-return n8;
-}
-
-
-
-/*************************************************
-*       Process (*VERB) name for escapes         *
-*************************************************/
-
-/* This function is called when the PCRE2_ALT_VERBNAMES option is set, to
-process the characters in a verb's name argument. It is called twice, once with
-codeptr == NULL, to find out the length of the processed name, and again to put
-the name into memory.
-
-Arguments:
-  ptrptr        pointer to the input pointer
-  codeptr       pointer to the compiled code pointer
-  errorcodeptr  pointer to the error code
-  options       the options bits
-  utf           TRUE if processing UTF
-  cb            compile data block
-
-Returns:        length of the processed name, or < 0 on error
-*/
-
-static int
-process_verb_name(PCRE2_SPTR *ptrptr, PCRE2_UCHAR **codeptr, int *errorcodeptr,
-  uint32_t options, BOOL utf, compile_block *cb)
-{
-int32_t arglen = 0;
-BOOL inescq = FALSE;
-PCRE2_SPTR ptr = *ptrptr;
-PCRE2_UCHAR *code = (codeptr == NULL)? NULL : *codeptr;
-
-for (; ptr < cb->end_pattern; ptr++)
-  {
-  uint32_t x = *ptr;
-
-  /* Skip over literals */
-
-  if (inescq)
-    {
-    if (x == CHAR_BACKSLASH && ptr[1] == CHAR_E)
-      {
-      inescq = FALSE;
-      ptr++;;
-      continue;
-      }
-    }
-
-  else  /* Not a literal character */
-    {
-    if (x == CHAR_RIGHT_PARENTHESIS) break;
-
-    /* Skip over comments and whitespace in extended mode. */
-
-    if ((options & PCRE2_EXTENDED) != 0)
-      {
-      PCRE2_SPTR wscptr = ptr;
-      while (MAX_255(x) && (cb->ctypes[x] & ctype_space) != 0) x = *(++ptr);
-      if (x == CHAR_NUMBER_SIGN)
-        {
-        ptr++;
-        while (*ptr != CHAR_NULL || ptr < cb->end_pattern)
-          {
-          if (IS_NEWLINE(ptr))       /* For non-fixed-length newline cases, */
-            {                        /* IS_NEWLINE sets cb->nllen. */
-            ptr += cb->nllen;
-            break;
-            }
-          ptr++;
-#ifdef SUPPORT_UNICODE
-          if (utf) FORWARDCHAR(ptr);
-#endif
-          }
-        }
-
-      /* If we have skipped any characters, restart the loop. */
-
-      if (ptr > wscptr)
-        {
-        ptr--;
-        continue;
-        }
-      }
-
-    /* Process escapes */
-
-    if (x == '\\')
-      {
-      int rc;
-      *errorcodeptr = 0;
-      rc = PRIV(check_escape)(&ptr, cb->end_pattern, &x, errorcodeptr, options,
-        FALSE, cb);
-      *ptrptr = ptr;   /* For possible error */
-      if (*errorcodeptr != 0) return -1;
-      if (rc != 0)
-        {
-        if (rc == ESC_Q)
-          {
-          inescq = TRUE;
-          continue;
-          }
-        if (rc == ESC_E) continue;
-        *errorcodeptr = ERR40;
-        return -1;
-        }
-      }
-    }
-
-  /* We have the next character in the name. */
-
-#ifdef SUPPORT_UNICODE
-  if (utf)
-    {
-    if (code == NULL)   /* Just want the length */
-      {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-      int i;
-      for (i = 0; i < PRIV(utf8_table1_size); i++)
-        if ((int)x <= PRIV(utf8_table1)[i]) break;
-      arglen += i;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-      if (x > 0xffff) arglen++;
-#endif
-      }
-    else
-      {
-      PCRE2_UCHAR cbuff[8];
-      x = PRIV(ord2utf)(x, cbuff);
-      memcpy(code, cbuff, CU2BYTES(x));
-      code += x;
-      }
-    }
-  else
-#endif  /* SUPPORT_UNICODE */
-
-  /* Not UTF */
-    {
-    if (code != NULL) *code++ = (PCRE2_UCHAR)x;
-    }
-
-  arglen++;
-
-  if ((unsigned int)arglen > MAX_MARK)
-    {
-    *errorcodeptr = ERR76;
-    *ptrptr = ptr;
-    return -1;
-    }
-  }
-
-/* Update the pointers before returning. */
-
-*ptrptr = ptr;
-if (codeptr != NULL) *codeptr = code;
-return arglen;
-}
-
-
-
-/*************************************************
-*          Macro for the next two functions      *
-*************************************************/
-
-/* Both scan_for_captures() and compile_branch() use this macro to generate a
-fragment of code that reads the characters of a name and sets its length
-(checking for not being too long). Count the characters dynamically, to avoid
-the possibility of integer overflow. The same macro is used for reading *VERB
-names. */
-
-#define READ_NAME(ctype, errno, errset)                      \
-  namelen = 0;                                               \
-  while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype) != 0)   \
-    {                                                        \
-    ptr++;                                                   \
-    namelen++;                                               \
-    if (namelen > MAX_NAME_SIZE)                             \
-      {                                                      \
-      errset = errno;                                        \
-      goto FAILED;                                           \
-      }                                                      \
-    }
-
-
-
-/*************************************************
-*      Scan regex to identify named groups       *
-*************************************************/
-
-/* This function is called first of all, to scan for named capturing groups so
-that information about them is fully available to both the compiling scans.
-It skips over everything except parenthesized items.
-
-Arguments:
-  ptrptr   points to pointer to the start of the pattern
-  options  compiling dynamic options
-  cb       pointer to the compile data block
-
-Returns:   zero on success or a non-zero error code, with pointer updated
-*/
-
-typedef struct nest_save {
-  uint16_t  nest_depth;
-  uint16_t  reset_group;
-  uint16_t  max_group;
-  uint16_t  flags;
-} nest_save;
-
-#define NSF_RESET    0x0001u
-#define NSF_EXTENDED 0x0002u
-#define NSF_DUPNAMES 0x0004u
-
-static int scan_for_captures(PCRE2_SPTR *ptrptr, uint32_t options,
-  compile_block *cb)
-{
-uint32_t c;
-uint32_t delimiter;
-uint32_t set, unset, *optset;
-uint32_t skiptoket = 0;
-uint16_t nest_depth = 0;
-int errorcode = 0;
-int escape;
-int namelen;
-int i;
-BOOL inescq = FALSE;
-BOOL isdupname;
-BOOL utf = (options & PCRE2_UTF) != 0;
-BOOL negate_class;
-PCRE2_SPTR name;
-PCRE2_SPTR start;
-PCRE2_SPTR ptr = *ptrptr;
-named_group *ng;
-nest_save *top_nest = NULL;
-nest_save *end_nests = (nest_save *)(cb->start_workspace + cb->workspace_size);
-
-/* The size of the nest_save structure might not be a factor of the size of the
-workspace. Therefore we must round down end_nests so as to correctly avoid
-creating a nest_save that spans the end of the workspace. */
-
-end_nests = (nest_save *)((char *)end_nests -
-  ((cb->workspace_size * sizeof(PCRE2_UCHAR)) % sizeof(nest_save)));
-
-/* Now scan the pattern */
-
-for (; ptr < cb->end_pattern; ptr++)
-  {
-  c = *ptr;
-
-  /* Parenthesized groups set skiptoket when all following characters up to the
-  next closing parenthesis must be ignored. The parenthesis itself must be
-  processed (to end the nested parenthesized item). */
-
-  if (skiptoket != 0)
-    {
-    if (c != CHAR_RIGHT_PARENTHESIS) continue;
-    skiptoket = 0;
-    }
-
-  /* Skip over literals */
-
-  if (inescq)
-    {
-    if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)
-      {
-      inescq = FALSE;
-      ptr++;
-      }
-    continue;
-    }
-
-  /* Skip over # comments and whitespace in extended mode. */
-
-  if ((options & PCRE2_EXTENDED) != 0)
-    {
-    PCRE2_SPTR wscptr = ptr;
-    while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr);
-    if (c == CHAR_NUMBER_SIGN)
-      {
-      ptr++;
-      while (ptr < cb->end_pattern)
-        {
-        if (IS_NEWLINE(ptr))         /* For non-fixed-length newline cases, */
-          {                          /* IS_NEWLINE sets cb->nllen. */
-          ptr += cb->nllen;
-          break;
-          }
-        ptr++;
-#ifdef SUPPORT_UNICODE
-        if (utf) FORWARDCHAR(ptr);
-#endif
-        }
-      }
-
-    /* If we skipped any characters, restart the loop. Otherwise, we didn't see
-    a comment. */
-
-    if (ptr > wscptr)
-      {
-      ptr--;
-      continue;
-      }
-    }
-
-  /* Process the next pattern item. */
-
-  switch(c)
-    {
-    default:              /* Most characters are just skipped */
-    break;
-
-    /* Skip escapes except for \Q */
-
-    case CHAR_BACKSLASH:
-    errorcode = 0;
-    escape = PRIV(check_escape)(&ptr, cb->end_pattern, &c, &errorcode, options,
-      FALSE, cb);
-    if (errorcode != 0) goto FAILED;
-    if (escape == ESC_Q) inescq = TRUE;
-    break;
-
-    /* Skip a character class. The syntax is complicated so we have to
-    replicate some of what happens when a class is processed for real. */
-
-    case CHAR_LEFT_SQUARE_BRACKET:
-    if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0 ||
-        PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0)
-      {
-      ptr += 6;
-      break;
-      }
-
-    /* If the first character is '^', set the negation flag (not actually used
-    here, except to recognize only one ^) and skip it. If the first few
-    characters (either before or after ^) are \Q\E or \E we skip them too. This
-    makes for compatibility with Perl. */
-
-    negate_class = FALSE;
-    for (;;)
-      {
-      c = *(++ptr);   /* First character in class */
-      if (c == CHAR_BACKSLASH)
-        {
-        if (ptr[1] == CHAR_E)
-          ptr++;
-        else if (PRIV(strncmp_c8)(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0)
-          ptr += 3;
-        else
-          break;
-        }
-      else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
-        negate_class = TRUE;
-      else break;
-      }
-
-    if (c == CHAR_RIGHT_SQUARE_BRACKET &&
-        (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0)
-      break;
-
-    /* Loop for the contents of the class */
-
-    for (;;)
-      {
-      PCRE2_SPTR tempptr;
-
-      if (c == CHAR_NULL && ptr >= cb->end_pattern)
-        {
-        errorcode = ERR6;  /* Missing terminating ']' */
-        goto FAILED;
-        }
-
-#ifdef SUPPORT_UNICODE
-      if (utf && HAS_EXTRALEN(c))
-        {                           /* Braces are required because the */
-        GETCHARLEN(c, ptr, ptr);    /* macro generates multiple statements */
-        }
-#endif
-
-      /* Inside \Q...\E everything is literal except \E */
-
-      if (inescq)
-        {
-        if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)  /* If we are at \E */
-          {
-          inescq = FALSE;                   /* Reset literal state */
-          ptr++;                            /* Skip the 'E' */
-          }
-        goto CONTINUE_CLASS;
-        }
-
-      /* Skip POSIX class names. */
-      if (c == CHAR_LEFT_SQUARE_BRACKET &&
-          (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
-           ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
-        {
-        ptr = tempptr + 1;
-        }
-      else if (c == CHAR_BACKSLASH)
-        {
-        errorcode = 0;
-        escape = PRIV(check_escape)(&ptr, cb->end_pattern, &c, &errorcode,
-          options, TRUE, cb);
-        if (errorcode != 0) goto FAILED;
-        if (escape == ESC_Q) inescq = TRUE;
-        }
-
-      CONTINUE_CLASS:
-      c = *(++ptr);
-      if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break;
-      }     /* End of class-processing loop */
-    break;
-
-    /* This is the real work of this function - handling parentheses. */
-
-    case CHAR_LEFT_PARENTHESIS:
-    nest_depth++;
-
-    if (ptr[1] != CHAR_QUESTION_MARK)
-      {
-      if (ptr[1] != CHAR_ASTERISK)
-        {
-        if ((options & PCRE2_NO_AUTO_CAPTURE) == 0) cb->bracount++;
-        }
-
-      /* (*something) - skip over a name, and then just skip to closing ket
-      unless PCRE2_ALT_VERBNAMES is set, in which case we have to process
-      escapes in the string after a verb name terminated by a colon. */
-
-      else
-        {
-        ptr += 2;
-        while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0) ptr++;
-        if (*ptr == CHAR_COLON && (options & PCRE2_ALT_VERBNAMES) != 0)
-          {
-          ptr++;
-          if (process_verb_name(&ptr, NULL, &errorcode, options, utf, cb) < 0)
-            goto FAILED;
-          }
-        else
-          {
-          while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS)
-            ptr++;
-          }
-        nest_depth--;
-        }
-      }
-
-    /* Handle (?...) groups */
-
-    else switch(ptr[2])
-      {
-      default:
-      ptr += 2;
-      if (ptr[0] == CHAR_R ||                           /* (?R) */
-          ptr[0] == CHAR_NUMBER_SIGN ||                 /* (?#) */
-          IS_DIGIT(ptr[0]) ||                           /* (?n) */
-          (ptr[0] == CHAR_MINUS && IS_DIGIT(ptr[1])))   /* (?-n) */
-        {
-        skiptoket = ptr[0];
-        break;
-        }
-
-      /* Handle (?| and (?imsxJU: which are the only other valid forms. Both
-      need a new block on the nest stack. */
-
-      if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace);
-      else if (++top_nest >= end_nests)
-        {
-        errorcode = ERR84;
-        goto FAILED;
-        }
-      top_nest->nest_depth = nest_depth;
-      top_nest->flags = 0;
-      if ((options & PCRE2_EXTENDED) != 0) top_nest->flags |= NSF_EXTENDED;
-      if ((options & PCRE2_DUPNAMES) != 0) top_nest->flags |= NSF_DUPNAMES;
-
-      if (*ptr == CHAR_VERTICAL_LINE)
-        {
-        top_nest->reset_group = (uint16_t)cb->bracount;
-        top_nest->max_group = (uint16_t)cb->bracount;
-        top_nest->flags |= NSF_RESET;
-        cb->external_flags |= PCRE2_DUPCAPUSED;
-        break;
-        }
-
-      /* Scan options */
-
-      top_nest->reset_group = 0;
-      top_nest->max_group = 0;
-
-      set = unset = 0;
-      optset = &set;
-
-      /* Need only track (?x: and (?J: at this stage */
-
-      while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON)
-        {
-        switch (*ptr++)
-          {
-          case CHAR_MINUS: optset = &unset; break;
-
-          case CHAR_x: *optset |= PCRE2_EXTENDED; break;
-
-          case CHAR_J:
-          *optset |= PCRE2_DUPNAMES;
-          cb->external_flags |= PCRE2_JCHANGED;
-          break;
-
-          case CHAR_i:
-          case CHAR_m:
-          case CHAR_s:
-          case CHAR_U:
-          break;
-
-          default:
-          errorcode = ERR11;
-          ptr--;    /* Correct the offset */
-          goto FAILED;
-          }
-        }
-
-      options = (options | set) & (~unset);
-
-      /* If the options ended with ')' this is not the start of a nested
-      group with option changes, so the options change at this level. If the
-      previous level set up a nest block, discard the one we have just created.
-      Otherwise adjust it for the previous level. */
-
-      if (*ptr == CHAR_RIGHT_PARENTHESIS)
-        {
-        nest_depth--;
-        if (top_nest > (nest_save *)(cb->start_workspace) &&
-            (top_nest-1)->nest_depth == nest_depth) top_nest --;
-        else top_nest->nest_depth = nest_depth;
-        }
-      break;
-
-      /* Skip over a numerical or string argument for a callout. */
-
-      case CHAR_C:
-      ptr += 2;
-      if (ptr[1] == CHAR_RIGHT_PARENTHESIS) break;
-      if (IS_DIGIT(ptr[1]))
-        {
-        while (IS_DIGIT(ptr[1])) ptr++;
-        }
-
-      /* Handle a string argument */
-
-      else
-        {
-        ptr++;
-        delimiter = 0;
-        for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
-          {
-          if (*ptr == PRIV(callout_start_delims)[i])
-            {
-            delimiter = PRIV(callout_end_delims)[i];
-            break;
-            }
-          }
-
-        if (delimiter == 0)
-          {
-          errorcode = ERR82;
-          goto FAILED;
-          }
-
-        start = ptr;
-        do
-          {
-          if (++ptr >= cb->end_pattern)
-            {
-            errorcode = ERR81;
-            ptr = start;   /* To give a more useful message */
-            goto FAILED;
-            }
-          if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2;
-          }
-        while (ptr[0] != delimiter);
-        }
-
-      /* Check terminating ) */
-
-      if (ptr[1] != CHAR_RIGHT_PARENTHESIS)
-        {
-        errorcode = ERR39;
-        ptr++;
-        goto FAILED;
-        }
-      break;
-
-      /* Conditional group */
-
-      case CHAR_LEFT_PARENTHESIS:
-      if (ptr[3] != CHAR_QUESTION_MARK)   /* Not assertion or callout */
-        {
-        nest_depth++;
-        ptr += 2;
-        break;
-        }
-
-      /* Must be an assertion or a callout */
-
-      switch(ptr[4])
-       {
-       case CHAR_LESS_THAN_SIGN:
-       if (ptr[5] != CHAR_EXCLAMATION_MARK && ptr[5] != CHAR_EQUALS_SIGN)
-         goto MISSING_ASSERTION;
-       /* Fall through */
-
-       case CHAR_C:
-       case CHAR_EXCLAMATION_MARK:
-       case CHAR_EQUALS_SIGN:
-       ptr++;
-       break;
-
-       default:
-       MISSING_ASSERTION:
-       ptr += 3;            /* To improve error message */
-       errorcode = ERR28;
-       goto FAILED;
-       }
-      break;
-
-      case CHAR_COLON:
-      case CHAR_GREATER_THAN_SIGN:
-      case CHAR_EQUALS_SIGN:
-      case CHAR_EXCLAMATION_MARK:
-      case CHAR_AMPERSAND:
-      case CHAR_PLUS:
-      ptr += 2;
-      break;
-
-      case CHAR_P:
-      if (ptr[3] != CHAR_LESS_THAN_SIGN)
-        {
-        ptr += 3;
-        break;
-        }
-      ptr++;
-      c = CHAR_GREATER_THAN_SIGN;   /* Terminator */
-      goto DEFINE_NAME;
-
-      case CHAR_LESS_THAN_SIGN:
-      if (ptr[3] == CHAR_EQUALS_SIGN || ptr[3] == CHAR_EXCLAMATION_MARK)
-        {
-        ptr += 3;
-        break;
-        }
-      c = CHAR_GREATER_THAN_SIGN;   /* Terminator */
-      goto DEFINE_NAME;
-
-      case CHAR_APOSTROPHE:
-      c = CHAR_APOSTROPHE;    /* Terminator */
-
-      DEFINE_NAME:
-      name = ptr = ptr + 3;
-
-      if (*ptr == c)          /* Empty name */
-        {
-        errorcode = ERR62;
-        goto FAILED;
-        }
-
-      if (IS_DIGIT(*ptr))
-        {
-        errorcode = ERR44;   /* Group name must start with non-digit */
-        goto FAILED;
-        }
-
-      if (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) == 0)
-        {
-        errorcode = ERR24;
-        goto FAILED;
-        }
-
-      /* Advance ptr, set namelen and check its length. */
-      READ_NAME(ctype_word, ERR48, errorcode);
-
-      if (*ptr != c)
-        {
-        errorcode = ERR42;
-        goto FAILED;
-        }
-
-      if (cb->names_found >= MAX_NAME_COUNT)
-        {
-        errorcode = ERR49;
-        goto FAILED;
-        }
-
-      if (namelen + IMM2_SIZE + 1 > cb->name_entry_size)
-        cb->name_entry_size = (uint16_t)(namelen + IMM2_SIZE + 1);
-
-      /* We have a valid name for this capturing group. */
-
-      cb->bracount++;
-
-      /* Scan the list to check for duplicates. For duplicate names, if the
-      number is the same, break the loop, which causes the name to be
-      discarded; otherwise, if DUPNAMES is not set, give an error.
-      If it is set, allow the name with a different number, but continue
-      scanning in case this is a duplicate with the same number. For
-      non-duplicate names, give an error if the number is duplicated. */
-
-      isdupname = FALSE;
-      ng = cb->named_groups;
-      for (i = 0; i < cb->names_found; i++, ng++)
-        {
-        if (namelen == ng->length &&
-            PRIV(strncmp)(name, ng->name, (size_t)namelen) == 0)
-          {
-          if (ng->number == cb->bracount) break;
-          if ((options & PCRE2_DUPNAMES) == 0)
-            {
-            errorcode = ERR43;
-            goto FAILED;
-            }
-          isdupname = ng->isdup = TRUE;     /* Mark as a duplicate */
-          cb->dupnames = TRUE;              /* Duplicate names exist */
-          }
-        else if (ng->number == cb->bracount)
-          {
-          errorcode = ERR65;
-          goto FAILED;
-          }
-        }
-
-      if (i < cb->names_found) break;   /* Ignore duplicate with same number */
-
-      /* Increase the list size if necessary */
-
-      if (cb->names_found >= cb->named_group_list_size)
-        {
-        uint32_t newsize = cb->named_group_list_size * 2;
-        named_group *newspace =
-          cb->cx->memctl.malloc(newsize * sizeof(named_group),
-          cb->cx->memctl.memory_data);
-        if (newspace == NULL)
-          {
-          errorcode = ERR21;
-          goto FAILED;
-          }
-
-        memcpy(newspace, cb->named_groups,
-          cb->named_group_list_size * sizeof(named_group));
-        if (cb->named_group_list_size > NAMED_GROUP_LIST_SIZE)
-          cb->cx->memctl.free((void *)cb->named_groups,
-          cb->cx->memctl.memory_data);
-        cb->named_groups = newspace;
-        cb->named_group_list_size = newsize;
-        }
-
-      /* Add this name to the list */
-
-      cb->named_groups[cb->names_found].name = name;
-      cb->named_groups[cb->names_found].length = (uint16_t)namelen;
-      cb->named_groups[cb->names_found].number = cb->bracount;
-      cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname;
-      cb->names_found++;
-      break;
-      }        /* End of (? switch */
-    break;     /* End of ( handling */
-
-    /* At an alternation, reset the capture count if we are in a (?| group. */
-
-    case CHAR_VERTICAL_LINE:
-    if (top_nest != NULL && top_nest->nest_depth == nest_depth &&
-        (top_nest->flags & NSF_RESET) != 0)
-      {
-      if (cb->bracount > top_nest->max_group)
-        top_nest->max_group = (uint16_t)cb->bracount;
-      cb->bracount = top_nest->reset_group;
-      }
-    break;
-
-    /* At a right parenthesis, reset the capture count to the maximum if we
-    are in a (?| group and/or reset the extended option. */
-
-    case CHAR_RIGHT_PARENTHESIS:
-    if (top_nest != NULL && top_nest->nest_depth == nest_depth)
-      {
-      if ((top_nest->flags & NSF_RESET) != 0 &&
-          top_nest->max_group > cb->bracount)
-        cb->bracount = top_nest->max_group;
-      if ((top_nest->flags & NSF_EXTENDED) != 0) options |= PCRE2_EXTENDED;
-        else options &= ~PCRE2_EXTENDED;
-      if ((top_nest->flags & NSF_DUPNAMES) != 0) options |= PCRE2_DUPNAMES;
-        else options &= ~PCRE2_DUPNAMES;
-      if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL;
-        else top_nest--;
-      }
-    if (nest_depth == 0)    /* Unmatched closing parenthesis */
-      {
-      errorcode = ERR22;
-      goto FAILED;
-      }
-    nest_depth--;
-    break;
-    }
-  }
-
-if (nest_depth == 0)
-  {
-  cb->final_bracount = cb->bracount;
-  return 0;
-  }
-
-/* We give a special error for a missing closing parentheses after (?# because
-it might otherwise be hard to see where the missing character is. */
-
-errorcode = (skiptoket == CHAR_NUMBER_SIGN)? ERR18 : ERR14;
-
-FAILED:
-*ptrptr = ptr;
-return errorcode;
-}
-
-
-
-/*************************************************
-*           Compile one branch                   *
-*************************************************/
-
-/* Scan the pattern, compiling it into the a vector. If the options are
-changed during the branch, the pointer is used to change the external options
-bits. This function is used during the pre-compile phase when we are trying
-to find out the amount of memory needed, as well as during the real compile
-phase. The value of lengthptr distinguishes the two phases.
-
-Arguments:
-  optionsptr        pointer to the option bits
-  codeptr           points to the pointer to the current code point
-  ptrptr            points to the current pattern pointer
-  errorcodeptr      points to error code variable
-  firstcuptr        place to put the first required code unit
-  firstcuflagsptr   place to put the first code unit flags, or a negative number
-  reqcuptr          place to put the last required code unit
-  reqcuflagsptr     place to put the last required code unit flags, or a negative number
-  bcptr             points to current branch chain
-  cond_depth        conditional nesting depth
-  cb                contains pointers to tables etc.
-  lengthptr         NULL during the real compile phase
-                    points to length accumulator during pre-compile phase
-
-Returns:            TRUE on success
-                    FALSE, with *errorcodeptr set non-zero on error
-*/
-
-static BOOL
-compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr,
-  PCRE2_SPTR *ptrptr, int *errorcodeptr,
-  uint32_t *firstcuptr, int32_t *firstcuflagsptr,
-  uint32_t *reqcuptr, int32_t *reqcuflagsptr,
-  branch_chain *bcptr, int cond_depth,
-  compile_block *cb, size_t *lengthptr)
-{
-int repeat_min = 0, repeat_max = 0;      /* To please picky compilers */
-int bravalue = 0;
-uint32_t greedy_default, greedy_non_default;
-uint32_t repeat_type, op_type;
-uint32_t options = *optionsptr;               /* May change dynamically */
-uint32_t firstcu, reqcu;
-int32_t firstcuflags, reqcuflags;
-uint32_t zeroreqcu, zerofirstcu;
-int32_t zeroreqcuflags, zerofirstcuflags;
-int32_t req_caseopt, reqvary, tempreqvary;
-int after_manual_callout = 0;
-int escape;
-size_t length_prevgroup = 0;
-register uint32_t c;
-register PCRE2_UCHAR *code = *codeptr;
-PCRE2_UCHAR *last_code = code;
-PCRE2_UCHAR *orig_code = code;
-PCRE2_UCHAR *tempcode;
-BOOL inescq = FALSE;
-BOOL groupsetfirstcu = FALSE;
-PCRE2_SPTR ptr = *ptrptr;
-PCRE2_SPTR tempptr;
-PCRE2_UCHAR *previous = NULL;
-PCRE2_UCHAR *previous_callout = NULL;
-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) because they may change
-dynamically as we process the pattern. */
-
-#ifdef SUPPORT_UNICODE
-BOOL utf = (options & PCRE2_UTF) != 0;
-#if PCRE2_CODE_UNIT_WIDTH != 32
-PCRE2_UCHAR utf_units[6];      /* For setting up multi-cu chars */
-#endif
-
-#else  /* No UTF support */
-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);
-greedy_non_default = greedy_default ^ 1;
-
-/* Initialize no first unit, no required unit. REQ_UNSET means "no char
-matching encountered yet". It gets changed to REQ_NONE if we hit something that
-matches a non-fixed first unit; reqcu just remains unset if we never find one.
-
-When we hit a repeat whose minimum is zero, we may have to adjust these values
-to take the zero repeat into account. This is implemented by setting them to
-zerofirstcu and zeroreqcu when such a repeat is encountered. The individual
-item types that can be repeated set these backoff variables appropriately. */
-
-firstcu = reqcu = zerofirstcu = zeroreqcu = 0;
-firstcuflags = reqcuflags = zerofirstcuflags = zeroreqcuflags = REQ_UNSET;
-
-/* The variable req_caseopt contains either the REQ_CASELESS value or zero,
-according to the current setting of the caseless flag. The REQ_CASELESS value
-leaves the lower 28 bit empty. It is added into the firstcu or reqcu variables
-to record the case status of the value. This is used only for ASCII characters.
-*/
-
-req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS:0;
-
-/* Switch on next character until the end of the branch */
-
-for (;; ptr++)
-  {
-  BOOL negate_class;
-  BOOL should_flip_negation;
-  BOOL match_all_or_no_wide_chars;
-  BOOL possessive_quantifier;
-  BOOL is_quantifier;
-  BOOL is_recurse;
-  BOOL is_dupname;
-  BOOL reset_bracount;
-  int class_has_8bitchar;
-  int class_one_char;
-#ifdef SUPPORT_WIDE_CHARS
-  BOOL xclass_has_prop;
-#endif
-  int recno;                               /* Must be signed */
-  int refsign;                             /* Must be signed */
-  int terminator;                          /* Must be signed */
-  unsigned int mclength;
-  unsigned int tempbracount;
-  uint32_t ec;
-  uint32_t newoptions;
-  uint32_t skipunits;
-  uint32_t subreqcu, subfirstcu;
-  int32_t subreqcuflags, subfirstcuflags;  /* Must be signed */
-  PCRE2_UCHAR mcbuffer[8];
-
-  /* Come here to restart the loop. */
-
-  REDO_LOOP:
-
-  /* Get next character in the pattern */
-
-  c = *ptr;
-
-  /* If we are at the end of a nested substitution, revert to the outer level
-  string. Nesting only happens one or two levels deep, and the inserted string
-  is always zero terminated. */
-
-  if (c == CHAR_NULL && cb->nestptr[0] != NULL)
-    {
-    ptr = cb->nestptr[0];
-    cb->nestptr[0] = cb->nestptr[1];
-    cb->nestptr[1] = NULL;
-    c = *ptr;
-    }
-
-  /* If we are in the pre-compile phase, accumulate the length used for the
-  previous cycle of this loop. */
-
-  if (lengthptr != NULL)
-    {
-    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;
-      goto FAILED;
-      }
-
-    /* There is at least one situation where code goes backwards: this is the
-    case of a zero quantifier after a class (e.g. [ab]{0}). At compile time,
-    the class is simply eliminated. However, it is created first, so we have to
-    allow memory for it. Therefore, don't ever reduce the length at this point.
-    */
-
-    if (code < last_code) code = last_code;
-
-    /* Paranoid check for integer overflow */
-
-    if (OFLOW_MAX - *lengthptr < (size_t)(code - last_code))
-      {
-      *errorcodeptr = ERR20;
-      goto FAILED;
-      }
-    *lengthptr += (size_t)(code - last_code);
-
-    /* If "previous" is set and it is not at the start of the work space, move
-    it back to there, in order to avoid filling up the work space. Otherwise,
-    if "previous" is NULL, reset the current code pointer to the start. */
-
-    if (previous != NULL)
-      {
-      if (previous > orig_code)
-        {
-        memmove(orig_code, previous, (size_t)CU2BYTES(code - previous));
-        code -= previous - orig_code;
-        previous = orig_code;
-        }
-      }
-    else code = orig_code;
-
-    /* Remember where this code item starts so we can pick up the length
-    next time round. */
-
-    last_code = code;
-    }
-
-  /* Before doing anything else we must handle all the special items that do
-  nothing, and which may come between an item and its quantifier. Otherwise,
-  when auto-callouts are enabled, a callout gets incorrectly inserted before
-  the quantifier is recognized. After recognizing a "do nothing" item, restart
-  the loop in case another one follows. */
-
-  /* If c is not NULL we are not at the end of the pattern. If it is NULL, we
-  may still be in the pattern with a NULL data item. In these cases, if we are
-  in \Q...\E, check for the \E that ends the literal string; if not, we have a
-  literal character. If not in \Q...\E, an isolated \E is ignored. */
-
-  if (c != CHAR_NULL || ptr < cb->end_pattern)
-    {
-    if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)
-      {
-      inescq = FALSE;
-      ptr++;
-      continue;
-      }
-    else if (inescq)   /* Literal character */
-      {
-      if (previous_callout != NULL)
-        {
-        if (lengthptr == NULL)  /* Don't attempt in pre-compile phase */
-          complete_callout(previous_callout, ptr, cb);
-        previous_callout = NULL;
-        }
-      if ((options & PCRE2_AUTO_CALLOUT) != 0)
-        {
-        previous_callout = code;
-        code = auto_callout(code, ptr, cb);
-        }
-      goto NORMAL_CHAR;
-      }
-
-    /* Check for the start of a \Q...\E sequence. We must do this here rather
-    than later in case it is immediately followed by \E, which turns it into a
-    "do nothing" sequence. */
-
-    if (c == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
-      {
-      inescq = TRUE;
-      ptr++;
-      continue;
-      }
-    }
-
-  /* In extended mode, skip white space and #-comments that end at newline. */
-
-  if ((options & PCRE2_EXTENDED) != 0)
-    {
-    PCRE2_SPTR wscptr = ptr;
-    while (MAX_255(c) && (cb->ctypes[c] & ctype_space) != 0) c = *(++ptr);
-    if (c == CHAR_NUMBER_SIGN)
-      {
-      ptr++;
-      while (ptr < cb->end_pattern)
-        {
-        if (IS_NEWLINE(ptr))         /* For non-fixed-length newline cases, */
-          {                          /* IS_NEWLINE sets cb->nllen. */
-          ptr += cb->nllen;
-          break;
-          }
-        ptr++;
-#ifdef SUPPORT_UNICODE
-        if (utf) FORWARDCHAR(ptr);
-#endif
-        }
-      }
-
-    /* If we skipped any characters, restart the loop. Otherwise, we didn't see
-    a comment. */
-
-    if (ptr > wscptr) goto REDO_LOOP;
-    }
-
-  /* Skip over (?# comments. */
-
-  if (c == CHAR_LEFT_PARENTHESIS && ptr[1] == CHAR_QUESTION_MARK &&
-      ptr[2] == CHAR_NUMBER_SIGN)
-    {
-    ptr += 3;
-    while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
-    if (*ptr != CHAR_RIGHT_PARENTHESIS)
-      {
-      *errorcodeptr = ERR18;
-      goto FAILED;
-      }
-    continue;
-    }
-
-  /* End of processing "do nothing" items. See if the next thing is a
-  quantifier. */
-
-  is_quantifier =
-    c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
-     (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
-
-  /* Fill in length of a previous callout and create an auto callout if
-  required, except when the next thing is a quantifier or when processing a
-  property substitution string for \w etc in UCP mode. */
-
-  if (!is_quantifier && cb->nestptr[0] == NULL)
-    {
-    if (previous_callout != NULL && after_manual_callout-- <= 0)
-      {
-      if (lengthptr == NULL)      /* Don't attempt in pre-compile phase */
-        complete_callout(previous_callout, ptr, cb);
-      previous_callout = NULL;
-      }
-
-    if ((options & PCRE2_AUTO_CALLOUT) != 0)
-      {
-      previous_callout = code;
-      code = auto_callout(code, ptr, cb);
-      }
-    }
-
-  /* Process the next pattern item. */
-
-  switch(c)
-    {
-    /* ===================================================================*/
-    /* The branch terminates at string end or | or ) */
-
-    case CHAR_NULL:
-    if (ptr < cb->end_pattern) goto NORMAL_CHAR;   /* Zero data character */
-    /* Fall through */
-
-    case CHAR_VERTICAL_LINE:
-    case CHAR_RIGHT_PARENTHESIS:
-    *firstcuptr = firstcu;
-    *firstcuflagsptr = firstcuflags;
-    *reqcuptr = reqcu;
-    *reqcuflagsptr = reqcuflags;
-    *codeptr = code;
-    *ptrptr = ptr;
-    if (lengthptr != NULL)
-      {
-      if (OFLOW_MAX - *lengthptr < (size_t)(code - last_code))
-        {
-        *errorcodeptr = ERR20;
-        goto FAILED;
-        }
-      *lengthptr += (size_t)(code - last_code);  /* To include callout length */
-      }
-    return TRUE;
-
-
-    /* ===================================================================*/
-    /* Handle single-character metacharacters. In multiline mode, ^ disables
-    the setting of any following char as a first character. */
-
-    case CHAR_CIRCUMFLEX_ACCENT:
-    previous = NULL;
-    if ((options & PCRE2_MULTILINE) != 0)
-      {
-      if (firstcuflags == REQ_UNSET)
-        zerofirstcuflags = firstcuflags = REQ_NONE;
-      *code++ = OP_CIRCM;
-      }
-    else *code++ = OP_CIRC;
-    break;
-
-    case CHAR_DOLLAR_SIGN:
-    previous = NULL;
-    *code++ = ((options & PCRE2_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
-    break;
-
-    /* There can never be a first char if '.' is first, whatever happens about
-    repeats. The value of reqcu doesn't change either. */
-
-    case CHAR_DOT:
-    if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
-    zerofirstcu = firstcu;
-    zerofirstcuflags = firstcuflags;
-    zeroreqcu = reqcu;
-    zeroreqcuflags = reqcuflags;
-    previous = code;
-    *code++ = ((options & PCRE2_DOTALL) != 0)? OP_ALLANY: OP_ANY;
-    break;
-
-
-    /* ===================================================================*/
-    /* Character classes. If the included characters are all < 256, we build a
-    32-byte bitmap of the permitted characters, except in the special case
-    where there is only one such character. For negated classes, we build the
-    map as usual, then invert it at the end. However, we use a different opcode
-    so that data characters > 255 can be handled correctly.
-
-    If the class contains characters outside the 0-255 range, a different
-    opcode is compiled. It may optionally have a bit map for characters < 256,
-    but those above are are explicitly listed afterwards. A flag byte tells
-    whether the bitmap is present, and whether this is a negated class or not.
-
-    An isolated ']' character is not treated specially, so is just another data
-    character. In earlier versions of PCRE that used the original API there was
-    a "JavaScript compatibility mode" in which it gave an error. However,
-    JavaScript itself has changed in this respect so there is no longer any
-    need for this special handling.
-
-    In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
-    used for "start of word" and "end of word". As these are otherwise illegal
-    sequences, we don't break anything by recognizing them. They are replaced
-    by \b(?=\w) and \b(?<=\w) respectively. This can only happen at the top
-    nesting level, as no other inserted sequences will contains these oddities.
-    Sequences like [a[:<:]] are erroneous and are handled by the normal code
-    below. */
-
-    case CHAR_LEFT_SQUARE_BRACKET:
-    if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0)
-      {
-      cb->nestptr[0] = ptr + 7;
-      ptr = sub_start_of_word;
-      goto REDO_LOOP;
-      }
-
-    if (PRIV(strncmp_c8)(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0)
-      {
-      cb->nestptr[0] = ptr + 7;
-      ptr = sub_end_of_word;
-      goto REDO_LOOP;
-      }
-
-    /* Handle a real character class. */
-
-    previous = code;
-
-    /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
-    they are encountered at the top level, so we'll do that too. */
-
-    if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
-         ptr[1] == CHAR_EQUALS_SIGN) &&
-        check_posix_syntax(ptr, &tempptr))
-      {
-      *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR12 : ERR13;
-      goto FAILED;
-      }
-
-    /* If the first character is '^', set the negation flag and skip it. Also,
-    if the first few characters (either before or after ^) are \Q\E or \E we
-    skip them too. This makes for compatibility with Perl. */
-
-    negate_class = FALSE;
-    for (;;)
-      {
-      c = *(++ptr);
-      if (c == CHAR_BACKSLASH)
-        {
-        if (ptr[1] == CHAR_E)
-          ptr++;
-        else if (PRIV(strncmp_c8)(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0)
-          ptr += 3;
-        else
-          break;
-        }
-      else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
-        negate_class = TRUE;
-      else break;
-      }
-
-    /* Empty classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set. Otherwise,
-    an initial ']' is taken as a data character -- the code below handles
-    that. When empty classes are allowed, [] must always fail, so generate
-    OP_FAIL, whereas [^] must match any character, so generate OP_ALLANY. */
-
-    if (c == CHAR_RIGHT_SQUARE_BRACKET &&
-        (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0)
-      {
-      *code++ = negate_class? OP_ALLANY : OP_FAIL;
-      if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
-      zerofirstcu = firstcu;
-      zerofirstcuflags = firstcuflags;
-      break;
-      }
-
-    /* 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 256
-    character with a code point less than 256; class_one_char will be 1 if the
-    class contains just one character; xclass_has_prop will be TRUE if Unicode
-    property checks are present in the class. */
-
-    class_has_8bitchar = 0;
-    class_one_char = 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 characters until ] is reached. As the test is at the end of the
-    loop, an initial ] is taken as a data character. At the start of the loop,
-    c contains the first code unit of the character. If it is zero, check for
-    the end of the pattern, to allow binary zero as data. */
-
-    for(;;)
-      {
-      PCRE2_SPTR oldptr;
-#ifdef EBCDIC
-      BOOL range_is_literal = TRUE;
-#endif
-
-      if (c == CHAR_NULL && ptr >= cb->end_pattern)
-        {
-        *errorcodeptr = ERR6;  /* Missing terminating ']' */
-        goto FAILED;
-        }
-
-#ifdef SUPPORT_UNICODE
-      if (utf && HAS_EXTRALEN(c))
-        {                           /* Braces are required because the */
-        GETCHARLEN(c, ptr, ptr);    /* macro generates multiple statements */
-        }
-#endif
-
-      /* Inside \Q...\E everything is literal except \E */
-
-      if (inescq)
-        {
-        if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)  /* If we are at \E */
-          {
-          inescq = FALSE;                   /* Reset literal state */
-          ptr++;                            /* Skip the 'E' */
-          goto CONTINUE_CLASS;              /* Carry on with next char */
-          }
-        goto CHECK_RANGE;                   /* Could be range if \E follows */
-        }
-
-      /* Handle POSIX class names. Perl allows a negation extension of the
-      form [:^name:]. A square bracket that doesn't match the syntax is
-      treated as a literal. We also recognize the POSIX constructions
-      [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
-      5.6 and 5.8 do. */
-
-      if (c == CHAR_LEFT_SQUARE_BRACKET &&
-          (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
-           ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
-        {
-        BOOL local_negate = FALSE;
-        int posix_class, taboffset, tabopt;
-        register const uint8_t *cbits = cb->cbits;
-        uint8_t pbits[32];
-
-        if (ptr[1] != CHAR_COLON)
-          {
-          *errorcodeptr = ERR13;
-          goto FAILED;
-          }
-
-        ptr += 2;
-        if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
-          {
-          local_negate = TRUE;
-          should_flip_negation = TRUE;  /* Note negative special */
-          ptr++;
-          }
-
-        posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
-        if (posix_class < 0)
-          {
-          *errorcodeptr = ERR30;
-          goto FAILED;
-          }
-
-        /* 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 generate XCL_PROP/XCL_NOTPROP
-        directly. UCP support is not available unless UTF support is.*/
-
-#ifdef SUPPORT_UNICODE
-        if ((options & PCRE2_UCP) != 0)
-          {
-          unsigned int ptype = 0;
-          int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0);
-
-          /* The posix_substitutes table specifies which POSIX classes can be
-          converted to \p or \P items. This can only happen at top nestling
-          level, as there will never be a POSIX class in a string that is
-          substituted for something else. */
-
-          if (posix_substitutes[pc] != NULL)
-            {
-            cb->nestptr[0] = tempptr + 1;
-            ptr = posix_substitutes[pc] - 1;
-            goto CONTINUE_CLASS;
-            }
-
-          /* There are three other classes that generate special property calls
-          that are recognized only in an XCLASS. */
-
-          else switch(posix_class)
-            {
-            case PC_GRAPH:
-            ptype = PT_PXGRAPH;
-            /* Fall through */
-            case PC_PRINT:
-            if (ptype == 0) ptype = PT_PXPRINT;
-            /* Fall through */
-            case PC_PUNCT:
-            if (ptype == 0) ptype = PT_PXPUNCT;
-            *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;
-            *class_uchardata++ = (PCRE2_UCHAR)ptype;
-            *class_uchardata++ = 0;
-            xclass_has_prop = TRUE;
-            ptr = tempptr + 1;
-            goto CONTINUE_CLASS;
-
-            /* For the other POSIX classes (ascii, xdigit) 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 [^[:^xdigit:]... 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. */
-
-            default:
-            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 (c = 0; c < 32; c++) pbits[c] |= cbits[(int)c + taboffset];
-          else
-            for (c = 0; c < 32; c++) pbits[c] &= ~cbits[(int)c + 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 (c = 0; c < 32; c++) classbits[c] |= ~pbits[c];
-        else
-          for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
-
-        ptr = tempptr + 1;
-        /* Every class contains at least one < 256 character. */
-        class_has_8bitchar = 1;
-        /* Every class contains at least two characters. */
-        class_one_char = 2;
-        goto CONTINUE_CLASS;    /* End of POSIX syntax handling */
-        }
-
-      /* Backslash may introduce a single character, or it may introduce one
-      of the specials, which just set a flag. The sequence \b is a special
-      case. Inside a class (and only there) it is treated as backspace. We
-      assume that other escapes have more than one character in them, so
-      speculatively set both class_has_8bitchar and class_one_char bigger
-      than one. Unrecognized escapes fall through and are faulted. */
-
-      if (c == CHAR_BACKSLASH)
-        {
-        escape = PRIV(check_escape)(&ptr, cb->end_pattern, &ec, errorcodeptr,
-          options, TRUE, cb);
-        if (*errorcodeptr != 0) goto FAILED;
-        if (escape == 0)    /* Escaped single char */
-          {
-          c = ec;
-#ifdef EBCDIC
-          range_is_literal = FALSE;
-#endif
-          }
-        else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
-        else if (escape == ESC_N)          /* \N is not supported in a class */
-          {
-          *errorcodeptr = ERR71;
-          goto FAILED;
-          }
-        else if (escape == ESC_Q)            /* Handle start of quoted string */
-          {
-          if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
-            {
-            ptr += 2; /* avoid empty string */
-            }
-          else inescq = TRUE;
-          goto CONTINUE_CLASS;
-          }
-        else if (escape == ESC_E) goto CONTINUE_CLASS;  /* Ignore orphan \E */
-
-        else  /* Handle \d-type escapes */
-          {
-          register const uint8_t *cbits = cb->cbits;
-          /* Every class contains at least two < 256 characters. */
-          class_has_8bitchar++;
-          /* Every class contains at least two characters. */
-          class_one_char += 2;
-
-          switch (escape)
-            {
-#ifdef SUPPORT_UNICODE
-            case ESC_du:     /* These are the values given for \d etc */
-            case ESC_DU:     /* when PCRE2_UCP is set. We replace the */
-            case ESC_wu:     /* escape sequence with an appropriate \p */
-            case ESC_WU:     /* or \P to test Unicode properties instead */
-            case ESC_su:     /* of the default ASCII testing. This might be */
-            case ESC_SU:     /* a 2nd-level nesting for [[:<:]] or [[:>:]]. */
-            cb->nestptr[1] = cb->nestptr[0];
-            cb->nestptr[0] = ptr;
-            ptr = substitutes[escape - ESC_DU] - 1;  /* Just before substitute */
-            class_has_8bitchar--;                /* Undo! */
-            break;
-#endif
-            case ESC_d:
-            for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit];
-            break;
-
-            case ESC_D:
-            should_flip_negation = TRUE;
-            for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit];
-            break;
-
-            case ESC_w:
-            for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word];
-            break;
-
-            case ESC_W:
-            should_flip_negation = TRUE;
-            for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+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 (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
-            break;
-
-            case ESC_S:
-            should_flip_negation = TRUE;
-            for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
-            break;
-
-            /* The rest apply in both UCP and non-UCP cases. */
-
-            case ESC_h:
-            (void)add_list_to_class(classbits, &class_uchardata, options, cb,
-              PRIV(hspace_list), NOTACHAR);
-            break;
-
-            case ESC_H:
-            (void)add_not_list_to_class(classbits, &class_uchardata, options,
-              cb, PRIV(hspace_list));
-            break;
-
-            case ESC_v:
-            (void)add_list_to_class(classbits, &class_uchardata, options, cb,
-              PRIV(vspace_list), NOTACHAR);
-            break;
-
-            case ESC_V:
-            (void)add_not_list_to_class(classbits, &class_uchardata, options,
-              cb, PRIV(vspace_list));
-            break;
-
-            case ESC_p:
-            case ESC_P:
-#ifdef SUPPORT_UNICODE
-              {
-              BOOL negated;
-              unsigned int ptype = 0, pdata = 0;
-              if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr, cb))
-                goto FAILED;
-              *class_uchardata++ = ((escape == ESC_p) != negated)?
-                XCL_PROP : XCL_NOTPROP;
-              *class_uchardata++ = ptype;
-              *class_uchardata++ = pdata;
-              xclass_has_prop = TRUE;
-              class_has_8bitchar--;                /* Undo! */
-              }
-            break;
-#else
-            *errorcodeptr = ERR45;
-            goto FAILED;
-#endif
-            /* Unrecognized escapes are faulted. */
-
-            default:
-            *errorcodeptr = ERR7;
-            goto FAILED;
-            }
-
-          /* Handled \d-type escape */
-
-          goto CONTINUE_CLASS;
-          }
-
-        /* Control gets here if the escape just defined a single character.
-        This is in c and may be greater than 256. */
-
-        escape = 0;
-        }   /* End of backslash handling */
-
-      /* A character may be followed by '-' to form a range. However, Perl does
-      not permit ']' to be the end of the range. A '-' character at the end is
-      treated as a literal. Perl ignores orphaned \E sequences entirely. The
-      code for handling \Q and \E is messy. */
-
-      CHECK_RANGE:
-      while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
-        {
-        inescq = FALSE;
-        ptr += 2;
-        }
-      oldptr = ptr;
-
-      /* Remember if \r or \n were explicitly used */
-
-      if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF;
-
-      /* Check for range */
-
-      if (!inescq && ptr[1] == CHAR_MINUS)
-        {
-        uint32_t d;
-        ptr += 2;
-        while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2;
-
-        /* If we hit \Q (not followed by \E) at this point, go into escaped
-        mode. */
-
-        while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
-          {
-          ptr += 2;
-          if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)
-            { ptr += 2; continue; }
-          inescq = TRUE;
-          break;
-          }
-
-        /* Minus (hyphen) at the end of a class is treated as a literal, so put
-        back the pointer and jump to handle the character that preceded it. */
-
-        if (*ptr == CHAR_NULL || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET))
-          {
-          ptr = oldptr;
-          goto CLASS_SINGLE_CHARACTER;
-          }
-
-        /* Otherwise, we have a potential range; pick up the next character */
-
-#ifdef SUPPORT_UNICODE
-        if (utf)
-          {                           /* Braces are required because the */
-          GETCHARLEN(d, ptr, ptr);    /* macro generates multiple statements */
-          }
-        else
-#endif
-        d = *ptr;  /* Not UTF mode */
-
-        /* The second part of a range can be a single-character escape
-        sequence, 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 (!inescq)
-          {
-          if (d == CHAR_BACKSLASH)
-            {
-            int descape;
-            descape = PRIV(check_escape)(&ptr, cb->end_pattern, &d,
-              errorcodeptr, options, TRUE, cb);
-            if (*errorcodeptr != 0) goto FAILED;
-#ifdef EBCDIC
-            range_is_literal = FALSE;
-#endif
-            /* 0 means a character was put into d; \b is backspace; any other
-            special causes an error. */
-
-            if (descape != 0)
-              {
-              if (descape == ESC_b) d = CHAR_BS; else
-                {
-                *errorcodeptr = ERR50;
-                goto FAILED;
-                }
-              }
-            }
-
-          /* A hyphen followed by a POSIX class is treated in the same way. */
-
-          else if (d == CHAR_LEFT_SQUARE_BRACKET &&
-                   (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
-                    ptr[1] == CHAR_EQUALS_SIGN) &&
-                   check_posix_syntax(ptr, &tempptr))
-            {
-            *errorcodeptr = ERR50;
-            goto FAILED;
-            }
-          }
-
-        /* Check that the two values are in the correct order. Optimize
-        one-character ranges. */
-
-        if (d < c)
-          {
-          *errorcodeptr = ERR8;
-          goto FAILED;
-          }
-        if (d == c) goto CLASS_SINGLE_CHARACTER;  /* A few lines below */
-
-        /* We have found a character range, so single character optimizations
-        cannot be done anymore. Any value greater than 1 indicates that there
-        is more than one character. */
-
-        class_one_char = 2;
-
-        /* 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 = (c <= 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, 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, 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, cb, C + uc,
-                D + uc);
-            }
-          }
-        else
-#endif
-        class_has_8bitchar +=
-          add_to_class(classbits, &class_uchardata, options, cb, c, d);
-        goto CONTINUE_CLASS;   /* Go get the next char in the class */
-        }
-
-      /* Handle a single character - we can get here for a normal non-escape
-      char, or after \ that introduces a single character or for an apparent
-      range that isn't. Only the value 1 matters for class_one_char, so don't
-      increase it if it is already 2 or more ... just in case there's a class
-      with a zillion characters in it. */
-
-      CLASS_SINGLE_CHARACTER:
-      if (class_one_char < 2) class_one_char++;
-
-      /* If class_one_char is 1 and xclass_has_prop is false, we have the first
-      single character in the class, and there have been no prior ranges, or
-      XCLASS items generated by escapes. If this is the final character in the
-      class, we can optimize by turning the item into a 1-character OP_CHAR[I]
-      if it's positive, or OP_NOT[I] if it's negative. In the positive case, it
-      can cause firstcu to be set. Otherwise, there can be no first char if
-      this item is first, whatever repeat count may follow. In the case of
-      reqcu, save the previous value for reinstating. */
-
-      if (!inescq &&
-#ifdef SUPPORT_UNICODE
-          !xclass_has_prop &&
-#endif
-          class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
-        {
-        ptr++;
-        zeroreqcu = reqcu;
-        zeroreqcuflags = reqcuflags;
-
-        if (negate_class)
-          {
-#ifdef SUPPORT_UNICODE
-          int d;
-#endif
-          if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
-          zerofirstcu = firstcu;
-          zerofirstcuflags = firstcuflags;
-
-          /* For caseless UTF mode, check whether this character has more than
-          one other case. If so, generate a special OP_NOTPROP item instead of
-          OP_NOTI. */
-
-#ifdef SUPPORT_UNICODE
-          if (utf && (options & PCRE2_CASELESS) != 0 &&
-              (d = UCD_CASESET(c)) != 0)
-            {
-            *code++ = OP_NOTPROP;
-            *code++ = PT_CLIST;
-            *code++ = d;
-            }
-          else
-#endif
-          /* Char has only one other case, or UCP not available */
-
-            {
-            *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT;
-            code += PUTCHAR(c, code);
-            }
-
-          /* We are finished with this character class */
-
-          goto END_CLASS;
-          }
-
-        /* For a single, positive character, get the value into mcbuffer, and
-        then we can handle this with the normal one-character code. */
-
-        mclength = PUTCHAR(c, mcbuffer);
-        goto ONE_CHAR;
-        }       /* End of 1-char optimization */
-
-      /* There is more than one character in the class, or an XCLASS item
-      has been generated. Add this character to the class. */
-
-      class_has_8bitchar +=
-        add_to_class(classbits, &class_uchardata, options, cb, c, c);
-
-      /* Continue to the next character in the class. Closing square bracket
-      not within \Q..\E ends the class. A NULL character terminates a
-      nested substitution string, but may be a data character in the main
-      pattern (tested at the start of this loop). */
-
-      CONTINUE_CLASS:
-      c = *(++ptr);
-      if (c == CHAR_NULL && cb->nestptr[0] != NULL)
-        {
-        ptr = cb->nestptr[0];
-        cb->nestptr[0] = cb->nestptr[1];
-        cb->nestptr[1] = NULL;
-        c = *(++ptr);
-        }
-
-#ifdef SUPPORT_WIDE_CHARS
-      /* If any wide characters have been encountered, set xclass = TRUE. Then,
-      in the pre-compile phase, accumulate the length of the wide characters
-      and reset the pointer. This is so that very large classes that contain a
-      zillion wide characters do not overwrite the work space (which is on the
-      stack). */
-
-      if (class_uchardata > class_uchardata_base)
-        {
-        xclass = TRUE;
-        if (lengthptr != NULL)
-          {
-          *lengthptr += class_uchardata - class_uchardata_base;
-          class_uchardata = class_uchardata_base;
-          }
-        }
-#endif
-      /* An unescaped ] ends the class */
-
-      if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break;
-      }   /* End of main class-processing loop */
-
-    /* If this 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;
-
-    /* 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 ([:^ascii:] or
-    [^:xdigit:]) 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.
-
-    If, when generating an xclass, there are no characters < 256, we can omit
-    the bitmap in the actual compiled code. */
-
-#ifdef SUPPORT_WIDE_CHARS
-#ifdef SUPPORT_UNICODE
-    if (xclass && (xclass_has_prop || !should_flip_negation ||
-         (options & PCRE2_UCP) != 0))
-#elif PCRE2_CODE_UNIT_WIDTH != 8
-    if (xclass && (xclass_has_prop || !should_flip_negation))
-#endif
-      {
-      if (match_all_or_no_wide_chars)
-        {
-        *class_uchardata++ = XCL_RANGE;
-        class_uchardata += PRIV(ord2utf)(0x100, class_uchardata);
-        class_uchardata += PRIV(ord2utf)(MAX_UTF_CODE_POINT, class_uchardata);
-        }
-      *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;
-        memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,
-          CU2BYTES(class_uchardata - code));
-        if (negate_class && !xclass_has_prop)
-          for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
-        memcpy(code, classbits, 32);
-        code = class_uchardata + (32 / sizeof(PCRE2_UCHAR));
-        }
-      else code = class_uchardata;
-
-      /* Now fill in the complete length of the item */
-
-      PUT(previous, 1, (int)(code - previous));
-      break;   /* End of class handling */
-      }
-#endif
-
-    /* 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. */
-
-    *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
-    if (lengthptr == NULL)    /* Save time in the pre-compile phase */
-      {
-      if (negate_class)
-        for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
-      memcpy(code, classbits, 32);
-      }
-    code += 32 / sizeof(PCRE2_UCHAR);
-
-    END_CLASS:
-    break;
-
-
-    /* ===================================================================*/
-    /* Various kinds of repeat; '{' is not necessarily a quantifier, but this
-    has been tested above. */
-
-    case CHAR_LEFT_CURLY_BRACKET:
-    if (!is_quantifier) goto NORMAL_CHAR;
-    ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr);
-    if (*errorcodeptr != 0) goto FAILED;
-    goto REPEAT;
-
-    case CHAR_ASTERISK:
-    repeat_min = 0;
-    repeat_max = -1;
-    goto REPEAT;
-
-    case CHAR_PLUS:
-    repeat_min = 1;
-    repeat_max = -1;
-    goto REPEAT;
-
-    case CHAR_QUESTION_MARK:
-    repeat_min = 0;
-    repeat_max = 1;
-
-    REPEAT:
-    if (previous == NULL)
-      {
-      *errorcodeptr = ERR9;
-      goto FAILED;
-      }
-
-    if (repeat_min == 0)
-      {
-      firstcu = zerofirstcu;    /* Adjust for zero repeat */
-      firstcuflags = zerofirstcuflags;
-      reqcu = zeroreqcu;        /* Ditto */
-      reqcuflags = zeroreqcuflags;
-      }
-
-    /* Remember whether this is a variable length repeat */
-
-    reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
-
-    op_type = 0;                    /* Default single-char op codes */
-    possessive_quantifier = FALSE;  /* Default not possessive quantifier */
-
-    /* Save start of previous item, in case we have to move it up in order to
-    insert something before it. */
-
-    tempcode = previous;
-
-    /* Before checking for a possessive quantifier, we must skip over
-    whitespace and comments in extended mode because Perl allows white space at
-    this point. */
-
-    if ((options & PCRE2_EXTENDED) != 0)
-      {
-      ptr++;
-      for (;;)
-        {
-        while (MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_space) != 0) ptr++;
-        if (*ptr != CHAR_NUMBER_SIGN) break;
-        ptr++;
-        while (ptr < cb->end_pattern)
-          {
-          if (IS_NEWLINE(ptr))         /* For non-fixed-length newline cases, */
-            {                        /* IS_NEWLINE sets cb->nllen. */
-            ptr += cb->nllen;
-            break;
-            }
-          ptr++;
-#ifdef SUPPORT_UNICODE
-          if (utf) FORWARDCHAR(ptr);
-#endif
-          }           /* Loop for comment characters */
-        }             /* Loop for multiple comments */
-      ptr--;          /* Last code unit of previous character. */
-      }
-
-    /* If the next character is '+', we have a possessive quantifier. This
-    implies greediness, whatever the setting of the PCRE2_UNGREEDY option.
-    If the next character is '?' this is a minimizing repeat, by default,
-    but if PCRE2_UNGREEDY is set, it works the other way round. We change the
-    repeat type to the non-default. */
-
-    if (ptr[1] == CHAR_PLUS)
-      {
-      repeat_type = 0;                  /* Force greedy */
-      possessive_quantifier = TRUE;
-      ptr++;
-      }
-    else if (ptr[1] == CHAR_QUESTION_MARK)
-      {
-      repeat_type = greedy_non_default;
-      ptr++;
-      }
-    else repeat_type = greedy_default;
-
-    /* If the repeat is {1} we can ignore it. */
-
-    if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
-
-    /* If previous was a recursion call, wrap it in atomic brackets so that
-    previous becomes the atomic group. All recursions were so wrapped in the
-    past, but it no longer happens for non-repeated recursions. In fact, the
-    repeated ones could be re-implemented independently so as not to need this,
-    but for the moment we rely on the code for repeating groups. */
-
-    if (*previous == OP_RECURSE)
-      {
-      memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE));
-      *previous = OP_ONCE;
-      PUT(previous, 1, 2 + 2*LINK_SIZE);
-      previous[2 + 2*LINK_SIZE] = OP_KET;
-      PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
-      code += 2 + 2 * LINK_SIZE;
-      length_prevgroup = 3 + 3*LINK_SIZE;
-      }
-
-    /* Now handle repetition for the different types of item. */
-
-    /* If previous was a character or negated character match, abolish the item
-    and generate a repeat item instead. If a char item has a minimum of more
-    than one, ensure that it is set in reqcu - it might not be if a sequence
-    such as x{3} is the first thing in a branch because the x will have gone
-    into firstcu instead.  */
-
-    if (*previous == OP_CHAR || *previous == OP_CHARI
-        || *previous == OP_NOT || *previous == OP_NOTI)
-      {
-      switch (*previous)
-        {
-        default: /* Make compiler happy. */
-        case OP_CHAR:  op_type = OP_STAR - OP_STAR; break;
-        case OP_CHARI: op_type = OP_STARI - OP_STAR; break;
-        case OP_NOT:   op_type = OP_NOTSTAR - OP_STAR; break;
-        case OP_NOTI:  op_type = OP_NOTSTARI - OP_STAR; break;
-        }
-
-      /* Deal with UTF characters that take up more than one code unit. It's
-      easier to write this out separately than try to macrify it. Use c to
-      hold the length of the character in code units, plus UTF_LENGTH to flag
-      that it's a length rather than a small character. */
-
-#ifdef MAYBE_UTF_MULTI
-      if (utf && NOT_FIRSTCU(code[-1]))
-        {
-        PCRE2_UCHAR *lastchar = code - 1;
-        BACKCHAR(lastchar);
-        c = (int)(code - lastchar);               /* Length of UTF character */
-        memcpy(utf_units, lastchar, CU2BYTES(c)); /* Save the char */
-        c |= UTF_LENGTH;                          /* Flag c as a length */
-        }
-      else
-#endif  /* MAYBE_UTF_MULTI */
-
-      /* Handle the case of a single charater - either with no UTF support, or
-      with UTF disabled, or for a single-code-unit UTF character. */
-        {
-        c = code[-1];
-        if (*previous <= OP_CHARI && repeat_min > 1)
-          {
-          reqcu = c;
-          reqcuflags = req_caseopt | cb->req_varyopt;
-          }
-        }
-
-      goto OUTPUT_SINGLE_REPEAT;   /* Code shared with single character types */
-      }
-
-    /* If previous was a character type match (\d or similar), abolish it and
-    create a suitable repeat item. The code is shared with single-character
-    repeats by setting op_type to add a suitable offset into repeat_type. Note
-    the the Unicode property types will be present only when SUPPORT_UNICODE is
-    defined, but we don't wrap the little bits of code here because it just
-    makes it horribly messy. */
-
-    else if (*previous < OP_EODN)
-      {
-      PCRE2_UCHAR *oldcode;
-      int prop_type, prop_value;
-      op_type = OP_TYPESTAR - OP_STAR;      /* Use type opcodes */
-      c = *previous;                        /* Save previous opcode */
-      if (c == OP_PROP || c == OP_NOTPROP)
-        {
-        prop_type = previous[1];
-        prop_value = previous[2];
-        }
-      else
-        {
-        /* Come here from just above with a character in c */
-        OUTPUT_SINGLE_REPEAT:
-        prop_type = prop_value = -1;
-        }
-
-      /* At this point we either have prop_type == prop_value == -1 and either
-      a code point or a character type that is not OP_[NOT]PROP in c, or we
-      have OP_[NOT]PROP in c and prop_type/prop_value not negative. */
-
-      oldcode = code;                   /* Save where we were */
-      code = previous;                  /* Usually overwrite previous item */
-
-      /* If the maximum is zero then the minimum must also be zero; Perl allows
-      this case, so we do too - by simply omitting the item altogether. */
-
-      if (repeat_max == 0) goto END_REPEAT;
-
-      /* Combine the op_type with the repeat_type */
-
-      repeat_type += op_type;
-
-      /* A minimum of zero is handled either as the special case * or ?, or as
-      an UPTO, with the maximum given. */
-
-      if (repeat_min == 0)
-        {
-        if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
-          else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
-        else
-          {
-          *code++ = OP_UPTO + repeat_type;
-          PUT2INC(code, 0, repeat_max);
-          }
-        }
-
-      /* A repeat minimum of 1 is optimized into some special cases. If the
-      maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
-      left in place and, if the maximum is greater than 1, we use OP_UPTO with
-      one less than the maximum. */
-
-      else if (repeat_min == 1)
-        {
-        if (repeat_max == -1)
-          *code++ = OP_PLUS + repeat_type;
-        else
-          {
-          code = oldcode;                 /* Leave previous item in place */
-          if (repeat_max == 1) goto END_REPEAT;
-          *code++ = OP_UPTO + repeat_type;
-          PUT2INC(code, 0, repeat_max - 1);
-          }
-        }
-
-      /* The case {n,n} is just an EXACT, while the general case {n,m} is
-      handled as an EXACT followed by an UPTO or STAR or QUERY. */
-
-      else
-        {
-        *code++ = OP_EXACT + op_type;  /* NB EXACT doesn't have repeat_type */
-        PUT2INC(code, 0, repeat_min);
-
-        /* Unless repeat_max equals repeat_min, fill in the data for EXACT, and
-        then generate the second opcode. In UTF mode, multi-code-unit
-        characters have their length in c, with the UTF_LENGTH bit as a flag,
-        and the code units in utf_units. For a repeated Unicode property match,
-        there are two extra values that define the required property, and c
-        never has the UTF_LENGTH bit set. */
-
-        if (repeat_max != repeat_min)
-          {
-#ifdef MAYBE_UTF_MULTI
-          if (utf && (c & UTF_LENGTH) != 0)
-            {
-            memcpy(code, utf_units, CU2BYTES(c & 7));
-            code += c & 7;
-            }
-          else
-#endif  /* MAYBE_UTF_MULTI */
-            {
-            *code++ = c;
-            if (prop_type >= 0)
-              {
-              *code++ = prop_type;
-              *code++ = prop_value;
-              }
-            }
-
-          /* Now set up the following opcode */
-
-          if (repeat_max < 0) *code++ = OP_STAR + repeat_type; else
-            {
-            repeat_max -= repeat_min;
-            if (repeat_max == 1)
-              {
-              *code++ = OP_QUERY + repeat_type;
-              }
-            else
-              {
-              *code++ = OP_UPTO + repeat_type;
-              PUT2INC(code, 0, repeat_max);
-              }
-            }
-          }
-        }
-
-      /* Fill in the character or character type for the final opcode. */
-
-#ifdef MAYBE_UTF_MULTI
-      if (utf && (c & UTF_LENGTH) != 0)
-        {
-        memcpy(code, utf_units, CU2BYTES(c & 7));
-        code += c & 7;
-        }
-      else
-#endif  /* MAYBEW_UTF_MULTI */
-        {
-        *code++ = c;
-        if (prop_type >= 0)
-          {
-          *code++ = prop_type;
-          *code++ = prop_value;
-          }
-        }
-      }
-
-    /* If previous was a character class or a back reference, we put the repeat
-    stuff after it, but just skip the item if the repeat was {0,0}. */
-
-    else if (*previous == OP_CLASS || *previous == OP_NCLASS ||
-#ifdef SUPPORT_WIDE_CHARS
-             *previous == OP_XCLASS ||
-#endif
-             *previous == OP_REF   || *previous == OP_REFI ||
-             *previous == OP_DNREF || *previous == OP_DNREFI)
-      {
-      if (repeat_max == 0)
-        {
-        code = previous;
-        goto END_REPEAT;
-        }
-
-      if (repeat_min == 0 && repeat_max == -1)
-        *code++ = OP_CRSTAR + repeat_type;
-      else if (repeat_min == 1 && repeat_max == -1)
-        *code++ = OP_CRPLUS + repeat_type;
-      else if (repeat_min == 0 && repeat_max == 1)
-        *code++ = OP_CRQUERY + repeat_type;
-      else
-        {
-        *code++ = OP_CRRANGE + repeat_type;
-        PUT2INC(code, 0, repeat_min);
-        if (repeat_max == -1) repeat_max = 0;  /* 2-byte encoding for max */
-        PUT2INC(code, 0, repeat_max);
-        }
-      }
-
-    /* If previous was a bracket group, we may have to replicate it in certain
-    cases. Note that at this point we can encounter only the "basic" bracket
-    opcodes such as BRA and CBRA, as this is the place where they get converted
-    into the more special varieties such as BRAPOS and SBRA. A test for >=
-    OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK,
-    ASSERTBACK_NOT, ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND.
-    Originally, PCRE did not allow repetition of assertions, but now it does,
-    for Perl compatibility. */
-
-    else if (*previous >= OP_ASSERT && *previous <= OP_COND)
-      {
-      register int i;
-      int len = (int)(code - previous);
-      PCRE2_UCHAR *bralink = NULL;
-      PCRE2_UCHAR *brazeroptr = NULL;
-
-      /* Repeating a DEFINE group (or any group where the condition is always
-      FALSE and there is only one branch) is pointless, but Perl allows the
-      syntax, so we just ignore the repeat. */
-
-      if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_FALSE &&
-          previous[GET(previous, 1)] != OP_ALT)
-        goto END_REPEAT;
-
-      /* There is no sense in actually repeating assertions. The only potential
-      use of repetition is in cases when the assertion is optional. Therefore,
-      if the minimum is greater than zero, just ignore the repeat. If the
-      maximum is not zero or one, set it to 1. */
-
-      if (*previous < OP_ONCE)    /* Assertion */
-        {
-        if (repeat_min > 0) goto END_REPEAT;
-        if (repeat_max < 0 || repeat_max > 1) repeat_max = 1;
-        }
-
-      /* The case of a zero minimum is special because of the need to stick
-      OP_BRAZERO in front of it, and because the group appears once in the
-      data, whereas in other cases it appears the minimum number of times. For
-      this reason, it is simplest to treat this case separately, as otherwise
-      the code gets far too messy. There are several special subcases when the
-      minimum is zero. */
-
-      if (repeat_min == 0)
-        {
-        /* If the maximum is also zero, we used to just omit the group from the
-        output altogether, like this:
-
-        ** if (repeat_max == 0)
-        **   {
-        **   code = previous;
-        **   goto END_REPEAT;
-        **   }
-
-        However, that fails when a group or a subgroup within it is referenced
-        as a subroutine from elsewhere in the pattern, so now we stick in
-        OP_SKIPZERO in front of it so that it is skipped on execution. As we
-        don't have a list of which groups are referenced, we cannot do this
-        selectively.
-
-        If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
-        and do no more at this point. */
-
-        if (repeat_max <= 1)    /* Covers 0, 1, and unlimited */
-          {
-          memmove(previous + 1, previous, CU2BYTES(len));
-          code++;
-          if (repeat_max == 0)
-            {
-            *previous++ = OP_SKIPZERO;
-            goto END_REPEAT;
-            }
-          brazeroptr = previous;    /* Save for possessive optimizing */
-          *previous++ = OP_BRAZERO + repeat_type;
-          }
-
-        /* If the maximum is greater than 1 and limited, we have to replicate
-        in a nested fashion, sticking OP_BRAZERO before each set of brackets.
-        The first one has to be handled carefully because it's the original
-        copy, which has to be moved up. The remainder can be handled by code
-        that is common with the non-zero minimum case below. We have to
-        adjust the value or repeat_max, since one less copy is required. */
-
-        else
-          {
-          int offset;
-          memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len));
-          code += 2 + LINK_SIZE;
-          *previous++ = OP_BRAZERO + repeat_type;
-          *previous++ = OP_BRA;
-
-          /* We chain together the bracket offset fields that have to be
-          filled in later when the ends of the brackets are reached. */
-
-          offset = (bralink == NULL)? 0 : (int)(previous - bralink);
-          bralink = previous;
-          PUTINC(previous, 0, offset);
-          }
-
-        repeat_max--;
-        }
-
-      /* If the minimum is greater than zero, replicate the group as many
-      times as necessary, and adjust the maximum to the number of subsequent
-      copies that we need. */
-
-      else
-        {
-        if (repeat_min > 1)
-          {
-          /* In the pre-compile phase, we don't actually do the replication. We
-          just adjust the length as if we had. Do some paranoid checks for
-          potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
-          integer type when available, otherwise double. */
-
-          if (lengthptr != NULL)
-            {
-            size_t delta = (repeat_min - 1)*length_prevgroup;
-            if ((INT64_OR_DOUBLE)(repeat_min - 1)*
-                  (INT64_OR_DOUBLE)length_prevgroup >
-                    (INT64_OR_DOUBLE)INT_MAX ||
-                OFLOW_MAX - *lengthptr < delta)
-              {
-              *errorcodeptr = ERR20;
-              goto FAILED;
-              }
-            *lengthptr += delta;
-            }
-
-          /* This is compiling for real. If there is a set first byte for
-          the group, and we have not yet set a "required byte", set it. */
-
-          else
-            {
-            if (groupsetfirstcu && reqcuflags < 0)
-              {
-              reqcu = firstcu;
-              reqcuflags = firstcuflags;
-              }
-            for (i = 1; i < repeat_min; i++)
-              {
-              memcpy(code, previous, CU2BYTES(len));
-              code += len;
-              }
-            }
-          }
-
-        if (repeat_max > 0) repeat_max -= repeat_min;
-        }
-
-      /* This code is common to both the zero and non-zero minimum cases. If
-      the maximum is limited, it replicates the group in a nested fashion,
-      remembering the bracket starts on a stack. In the case of a zero minimum,
-      the first one was set up above. In all cases the repeat_max now specifies
-      the number of additional copies needed. Again, we must remember to
-      replicate entries on the forward reference list. */
-
-      if (repeat_max >= 0)
-        {
-        /* In the pre-compile phase, we don't actually do the replication. We
-        just adjust the length as if we had. For each repetition we must add 1
-        to the length for BRAZERO and for all but the last repetition we must
-        add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
-        paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is
-        a 64-bit integer type when available, otherwise double. */
-
-        if (lengthptr != NULL && repeat_max > 0)
-          {
-          size_t delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
-                      2 - 2*LINK_SIZE;   /* Last one doesn't nest */
-          if ((INT64_OR_DOUBLE)repeat_max *
-                (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
-                  > (INT64_OR_DOUBLE)INT_MAX ||
-              OFLOW_MAX - *lengthptr < delta)
-            {
-            *errorcodeptr = ERR20;
-            goto FAILED;
-            }
-          *lengthptr += delta;
-          }
-
-        /* This is compiling for real */
-
-        else for (i = repeat_max - 1; i >= 0; i--)
-          {
-          *code++ = OP_BRAZERO + repeat_type;
-
-          /* All but the final copy start a new nesting, maintaining the
-          chain of brackets outstanding. */
-
-          if (i != 0)
-            {
-            int offset;
-            *code++ = OP_BRA;
-            offset = (bralink == NULL)? 0 : (int)(code - bralink);
-            bralink = code;
-            PUTINC(code, 0, offset);
-            }
-
-          memcpy(code, previous, CU2BYTES(len));
-          code += len;
-          }
-
-        /* Now chain through the pending brackets, and fill in their length
-        fields (which are holding the chain links pro tem). */
-
-        while (bralink != NULL)
-          {
-          int oldlinkoffset;
-          int offset = (int)(code - bralink + 1);
-          PCRE2_UCHAR *bra = code - offset;
-          oldlinkoffset = GET(bra, 1);
-          bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
-          *code++ = OP_KET;
-          PUTINC(code, 0, offset);
-          PUT(bra, 1, offset);
-          }
-        }
-
-      /* If the maximum is unlimited, set a repeater in the final copy. For
-      ONCE brackets, that's all we need to do. However, possessively repeated
-      ONCE brackets can be converted into non-capturing brackets, as the
-      behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
-      deal with possessive ONCEs specially.
-
-      Otherwise, when we are doing the actual compile phase, check to see
-      whether this group is one that could match an empty string. If so,
-      convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
-      that runtime checking can be done. [This check is also applied to ONCE
-      groups at runtime, but in a different way.]
-
-      Then, if the quantifier was possessive and the bracket is not a
-      conditional, we convert the BRA code to the POS form, and the KET code to
-      KETRPOS. (It turns out to be convenient at runtime to detect this kind of
-      subpattern at both the start and at the end.) The use of special opcodes
-      makes it possible to reduce greatly the stack usage in pcre2_match(). If
-      the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
-
-      Then, if the minimum number of matches is 1 or 0, cancel the possessive
-      flag so that the default action below, of wrapping everything inside
-      atomic brackets, does not happen. When the minimum is greater than 1,
-      there will be earlier copies of the group, and so we still have to wrap
-      the whole thing. */
-
-      else
-        {
-        PCRE2_UCHAR *ketcode = code - 1 - LINK_SIZE;
-        PCRE2_UCHAR *bracode = ketcode - GET(ketcode, 1);
-
-        /* Convert possessive ONCE brackets to non-capturing */
-
-        if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
-            possessive_quantifier) *bracode = OP_BRA;
-
-        /* For non-possessive ONCE brackets, all we need to do is to
-        set the KET. */
-
-        if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
-          *ketcode = OP_KETRMAX + repeat_type;
-
-        /* Handle non-ONCE brackets and possessive ONCEs (which have been
-        converted to non-capturing above). */
-
-        else
-          {
-          /* In the compile phase, check whether the group could match an empty
-          string. */
-
-          if (lengthptr == NULL)
-            {
-            PCRE2_UCHAR *scode = bracode;
-            do
-              {
-              int count = 0;
-              int rc = could_be_empty_branch(scode, ketcode, utf, cb, FALSE,
-                NULL, &count);
-              if (rc < 0)
-                {
-                *errorcodeptr = ERR86;
-                goto FAILED;
-                }
-              if (rc > 0)
-                {
-                *bracode += OP_SBRA - OP_BRA;
-                break;
-                }
-              scode += GET(scode, 1);
-              }
-            while (*scode == OP_ALT);
-
-            /* A conditional group with only one branch has an implicit empty
-            alternative branch. */
-
-            if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)
-              *bracode = OP_SCOND;
-            }
-
-          /* Handle possessive quantifiers. */
-
-          if (possessive_quantifier)
-            {
-            /* For COND brackets, we wrap the whole thing in a possessively
-            repeated non-capturing bracket, because we have not invented POS
-            versions of the COND opcodes. */
-
-            if (*bracode == OP_COND || *bracode == OP_SCOND)
-              {
-              int nlen = (int)(code - bracode);
-              memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));
-              code += 1 + LINK_SIZE;
-              nlen += 1 + LINK_SIZE;
-              *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
-              *code++ = OP_KETRPOS;
-              PUTINC(code, 0, nlen);
-              PUT(bracode, 1, nlen);
-              }
-
-            /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
-
-            else
-              {
-              *bracode += 1;              /* Switch to xxxPOS opcodes */
-              *ketcode = OP_KETRPOS;
-              }
-
-            /* If the minimum is zero, mark it as possessive, then unset the
-            possessive flag when the minimum is 0 or 1. */
-
-            if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
-            if (repeat_min < 2) possessive_quantifier = FALSE;
-            }
-
-          /* Non-possessive quantifier */
-
-          else *ketcode = OP_KETRMAX + repeat_type;
-          }
-        }
-      }
-
-    /* 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 (?!), set previous to NULL, which gives a
-    "nothing to repeat" error above. We can just ignore the repeat in empty
-    class case. */
-
-    else if (*previous == OP_FAIL) goto END_REPEAT;
-
-    /* Else there's some kind of shambles */
-
-    else
-      {
-      *errorcodeptr = ERR10;
-      goto FAILED;
-      }
-
-    /* If the character following a repeat is '+', possessive_quantifier is
-    TRUE. For some opcodes, there are special alternative opcodes for this
-    case. For anything else, we wrap the entire repeated item inside OP_ONCE
-    brackets. Logically, the '+' notation is just syntactic sugar, taken from
-    Sun's Java package, but the special opcodes can optimize it.
-
-    Some (but not all) possessively repeated subpatterns have already been
-    completely handled in the code just above. For them, possessive_quantifier
-    is always FALSE at this stage. Note that the repeated item starts at
-    tempcode, not at previous, which might be the first part of a string whose
-    (former) last char we repeated. */
-
-    if (possessive_quantifier)
-      {
-      int len;
-
-      /* Possessifying an EXACT quantifier has no effect, so we can ignore it.
-      However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6},
-      {5,}, or {5,10}). We skip over an EXACT item; if the length of what
-      remains is greater than zero, there's a further opcode that can be
-      handled. If not, do nothing, leaving the EXACT alone. */
-
-      switch(*tempcode)
-        {
-        case OP_TYPEEXACT:
-        tempcode += PRIV(OP_lengths)[*tempcode] +
-          ((tempcode[1 + IMM2_SIZE] == OP_PROP
-          || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
-        break;
-
-        /* CHAR opcodes are used for exacts whose count is 1. */
-
-        case OP_CHAR:
-        case OP_CHARI:
-        case OP_NOT:
-        case OP_NOTI:
-        case OP_EXACT:
-        case OP_EXACTI:
-        case OP_NOTEXACT:
-        case OP_NOTEXACTI:
-        tempcode += PRIV(OP_lengths)[*tempcode];
-#ifdef SUPPORT_UNICODE
-        if (utf && HAS_EXTRALEN(tempcode[-1]))
-          tempcode += GET_EXTRALEN(tempcode[-1]);
-#endif
-        break;
-
-        /* For the class opcodes, the repeat operator appears at the end;
-        adjust tempcode to point to it. */
-
-        case OP_CLASS:
-        case OP_NCLASS:
-        tempcode += 1 + 32/sizeof(PCRE2_UCHAR);
-        break;
-
-#ifdef SUPPORT_WIDE_CHARS
-        case OP_XCLASS:
-        tempcode += GET(tempcode, 1);
-        break;
-#endif
-        }
-
-      /* If tempcode is equal to code (which points to the end of the repeated
-      item), it means we have skipped an EXACT item but there is no following
-      QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In
-      all other cases, tempcode will be pointing to the repeat opcode, and will
-      be less than code, so the value of len will be greater than 0. */
-
-      len = (int)(code - tempcode);
-      if (len > 0)
-        {
-        unsigned int repcode = *tempcode;
-
-        /* There is a table for possessifying opcodes, all of which are less
-        than OP_CALLOUT. A zero entry means there is no possessified version.
-        */
-
-        if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0)
-          *tempcode = opcode_possessify[repcode];
-
-        /* For opcode without a special possessified version, wrap the item in
-        ONCE brackets. */
-
-        else
-          {
-          memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len));
-          code += 1 + LINK_SIZE;
-          len += 1 + LINK_SIZE;
-          tempcode[0] = OP_ONCE;
-          *code++ = OP_KET;
-          PUTINC(code, 0, len);
-          PUT(tempcode, 1, len);
-          }
-        }
-      }
-
-    /* In all case we no longer have a previous item. We also set the
-    "follows varying string" flag for subsequently encountered reqcus if
-    it isn't already set and we have just passed a varying length item. */
-
-    END_REPEAT:
-    previous = NULL;
-    cb->req_varyopt |= reqvary;
-    break;
-
-
-    /* ===================================================================*/
-    /* Start of nested parenthesized sub-expression, or lookahead or lookbehind
-    or option setting or condition or all the other extended parenthesis forms.
-    We must save the current high-water-mark for the forward reference list so
-    that we know where they start for this group. However, because the list may
-    be extended when there are very many forward references (usually the result
-    of a replicated inner group), we must use an offset rather than an absolute
-    address. Note that (?# comments are dealt with at the top of the loop;
-    they do not get this far. */
-
-    case CHAR_LEFT_PARENTHESIS:
-    ptr++;
-
-    /* Deal with various "verbs" that can be introduced by '*'. */
-
-    if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
-         || (MAX_255(ptr[1]) && ((cb->ctypes[ptr[1]] & ctype_letter) != 0))))
-      {
-      int i, namelen;
-      int arglen = 0;
-      const char *vn = verbnames;
-      PCRE2_SPTR name = ptr + 1;
-      PCRE2_SPTR arg = NULL;
-      previous = NULL;
-      ptr++;
-
-      /* Increment ptr, set namelen, check length */
-
-      READ_NAME(ctype_letter, ERR60, *errorcodeptr);
-
-      /* It appears that Perl allows any characters whatsoever, other than
-      a closing parenthesis, to appear in arguments, so we no longer insist on
-      letters, digits, and underscores. Perl does not, however, do any
-      interpretation within arguments, and has no means of including a closing
-      parenthesis. PCRE supports escape processing but only when it is
-      requested by an option. Note that check_escape() will not return values
-      greater than the code unit maximum when not in UTF mode. */
-
-      if (*ptr == CHAR_COLON)
-        {
-        arg = ++ptr;
-
-        if ((options & PCRE2_ALT_VERBNAMES) == 0)
-          {
-          arglen = 0;
-          while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS)
-            {
-            ptr++;                                /* Check length as we go */
-            arglen++;                             /* along, to avoid the   */
-            if ((unsigned int)arglen > MAX_MARK)  /* possibility of overflow. */
-              {
-              *errorcodeptr = ERR76;
-              goto FAILED;
-              }
-            }
-          }
-        else
-          {
-          /* The length check is in process_verb_names() */
-          arglen = process_verb_name(&ptr, NULL, errorcodeptr, options,
-            utf, cb);
-          if (arglen < 0) goto FAILED;
-          }
-        }
-
-      if (*ptr != CHAR_RIGHT_PARENTHESIS)
-        {
-        *errorcodeptr = ERR60;
-        goto FAILED;
-        }
-
-      /* Scan the table of verb names */
-
-      for (i = 0; i < verbcount; i++)
-        {
-        if (namelen == verbs[i].len &&
-            PRIV(strncmp_c8)(name, vn, namelen) == 0)
-          {
-          int setverb;
-
-          /* Check for open captures before ACCEPT and convert it to
-          ASSERT_ACCEPT if in an assertion. */
-
-          if (verbs[i].op == OP_ACCEPT)
-            {
-            open_capitem *oc;
-            if (arglen != 0)
-              {
-              *errorcodeptr = ERR59;
-              goto FAILED;
-              }
-            cb->had_accept = TRUE;
-
-            /* In the first pass, just accumulate the length required;
-            otherwise hitting (*ACCEPT) inside many nested parentheses can
-            cause workspace overflow. */
-
-            for (oc = cb->open_caps; oc != NULL; oc = oc->next)
-              {
-              if (lengthptr != NULL)
-                {
-                *lengthptr += CU2BYTES(1) + IMM2_SIZE;
-                }
-              else
-                {
-                *code++ = OP_CLOSE;
-                PUT2INC(code, 0, oc->number);
-                }
-              }
-            setverb = *code++ =
-              (cb->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
-
-            /* Do not set firstcu after *ACCEPT */
-            if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
-            }
-
-          /* Handle other cases with/without an argument */
-
-          else if (arglen == 0)    /* There is no argument */
-            {
-            if (verbs[i].op < 0)   /* Argument is mandatory */
-              {
-              *errorcodeptr = ERR66;
-              goto FAILED;
-              }
-            setverb = *code++ = verbs[i].op;
-            }
-
-          else                        /* An argument is present */
-            {
-            if (verbs[i].op_arg < 0)  /* Argument is forbidden */
-              {
-              *errorcodeptr = ERR59;
-              goto FAILED;
-              }
-            setverb = *code++ = verbs[i].op_arg;
-
-            /* Arguments can be very long, especially in 16- and 32-bit modes,
-            and can overflow the workspace in the first pass. Instead of
-            putting the argument into memory, we just update the length counter
-            and set up an empty argument. */
-
-            if (lengthptr != NULL)
-              {
-              *lengthptr += arglen;
-              *code++ = 0;
-              }
-            else
-              {
-              *code++ = arglen;
-              if ((options & PCRE2_ALT_VERBNAMES) != 0)
-                {
-                PCRE2_UCHAR *memcode = code;  /* code is "register" */
-                (void)process_verb_name(&arg, &memcode, errorcodeptr, options,
-                  utf, cb);
-                code = memcode;
-                }
-              else   /* No argument processing */
-                {
-                memcpy(code, arg, CU2BYTES(arglen));
-                code += arglen;
-                }
-              }
-
-            *code++ = 0;
-            }
-
-          switch (setverb)
-            {
-            case OP_THEN:
-            case OP_THEN_ARG:
-            cb->external_flags |= PCRE2_HASTHEN;
-            break;
-
-            case OP_PRUNE:
-            case OP_PRUNE_ARG:
-            case OP_SKIP:
-            case OP_SKIP_ARG:
-            cb->had_pruneorskip = TRUE;
-            break;
-            }
-
-          break;  /* Found verb, exit loop */
-          }
-
-        vn += verbs[i].len + 1;
-        }
-
-      if (i < verbcount) continue;    /* Successfully handled a verb */
-      *errorcodeptr = ERR60;          /* Verb not recognized */
-      goto FAILED;
-      }
-
-    /* Initialization for "real" parentheses */
-
-    newoptions = options;
-    skipunits = 0;
-    bravalue = OP_CBRA;
-    reset_bracount = FALSE;
-
-    /* Deal with the extended parentheses; all are introduced by '?', and the
-    appearance of any of them means that this is not a capturing group. */
-
-    if (*ptr == CHAR_QUESTION_MARK)
-      {
-      int i, count;
-      int namelen;                /* Must be signed */
-      uint32_t index;
-      uint32_t set, unset, *optset;
-      named_group *ng;
-      PCRE2_SPTR name;
-      PCRE2_UCHAR *slot;
-
-      switch (*(++ptr))
-        {
-        /* ------------------------------------------------------------ */
-        case CHAR_VERTICAL_LINE:  /* Reset capture count for each branch */
-        reset_bracount = TRUE;
-        /* Fall through */
-
-        /* ------------------------------------------------------------ */
-        case CHAR_COLON:          /* Non-capturing bracket */
-        bravalue = OP_BRA;
-        ptr++;
-        break;
-
-        /* ------------------------------------------------------------ */
-        case CHAR_LEFT_PARENTHESIS:
-        bravalue = OP_COND;       /* Conditional group */
-        tempptr = ptr;
-
-        /* A condition can be an assertion, a number (referring to a numbered
-        group's having been set), a name (referring to a named group), or 'R',
-        referring to recursion. R<digits> and R&name are also permitted for
-        recursion tests.
-
-        There are ways of testing a named group: (?(name)) is used by Python;
-        Perl 5.10 onwards uses (?(<name>) or (?('name')).
-
-        There is one unfortunate ambiguity, caused by history. 'R' can be the
-        recursive thing or the name 'R' (and similarly for 'R' followed by
-        digits). We look for a name first; if not found, we try the other case.
-
-        For compatibility with auto-callouts, we allow a callout to be
-        specified before a condition that is an assertion. First, check for the
-        syntax of a callout; if found, adjust the temporary pointer that is
-        used to check for an assertion condition. That's all that is needed! */
-
-        if (ptr[1] == CHAR_QUESTION_MARK && ptr[2] == CHAR_C)
-          {
-          if (IS_DIGIT(ptr[3]) || ptr[3] == CHAR_RIGHT_PARENTHESIS)
-            {
-            for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break;
-            if (ptr[i] == CHAR_RIGHT_PARENTHESIS)
-              tempptr += i + 1;
-            }
-          else
-            {
-            uint32_t delimiter = 0;
-            for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
-              {
-              if (ptr[3] == PRIV(callout_start_delims)[i])
-                {
-                delimiter = PRIV(callout_end_delims)[i];
-                break;
-                }
-              }
-            if (delimiter != 0)
-              {
-              for (i = 4; ptr + i < cb->end_pattern; i++)
-                {
-                if (ptr[i] == delimiter)
-                  {
-                  if (ptr[i+1] == delimiter) i++;
-                  else
-                    {
-                    if (ptr[i+1] == CHAR_RIGHT_PARENTHESIS) tempptr += i + 2;
-                    break;
-                    }
-                  }
-                }
-              }
-            }
-
-          /* tempptr should now be pointing to the opening parenthesis of the
-          assertion condition. */
-
-          if (*tempptr != CHAR_LEFT_PARENTHESIS)
-            {
-            *errorcodeptr = ERR28;
-            goto FAILED;
-            }
-          }
-
-        /* For conditions that are assertions, check the syntax, and then exit
-        the switch. This will take control down to where bracketed groups
-        are processed. The assertion will be handled as part of the group,
-        but we need to identify this case because the conditional assertion may
-        not be quantifier. */
-
-        if (tempptr[1] == CHAR_QUESTION_MARK &&
-              (tempptr[2] == CHAR_EQUALS_SIGN ||
-               tempptr[2] == CHAR_EXCLAMATION_MARK ||
-                 (tempptr[2] == CHAR_LESS_THAN_SIGN &&
-                   (tempptr[3] == CHAR_EQUALS_SIGN ||
-                    tempptr[3] == CHAR_EXCLAMATION_MARK))))
-          {
-          cb->iscondassert = TRUE;
-          break;
-          }
-
-        /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all
-        need to skip at least 1+IMM2_SIZE bytes at the start of the group. */
-
-        code[1+LINK_SIZE] = OP_CREF;
-        skipunits = 1+IMM2_SIZE;
-        refsign = -1;     /* => not a number */
-        namelen = -1;     /* => not a name; must set to avoid warning */
-        name = NULL;      /* Always set to avoid warning */
-        recno = 0;        /* Always set to avoid warning */
-
-        /* Point at character after (?( */
-
-        ptr++;
-
-        /* Check for (?(VERSION[>]=n.m), which is a facility whereby indirect
-        users of PCRE2 via an application can discover which release of PCRE2
-        is being used. */
-
-        if (PRIV(strncmp_c8)(ptr, STRING_VERSION, 7) == 0 &&
-            ptr[7] != CHAR_RIGHT_PARENTHESIS)
-          {
-          BOOL ge = FALSE;
-          int major = 0;
-          int minor = 0;
-
-          ptr += 7;
-          if (*ptr == CHAR_GREATER_THAN_SIGN)
-            {
-            ge = TRUE;
-            ptr++;
-            }
-
-          /* NOTE: cannot write IS_DIGIT(*(++ptr)) here because IS_DIGIT
-          references its argument twice. */
-
-          if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr)))
-            {
-            *errorcodeptr = ERR79;
-            goto FAILED;
-            }
-
-          while (IS_DIGIT(*ptr)) major = major * 10 + *ptr++ - '0';
-          if (*ptr == CHAR_DOT)
-            {
-            ptr++;
-            while (IS_DIGIT(*ptr)) minor = minor * 10 + *ptr++ - '0';
-            if (minor < 10) minor *= 10;
-            }
-
-          if (*ptr != CHAR_RIGHT_PARENTHESIS || minor > 99)
-            {
-            *errorcodeptr = ERR79;
-            goto FAILED;
-            }
-
-          if (ge)
-            code[1+LINK_SIZE] = ((PCRE2_MAJOR > major) ||
-              (PCRE2_MAJOR == major && PCRE2_MINOR >= minor))?
-                OP_TRUE : OP_FALSE;
-          else
-            code[1+LINK_SIZE] = (PCRE2_MAJOR == major && PCRE2_MINOR == minor)?
-              OP_TRUE : OP_FALSE;
-
-          ptr++;
-          skipunits = 1;
-          break;  /* End of condition processing */
-          }
-
-        /* Check for a test for recursion in a named group. */
-
-        if (*ptr == CHAR_R && ptr[1] == CHAR_AMPERSAND)
-          {
-          terminator = -1;
-          ptr += 2;
-          code[1+LINK_SIZE] = OP_RREF;    /* Change the type of test */
-          }
-
-        /* Check for a test for a named group's having been set, using the Perl
-        syntax (?(<name>) or (?('name'), and also allow for the original PCRE
-        syntax of (?(name) or for (?(+n), (?(-n), and just (?(n). */
-
-        else if (*ptr == CHAR_LESS_THAN_SIGN)
-          {
-          terminator = CHAR_GREATER_THAN_SIGN;
-          ptr++;
-          }
-        else if (*ptr == CHAR_APOSTROPHE)
-          {
-          terminator = CHAR_APOSTROPHE;
-          ptr++;
-          }
-        else
-          {
-          terminator = CHAR_NULL;
-          if (*ptr == CHAR_MINUS || *ptr == CHAR_PLUS) refsign = *ptr++;
-            else if (IS_DIGIT(*ptr)) refsign = 0;
-          }
-
-        /* Handle a number */
-
-        if (refsign >= 0)
-          {
-          while (IS_DIGIT(*ptr))
-            {
-            if (recno > INT_MAX / 10 - 1)  /* Integer overflow */
-              {
-              while (IS_DIGIT(*ptr)) ptr++;
-              *errorcodeptr = ERR61;
-              goto FAILED;
-              }
-            recno = recno * 10 + (int)(*ptr - CHAR_0);
-            ptr++;
-            }
-          }
-
-        /* Otherwise we expect to read a name; anything else is an error. When
-        the referenced name is one of a number of duplicates, a different
-        opcode is used and it needs more memory. Unfortunately we cannot tell
-        whether this is the case in the first pass, so we have to allow for
-        more memory always. In the second pass, the additional to skipunits
-        happens later. */
-
-        else
-          {
-          if (IS_DIGIT(*ptr))
-            {
-            *errorcodeptr = ERR44;  /* Group name must start with non-digit */
-            goto FAILED;
-            }
-          if (!MAX_255(*ptr) || (cb->ctypes[*ptr] & ctype_word) == 0)
-            {
-            *errorcodeptr = ERR28;   /* Assertion expected */
-            goto FAILED;
-            }
-          name = ptr;
-          /* Increment ptr, set namelen, check length */
-          READ_NAME(ctype_word, ERR48, *errorcodeptr);
-          if (lengthptr != NULL) skipunits += IMM2_SIZE;
-          }
-
-        /* Check the terminator */
-
-        if ((terminator > 0 && *ptr++ != (PCRE2_UCHAR)terminator) ||
-            *ptr++ != CHAR_RIGHT_PARENTHESIS)
-          {
-          ptr--;                  /* Error offset */
-          *errorcodeptr = ERR26;  /* Malformed number or name */
-          goto FAILED;
-          }
-
-        /* Do no further checking in the pre-compile phase. */
-
-        if (lengthptr != NULL) break;
-
-        /* In the real compile we do the work of looking for the actual
-        reference. If refsign is not negative, it means we have a number in
-        recno. */
-
-        if (refsign >= 0)
-          {
-          if (recno <= 0)
-            {
-            *errorcodeptr = ERR35;
-            goto FAILED;
-            }
-          if (refsign != 0) recno = (refsign == CHAR_MINUS)?
-            (cb->bracount + 1) - recno : recno + cb->bracount;
-          if (recno <= 0 || (uint32_t)recno > cb->final_bracount)
-            {
-            *errorcodeptr = ERR15;
-            goto FAILED;
-            }
-          PUT2(code, 2+LINK_SIZE, recno);
-          if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
-          break;
-          }
-
-        /* Otherwise look for the name. */
-
-        slot = cb->name_table;
-        for (i = 0; i < cb->names_found; i++)
-          {
-          if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) == 0) break;
-          slot += cb->name_entry_size;
-          }
-
-        /* Found the named subpattern. If the name is duplicated, add one to
-        the opcode to change CREF/RREF into DNCREF/DNRREF and insert
-        appropriate data values. Otherwise, just insert the unique subpattern
-        number. */
-
-        if (i < cb->names_found)
-          {
-          int offset = i;            /* Offset of first name found */
-
-          count = 0;
-          for (;;)
-            {
-            recno = GET2(slot, 0);   /* Number for last found */
-            if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
-            count++;
-            if (++i >= cb->names_found) break;
-            slot += cb->name_entry_size;
-            if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) != 0 ||
-              (slot+IMM2_SIZE)[namelen] != 0) break;
-            }
-
-          if (count > 1)
-            {
-            PUT2(code, 2+LINK_SIZE, offset);
-            PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count);
-            skipunits += IMM2_SIZE;
-            code[1+LINK_SIZE]++;
-            }
-          else  /* Not a duplicated name */
-            {
-            PUT2(code, 2+LINK_SIZE, recno);
-            }
-          }
-
-        /* If terminator == CHAR_NULL it means that the name followed directly
-        after the opening parenthesis [e.g. (?(abc)...] and in this case there
-        are some further alternatives to try. For the cases where terminator !=
-        CHAR_NULL [things like (?(<name>... or (?('name')... or (?(R&name)... ]
-        we have now checked all the possibilities, so give an error. */
-
-        else if (terminator != CHAR_NULL)
-          {
-          *errorcodeptr = ERR15;
-          goto FAILED;
-          }
-
-        /* Check for (?(R) for recursion. Allow digits after R to specify a
-        specific group number. */
-
-        else if (*name == CHAR_R)
-          {
-          recno = 0;
-          for (i = 1; i < namelen; i++)
-            {
-            if (!IS_DIGIT(name[i]))
-              {
-              *errorcodeptr = ERR15;        /* Non-existent subpattern */
-              goto FAILED;
-              }
-            if (recno > INT_MAX / 10 - 1)   /* Integer overflow */
-              {
-              *errorcodeptr = ERR61;
-              goto FAILED;
-              }
-            recno = recno * 10 + name[i] - CHAR_0;
-            }
-          if (recno == 0) recno = RREF_ANY;
-          code[1+LINK_SIZE] = OP_RREF;      /* Change test type */
-          PUT2(code, 2+LINK_SIZE, recno);
-          }
-
-        /* Similarly, check for the (?(DEFINE) "condition", which is always
-        false. During compilation we set OP_DEFINE to distinguish this from
-        other OP_FALSE conditions so that it can be checked for having only one
-        branch, but after that the opcode is changed to OP_FALSE. */
-
-        else if (namelen == 6 && PRIV(strncmp_c8)(name, STRING_DEFINE, 6) == 0)
-          {
-          code[1+LINK_SIZE] = OP_DEFINE;
-          skipunits = 1;
-          }
-
-        /* Reference to an unidentified subpattern. */
-
-        else
-          {
-          *errorcodeptr = ERR15;
-          goto FAILED;
-          }
-        break;
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_EQUALS_SIGN:                 /* Positive lookahead */
-        bravalue = OP_ASSERT;
-        cb->assert_depth += 1;
-        ptr++;
-        break;
-
-        /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird
-        thing to do, but Perl allows all assertions to be quantified, and when
-        they contain capturing parentheses there may be a potential use for
-        this feature. Not that that applies to a quantified (?!) but we allow
-        it for uniformity. */
-
-        /* ------------------------------------------------------------ */
-        case CHAR_EXCLAMATION_MARK:            /* Negative lookahead */
-        ptr++;
-        if (*ptr == CHAR_RIGHT_PARENTHESIS && ptr[1] != CHAR_ASTERISK &&
-             ptr[1] != CHAR_PLUS && ptr[1] != CHAR_QUESTION_MARK &&
-            (ptr[1] != CHAR_LEFT_CURLY_BRACKET || !is_counted_repeat(ptr+2)))
-          {
-          *code++ = OP_FAIL;
-          previous = NULL;
-          continue;
-          }
-        bravalue = OP_ASSERT_NOT;
-        cb->assert_depth += 1;
-        break;
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_LESS_THAN_SIGN:              /* Lookbehind or named define */
-        switch (ptr[1])
-          {
-          case CHAR_EQUALS_SIGN:               /* Positive lookbehind */
-          bravalue = OP_ASSERTBACK;
-          cb->assert_depth += 1;
-          ptr += 2;
-          break;
-
-          case CHAR_EXCLAMATION_MARK:          /* Negative lookbehind */
-          bravalue = OP_ASSERTBACK_NOT;
-          cb->assert_depth += 1;
-          ptr += 2;
-          break;
-
-          /* Must be a name definition - as the syntax was checked in the
-          pre-pass, we can assume here that it is valid. Skip over the name
-          and go to handle the numbered group. */
-
-          default:
-          while (*(++ptr) != CHAR_GREATER_THAN_SIGN);
-          ptr++;
-          goto NUMBERED_GROUP;
-          }
-        break;
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_GREATER_THAN_SIGN:           /* One-time brackets */
-        bravalue = OP_ONCE;
-        ptr++;
-        break;
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_C:                 /* Callout */
-        previous_callout = code;     /* Save for later completion */
-        after_manual_callout = 1;    /* Skip one item before completing */
-        ptr++;                       /* Character after (?C */
-
-        /* A callout may have a string argument, delimited by one of a fixed
-        number of characters, or an undelimited numerical argument, or no
-        argument, which is the same as (?C0). Different opcodes are used for
-        the two cases. */
-
-        if (*ptr != CHAR_RIGHT_PARENTHESIS && !IS_DIGIT(*ptr))
-          {
-          uint32_t delimiter = 0;
-
-          for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
-            {
-            if (*ptr == PRIV(callout_start_delims)[i])
-              {
-              delimiter = PRIV(callout_end_delims)[i];
-              break;
-              }
-            }
-
-          if (delimiter == 0)
-            {
-            *errorcodeptr = ERR82;
-            goto FAILED;
-            }
-
-          /* During the pre-compile phase, we parse the string and update the
-          length. There is no need to generate any code. (In fact, the string
-          has already been parsed in the pre-pass that looks for named
-          parentheses, but it does no harm to leave this code in.) */
-
-          if (lengthptr != NULL)     /* Only check the string */
-            {
-            PCRE2_SPTR start = ptr;
-            do
-              {
-              if (++ptr >= cb->end_pattern)
-                {
-                *errorcodeptr = ERR81;
-                ptr = start;   /* To give a more useful message */
-                goto FAILED;
-                }
-              if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2;
-              }
-            while (ptr[0] != delimiter);
-
-            /* Start points to the opening delimiter, ptr points to the
-            closing delimiter. We must allow for including the delimiter and
-            for the terminating zero. Any doubled delimiters within the string
-            make this an overestimate, but it is not worth bothering about. */
-
-            (*lengthptr) += (ptr - start) + 2 + (1 + 4*LINK_SIZE);
-            }
-
-          /* In the real compile we can copy the string, knowing that it is
-          syntactically OK. The starting delimiter is included so that the
-          client can discover it if they want. We also pass the start offset to
-          help a script language give better error messages. */
-
-          else
-            {
-            PCRE2_UCHAR *callout_string = code + (1 + 4*LINK_SIZE);
-            *callout_string++ = *ptr++;
-            PUT(code, 1 + 3*LINK_SIZE, (int)(ptr - cb->start_pattern)); /* Start offset */
-            for(;;)
-              {
-              if (*ptr == delimiter)
-                {
-                if (ptr[1] == delimiter) ptr++; else break;
-                }
-              *callout_string++ = *ptr++;
-              }
-            *callout_string++ = CHAR_NULL;
-            code[0] = OP_CALLOUT_STR;
-            PUT(code, 1, (int)(ptr + 2 - cb->start_pattern)); /* Next offset */
-            PUT(code, 1 + LINK_SIZE, 0);      /* Default length */
-            PUT(code, 1 + 2*LINK_SIZE,        /* Compute size */
-                (int)(callout_string - code));
-            code = callout_string;
-            }
-
-          /* Advance to what should be the closing parenthesis, which is
-          checked below. */
-
-          ptr++;
-          }
-
-        /* Handle a callout with an optional numerical argument, which must be
-        less than or equal to 255. A missing argument gives 0. */
-
-        else
-          {
-          int n = 0;
-          code[0] = OP_CALLOUT;     /* Numerical callout */
-          while (IS_DIGIT(*ptr))
-            {
-            n = n * 10 + *ptr++ - CHAR_0;
-            if (n > 255)
-              {
-              *errorcodeptr = ERR38;
-              goto FAILED;
-              }
-            }
-          PUT(code, 1, (int)(ptr - cb->start_pattern + 1));  /* Next offset */
-          PUT(code, 1 + LINK_SIZE, 0);                    /* Default length */
-          code[1 + 2*LINK_SIZE] = n;                      /* Callout number */
-          code += PRIV(OP_lengths)[OP_CALLOUT];
-          }
-
-        /* Both formats must have a closing parenthesis */
-
-        if (*ptr != CHAR_RIGHT_PARENTHESIS)
-          {
-          *errorcodeptr = ERR39;
-          goto FAILED;
-          }
-
-        /* Callouts cannot be quantified. */
-
-        previous = NULL;
-        continue;
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_P:              /* Python-style named subpattern handling */
-        if (*(++ptr) == CHAR_EQUALS_SIGN ||
-            *ptr == CHAR_GREATER_THAN_SIGN)  /* Reference or recursion */
-          {
-          is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;
-          terminator = CHAR_RIGHT_PARENTHESIS;
-          goto NAMED_REF_OR_RECURSE;
-          }
-        else if (*ptr != CHAR_LESS_THAN_SIGN)  /* Test for Python-style defn */
-          {
-          *errorcodeptr = ERR41;
-          goto FAILED;
-          }
-        /* Fall through to handle (?P< as (?< is handled */
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_APOSTROPHE:   /* Define a name - note fall through above */
-
-        /* The syntax was checked and the list of names was set up in the
-        pre-pass, so there is nothing to be done now except to skip over the
-        name. */
-
-        terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
-                  CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
-        while (*(++ptr) != (unsigned int)terminator);
-        ptr++;
-        goto NUMBERED_GROUP;      /* Set up numbered group */
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_AMPERSAND:            /* Perl recursion/subroutine syntax */
-        terminator = CHAR_RIGHT_PARENTHESIS;
-        is_recurse = TRUE;
-        /* Fall through */
-
-        /* We come here from the Python syntax above that handles both
-        references (?P=name) and recursion (?P>name), as well as falling
-        through from the Perl recursion syntax (?&name). We also come here from
-        the Perl \k<name> or \k'name' back reference syntax and the \k{name}
-        .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */
-
-        NAMED_REF_OR_RECURSE:
-        name = ++ptr;
-        if (IS_DIGIT(*ptr))
-          {
-          *errorcodeptr = ERR44;   /* Group name must start with non-digit */
-          goto FAILED;
-          }
-        /* Increment ptr, set namelen, check length */
-        READ_NAME(ctype_word, ERR48, *errorcodeptr);
-
-        /* In the pre-compile phase, do a syntax check. */
-
-        if (lengthptr != NULL)
-          {
-          if (namelen == 0)
-            {
-            *errorcodeptr = ERR62;
-            goto FAILED;
-            }
-          if (*ptr != (PCRE2_UCHAR)terminator)
-            {
-            *errorcodeptr = ERR42;
-            goto FAILED;
-            }
-          }
-
-        /* Scan the list of names generated in the pre-pass in order to get
-        a number and whether or not this name is duplicated. */
-
-        recno = 0;
-        is_dupname = FALSE;
-        ng = cb->named_groups;
-
-        for (i = 0; i < cb->names_found; i++, ng++)
-          {
-          if (namelen == ng->length &&
-              PRIV(strncmp)(name, ng->name, namelen) == 0)
-            {
-            open_capitem *oc;
-            is_dupname = ng->isdup;
-            recno = ng->number;
-
-            /* For a recursion, that's all that is needed. We can now go to the
-            code that handles numerical recursion. */
-
-            if (is_recurse) goto HANDLE_RECURSION;
-
-            /* For a back reference, update the back reference map and the
-            maximum back reference. Then for each group we must check to see if
-            it is recursive, that is, it is inside the group that it
-            references. A flag is set so that the group can be made atomic. */
-
-            cb->backref_map |= (recno < 32)? (1u << recno) : 1;
-            if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
-
-            for (oc = cb->open_caps; oc != NULL; oc = oc->next)
-              {
-              if (oc->number == recno)
-                {
-                oc->flag = TRUE;
-                break;
-                }
-              }
-            }
-          }
-
-        /* If the name was not found we have a bad reference. */
-
-        if (recno == 0)
-          {
-          *errorcodeptr = ERR15;
-          goto FAILED;
-          }
-
-        /* If a back reference name is not duplicated, we can handle it as a
-        numerical reference. */
-
-        if (!is_dupname) goto HANDLE_REFERENCE;
-
-        /* If a back reference name is duplicated, we generate a different
-        opcode to a numerical back reference. In the second pass we must search
-        for the index and count in the final name table. */
-
-        count = 0;
-        index = 0;
-
-        if (lengthptr == NULL)
-          {
-          slot = cb->name_table;
-          for (i = 0; i < cb->names_found; i++)
-            {
-            if (PRIV(strncmp)(name, slot+IMM2_SIZE, namelen) == 0 &&
-                slot[IMM2_SIZE+namelen] == 0)
-              {
-              if (count == 0) index = i;
-              count++;
-              }
-            slot += cb->name_entry_size;
-            }
-
-          if (count == 0)
-            {
-            *errorcodeptr = ERR15;
-            goto FAILED;
-            }
-          }
-
-        if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
-        previous = code;
-        *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
-        PUT2INC(code, 0, index);
-        PUT2INC(code, 0, count);
-        continue;  /* End of back ref handling */
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_R:              /* Recursion, same as (?0) */
-        recno = 0;
-        if (*(++ptr) != CHAR_RIGHT_PARENTHESIS)
-          {
-          *errorcodeptr = ERR29;
-          goto FAILED;
-          }
-        goto HANDLE_RECURSION;
-
-
-        /* ------------------------------------------------------------ */
-        case CHAR_MINUS: case CHAR_PLUS:  /* Recursion or subroutine */
-        case CHAR_0: 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:
-          {
-          terminator = CHAR_RIGHT_PARENTHESIS;
-
-          /* Come here from the \g<...> and \g'...' code (Oniguruma
-          compatibility). However, the syntax has been checked to ensure that
-          the ... are a (signed) number, so that neither ERR63 nor ERR29 will
-          be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY
-          ever be taken. */
-
-          HANDLE_NUMERICAL_RECURSION:
-
-          if ((refsign = *ptr) == CHAR_PLUS)
-            {
-            ptr++;
-            if (!IS_DIGIT(*ptr))
-              {
-              *errorcodeptr = ERR63;
-              goto FAILED;
-              }
-            }
-          else if (refsign == CHAR_MINUS)
-            {
-            if (!IS_DIGIT(ptr[1]))
-              goto OTHER_CHAR_AFTER_QUERY;
-            ptr++;
-            }
-
-          recno = 0;
-          while (IS_DIGIT(*ptr))
-            {
-            if (recno > INT_MAX / 10 - 1) /* Integer overflow */
-              {
-              while (IS_DIGIT(*ptr)) ptr++;
-              *errorcodeptr = ERR61;
-              goto FAILED;
-              }
-            recno = recno * 10 + *ptr++ - CHAR_0;
-            }
-
-          if (*ptr != (PCRE2_UCHAR)terminator)
-            {
-            *errorcodeptr = ERR29;
-            goto FAILED;
-            }
-
-          if (refsign == CHAR_MINUS)
-            {
-            if (recno == 0)
-              {
-              *errorcodeptr = ERR58;
-              goto FAILED;
-              }
-            recno = (int)(cb->bracount + 1) - recno;
-            if (recno <= 0)
-              {
-              *errorcodeptr = ERR15;
-              goto FAILED;
-              }
-            }
-          else if (refsign == CHAR_PLUS)
-            {
-            if (recno == 0)
-              {
-              *errorcodeptr = ERR58;
-              goto FAILED;
-              }
-            recno += cb->bracount;
-            }
-
-          if ((uint32_t)recno > cb->final_bracount)
-            {
-            *errorcodeptr = ERR15;
-            goto FAILED;
-            }
-
-          /* Come here from code above that handles a named recursion.
-          We insert the number of the called group after OP_RECURSE. At the
-          end of compiling the pattern is scanned and these numbers are
-          replaced by offsets within the pattern. It is done like this to avoid
-          problems with forward references and adjusting offsets when groups
-          are duplicated and moved (as discovered in previous implementations).
-          Note that a recursion does not have a set first character (relevant
-          if it is repeated, because it will then be wrapped with ONCE
-          brackets). */
-
-          HANDLE_RECURSION:
-          previous = code;
-          *code = OP_RECURSE;
-          PUT(code, 1, recno);
-          code += 1 + LINK_SIZE;
-          groupsetfirstcu = FALSE;
-          cb->had_recurse = TRUE;
-          }
-
-        /* Can't determine a first byte now */
-
-        if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
-        continue;
-
-
-        /* ------------------------------------------------------------ */
-        default:              /* Other characters: check option setting */
-        OTHER_CHAR_AFTER_QUERY:
-        set = unset = 0;
-        optset = &set;
-
-        while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON)
-          {
-          switch (*ptr++)
-            {
-            case CHAR_MINUS: optset = &unset; break;
-
-            case CHAR_J:    /* Record that it changed in the external options */
-            *optset |= PCRE2_DUPNAMES;
-            cb->external_flags |= PCRE2_JCHANGED;
-            break;
-
-            case CHAR_i: *optset |= PCRE2_CASELESS; break;
-            case CHAR_m: *optset |= PCRE2_MULTILINE; break;
-            case CHAR_s: *optset |= PCRE2_DOTALL; break;
-            case CHAR_x: *optset |= PCRE2_EXTENDED; break;
-            case CHAR_U: *optset |= PCRE2_UNGREEDY; break;
-
-            default:  *errorcodeptr = ERR11;
-                      ptr--;    /* Correct the offset */
-                      goto FAILED;
-            }
-          }
-
-        /* Set up the changed option bits, but don't change anything yet. */
-
-        newoptions = (options | set) & (~unset);
-
-        /* If the options ended with ')' this is not the start of a nested
-        group with option changes, so the options change at this level. They
-        must also be passed back for use in subsequent branches. Reset the
-        greedy defaults and the case value for firstcu and reqcu. */
-
-        if (*ptr == CHAR_RIGHT_PARENTHESIS)
-          {
-          *optionsptr = options = newoptions;
-          greedy_default = ((newoptions & PCRE2_UNGREEDY) != 0);
-          greedy_non_default = greedy_default ^ 1;
-          req_caseopt = ((newoptions & PCRE2_CASELESS) != 0)? REQ_CASELESS:0;
-          previous = NULL;       /* This item can't be repeated */
-          continue;              /* It is complete */
-          }
-
-        /* If the options ended with ':' we are heading into a nested group
-        with possible change of options. Such groups are non-capturing and are
-        not assertions of any kind. All we need to do is skip over the ':';
-        the newoptions value is handled below. */
-
-        bravalue = OP_BRA;
-        ptr++;
-        }     /* End of switch for character following (? */
-      }       /* End of (? handling */
-
-    /* Opening parenthesis not followed by '*' or '?'. If PCRE2_NO_AUTO_CAPTURE
-    is set, all unadorned brackets become non-capturing and behave like (?:...)
-    brackets. */
-
-    else if ((options & PCRE2_NO_AUTO_CAPTURE) != 0)
-      {
-      bravalue = OP_BRA;
-      }
-
-    /* Else we have a capturing group. */
-
-    else
-      {
-      NUMBERED_GROUP:
-      cb->bracount += 1;
-      PUT2(code, 1+LINK_SIZE, cb->bracount);
-      skipunits = IMM2_SIZE;
-      }
-
-    /* Process nested bracketed regex. First check for parentheses nested too
-    deeply. */
-
-    if ((cb->parens_depth += 1) > (int)(cb->cx->parens_nest_limit))
-      {
-      *errorcodeptr = ERR19;
-      goto FAILED;
-      }
-
-    /* All assertions used not to be repeatable, but this was changed for Perl
-    compatibility. All kinds can now be repeated except for assertions that are
-    conditions (Perl also forbids these to be repeated). We copy code into a
-    non-register variable (tempcode) in order to be able to pass its address
-    because some compilers complain otherwise. At the start of a conditional
-    group whose condition is an assertion, cb->iscondassert is set. We unset it
-    here so as to allow assertions later in the group to be quantified. */
-
-    if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT &&
-        cb->iscondassert)
-      {
-      previous = NULL;
-      cb->iscondassert = FALSE;
-      }
-    else
-      {
-      previous = code;
-      }
-
-    *code = bravalue;
-    tempcode = code;
-    tempreqvary = cb->req_varyopt;        /* Save value before bracket */
-    tempbracount = cb->bracount;          /* Save value before bracket */
-    length_prevgroup = 0;                 /* Initialize for pre-compile phase */
-
-    if (!compile_regex(
-         newoptions,                      /* The complete new option state */
-         &tempcode,                       /* Where to put code (updated) */
-         &ptr,                            /* Input pointer (updated) */
-         errorcodeptr,                    /* Where to put an error message */
-         (bravalue == OP_ASSERTBACK ||
-          bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
-         reset_bracount,                  /* True if (?| group */
-         skipunits,                       /* Skip over bracket number */
-         cond_depth +
-           ((bravalue == OP_COND)?1:0),   /* Depth of condition subpatterns */
-         &subfirstcu,                     /* For possible first char */
-         &subfirstcuflags,
-         &subreqcu,                       /* For possible last char */
-         &subreqcuflags,
-         bcptr,                           /* Current branch chain */
-         cb,                              /* Compile data block */
-         (lengthptr == NULL)? NULL :      /* Actual compile phase */
-           &length_prevgroup              /* Pre-compile phase */
-         ))
-      goto FAILED;
-
-    cb->parens_depth -= 1;
-
-    /* If this was an atomic group and there are no capturing groups within it,
-    generate OP_ONCE_NC instead of OP_ONCE. */
-
-    if (bravalue == OP_ONCE && cb->bracount <= tempbracount)
-      *code = OP_ONCE_NC;
-
-    if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
-      cb->assert_depth -= 1;
-
-    /* At the end of compiling, code is still pointing to the start of the
-    group, while tempcode has been updated to point past the end of the group.
-    The pattern pointer (ptr) is on the bracket.
-
-    If this is a conditional bracket, check that there are no more than
-    two branches in the group, or just one if it's a DEFINE group. We do this
-    in the real compile phase, not in the pre-pass, where the whole group may
-    not be available. */
-
-    if (bravalue == OP_COND && lengthptr == NULL)
-      {
-      PCRE2_UCHAR *tc = code;
-      int condcount = 0;
-
-      do {
-         condcount++;
-         tc += GET(tc,1);
-         }
-      while (*tc != OP_KET);
-
-      /* A DEFINE group is never obeyed inline (the "condition" is always
-      false). It must have only one branch. Having checked this, change the
-      opcode to OP_FALSE. */
-
-      if (code[LINK_SIZE+1] == OP_DEFINE)
-        {
-        if (condcount > 1)
-          {
-          *errorcodeptr = ERR54;
-          goto FAILED;
-          }
-        code[LINK_SIZE+1] = OP_FALSE;
-        bravalue = OP_DEFINE;   /* Just a flag to suppress char handling below */
-        }
-
-      /* A "normal" conditional group. If there is just one branch, we must not
-      make use of its firstcu or reqcu, because this is equivalent to an
-      empty second branch. */
-
-      else
-        {
-        if (condcount > 2)
-          {
-          *errorcodeptr = ERR27;
-          goto FAILED;
-          }
-        if (condcount == 1) subfirstcuflags = subreqcuflags = REQ_NONE;
-        }
-      }
-
-    /* At the end of a group, it's an error if we hit end of pattern or
-    any non-closing parenthesis. This check also happens in the pre-scan,
-    so should not trigger here, but leave this code as an insurance. */
-
-    if (*ptr != CHAR_RIGHT_PARENTHESIS)
-      {
-      *errorcodeptr = ERR14;
-      goto FAILED;
-      }
-
-    /* In the pre-compile phase, update the length by the length of the group,
-    less the brackets at either end. Then reduce the compiled code to just a
-    set of non-capturing brackets so that it doesn't use much memory if it is
-    duplicated by a quantifier.*/
-
-    if (lengthptr != NULL)
-      {
-      if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
-        {
-        *errorcodeptr = ERR20;
-        goto FAILED;
-        }
-      *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
-      code++;   /* This already contains bravalue */
-      PUTINC(code, 0, 1 + LINK_SIZE);
-      *code++ = OP_KET;
-      PUTINC(code, 0, 1 + LINK_SIZE);
-      break;    /* No need to waste time with special character handling */
-      }
-
-    /* Otherwise update the main code pointer to the end of the group. */
-
-    code = tempcode;
-
-    /* For a DEFINE group, required and first character settings are not
-    relevant. */
-
-    if (bravalue == OP_DEFINE) break;
-
-    /* Handle updating of the required and first characters for other types of
-    group. Update for normal brackets of all kinds, and conditions with two
-    branches (see code above). If the bracket is followed by a quantifier with
-    zero repeat, we have to back off. Hence the definition of zeroreqcu and
-    zerofirstcu outside the main loop so that they can be accessed for the
-    back off. */
-
-    zeroreqcu = reqcu;
-    zeroreqcuflags = reqcuflags;
-    zerofirstcu = firstcu;
-    zerofirstcuflags = firstcuflags;
-    groupsetfirstcu = FALSE;
-
-    if (bravalue >= OP_ONCE)
-      {
-      /* If we have not yet set a firstcu in this branch, take it from the
-      subpattern, remembering that it was set here so that a repeat of more
-      than one can replicate it as reqcu if necessary. If the subpattern has
-      no firstcu, set "none" for the whole branch. In both cases, a zero
-      repeat forces firstcu to "none". */
-
-      if (firstcuflags == REQ_UNSET && subfirstcuflags != REQ_UNSET)
-        {
-        if (subfirstcuflags >= 0)
-          {
-          firstcu = subfirstcu;
-          firstcuflags = subfirstcuflags;
-          groupsetfirstcu = TRUE;
-          }
-        else firstcuflags = REQ_NONE;
-        zerofirstcuflags = REQ_NONE;
-        }
-
-      /* If firstcu was previously set, convert the subpattern's firstcu
-      into reqcu if there wasn't one, using the vary flag that was in
-      existence beforehand. */
-
-      else if (subfirstcuflags >= 0 && subreqcuflags < 0)
-        {
-        subreqcu = subfirstcu;
-        subreqcuflags = subfirstcuflags | tempreqvary;
-        }
-
-      /* If the subpattern set a required byte (or set a first byte that isn't
-      really the first byte - see above), set it. */
-
-      if (subreqcuflags >= 0)
-        {
-        reqcu = subreqcu;
-        reqcuflags = subreqcuflags;
-        }
-      }
-
-    /* For a forward assertion, we take the reqcu, if set. This can be
-    helpful if the pattern that follows the assertion doesn't set a different
-    char. For example, it's useful for /(?=abcde).+/. We can't set firstcu
-    for an assertion, however because it leads to incorrect effect for patterns
-    such as /(?=a)a.+/ when the "real" "a" would then become a reqcu instead
-    of a firstcu. This is overcome by a scan at the end if there's no
-    firstcu, looking for an asserted first char. */
-
-    else if (bravalue == OP_ASSERT && subreqcuflags >= 0)
-      {
-      reqcu = subreqcu;
-      reqcuflags = subreqcuflags;
-      }
-    break;     /* End of processing '(' */
-
-
-    /* ===================================================================*/
-    /* Handle metasequences introduced by \. For ones like \d, the ESC_ values
-    are arranged to be the negation of the corresponding OP_values in the
-    default case when PCRE2_UCP is not set. For the back references, the values
-    are negative the reference number. Only back references and those types
-    that consume a character may be repeated. We can test for values between
-    ESC_b and ESC_Z for the latter; this may have to change if any new ones are
-    ever created.
-
-    Note: \Q and \E are handled at the start of the character-processing loop,
-    not here. */
-
-    case CHAR_BACKSLASH:
-    tempptr = ptr;
-    escape = PRIV(check_escape)(&ptr, cb->end_pattern, &ec, errorcodeptr,
-      options, FALSE, cb);
-    if (*errorcodeptr != 0) goto FAILED;
-
-    if (escape == 0)                  /* The escape coded a single character */
-      c = ec;
-    else
-      {
-      /* For metasequences that actually match a character, we disable the
-      setting of a first character if it hasn't already been set. */
-
-      if (firstcuflags == REQ_UNSET && escape > ESC_b && escape < ESC_Z)
-        firstcuflags = REQ_NONE;
-
-      /* Set values to reset to if this is followed by a zero repeat. */
-
-      zerofirstcu = firstcu;
-      zerofirstcuflags = firstcuflags;
-      zeroreqcu = reqcu;
-      zeroreqcuflags = reqcuflags;
-
-      /* \g<name> or \g'name' is a subroutine call by name and \g<n> or \g'n'
-      is a subroutine call by number (Oniguruma syntax). In fact, the value
-      ESC_g is returned only for these cases. So we don't need to check for <
-      or ' if the value is ESC_g. For the Perl syntax \g{n} the value is
-      -n, and for the Perl syntax \g{name} the result is ESC_k (as
-      that is a synonym for a named back reference). */
-
-      if (escape == ESC_g)
-        {
-        PCRE2_SPTR p;
-        uint32_t cf;
-
-        terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
-          CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
-
-        /* These two statements stop the compiler for warning about possibly
-        unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
-        fact, because we do the check for a number below, the paths that
-        would actually be in error are never taken. */
-
-        skipunits = 0;
-        reset_bracount = FALSE;
-
-        /* If it's not a signed or unsigned number, treat it as a name. */
-
-        cf = ptr[1];
-        if (cf != CHAR_PLUS && cf != CHAR_MINUS && !IS_DIGIT(cf))
-          {
-          is_recurse = TRUE;
-          goto NAMED_REF_OR_RECURSE;
-          }
-
-        /* Signed or unsigned number (cf = ptr[1]) is known to be plus or minus
-        or a digit. */
-
-        p = ptr + 2;
-        while (IS_DIGIT(*p)) p++;
-        if (*p != (PCRE2_UCHAR)terminator)
-          {
-          *errorcodeptr = ERR57;
-          goto FAILED;
-          }
-        ptr++;
-        goto HANDLE_NUMERICAL_RECURSION;
-        }
-
-      /* \k<name> or \k'name' is a back reference by name (Perl syntax).
-      We also support \k{name} (.NET syntax).  */
-
-      if (escape == ESC_k)
-        {
-        if ((ptr[1] != CHAR_LESS_THAN_SIGN &&
-          ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
-          {
-          *errorcodeptr = ERR69;
-          goto FAILED;
-          }
-        is_recurse = FALSE;
-        terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
-          CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
-          CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
-        goto NAMED_REF_OR_RECURSE;
-        }
-
-      /* Back references are handled specially; must disable firstcu if
-      not set to cope with cases like (?=(\w+))\1: which would otherwise set
-      ':' later. */
-
-      if (escape < 0)
-        {
-        open_capitem *oc;
-        recno = -escape;
-
-        /* Come here from named backref handling when the reference is to a
-        single group (i.e. not to a duplicated name). */
-
-        HANDLE_REFERENCE:
-        if (recno > (int)cb->final_bracount)
-          {
-          *errorcodeptr = ERR15;
-          goto FAILED;
-          }
-        if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
-        previous = code;
-        *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;
-        PUT2INC(code, 0, recno);
-        cb->backref_map |= (recno < 32)? (1u << recno) : 1;
-        if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
-
-        /* Check to see if this back reference is recursive, that it, it
-        is inside the group that it references. A flag is set so that the
-        group can be made atomic. */
-
-        for (oc = cb->open_caps; oc != NULL; oc = oc->next)
-          {
-          if (oc->number == recno)
-            {
-            oc->flag = TRUE;
-            break;
-            }
-          }
-        }
-
-      /* So are Unicode property matches, if supported. */
-
-#ifdef SUPPORT_UNICODE
-      else if (escape == ESC_P || escape == ESC_p)
-        {
-        BOOL negated;
-        unsigned int ptype = 0, pdata = 0;
-        if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr, cb))
-          goto FAILED;
-        previous = code;
-        *code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
-        *code++ = ptype;
-        *code++ = pdata;
-        }
-#else
-
-      /* If Unicode properties are not supported, \X, \P, and \p are not
-      allowed. */
-
-      else if (escape == ESC_X || escape == ESC_P || escape == ESC_p)
-        {
-        *errorcodeptr = ERR45;
-        goto FAILED;
-        }
-#endif
-
-      /* The use of \C can be locked out. */
-
-#ifdef NEVER_BACKSLASH_C
-      else if (escape == ESC_C)
-        {
-        *errorcodeptr = ERR85;
-        goto FAILED;
-        }
-#else
-      else if (escape == ESC_C && (options & PCRE2_NEVER_BACKSLASH_C) != 0)
-        {
-        *errorcodeptr = ERR83;
-        goto FAILED;
-        }
-#endif
-
-      /* For the rest (including \X when Unicode properties are supported), we
-      can obtain the OP value by negating the escape value in the default
-      situation when PCRE2_UCP is not set. When it *is* set, we substitute
-      Unicode property tests. Note that \b and \B do a one-character
-      lookbehind, and \A also behaves as if it does. */
-
-      else
-        {
-        if (escape == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */
-        if ((escape == ESC_b || escape == ESC_B || escape == ESC_A) &&
-             cb->max_lookbehind == 0)
-          cb->max_lookbehind = 1;
-#ifdef SUPPORT_UNICODE
-        if (escape >= ESC_DU && escape <= ESC_wu)
-          {
-          cb->nestptr[1] = cb->nestptr[0];         /* Back up if at 2nd level */
-          cb->nestptr[0] = ptr + 1;                /* Where to resume */
-          ptr = substitutes[escape - ESC_DU] - 1;  /* Just before substitute */
-          }
-        else
-#endif
-        /* In non-UTF mode, and for both 32-bit modes, we turn \C into
-        OP_ALLANY instead of OP_ANYBYTE so that it works in DFA mode and in
-        lookbehinds. */
-
-          {
-          previous = (escape > ESC_b && escape < ESC_Z)? code : NULL;
-#if PCRE2_CODE_UNIT_WIDTH == 32
-          *code++ = (escape == ESC_C)? OP_ALLANY : escape;
-#else
-          *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape;
-#endif
-          }
-        }
-      continue;
-      }
-
-    /* We have a data character whose value is in c. In UTF-8 mode it may have
-    a value > 127. We set its representation in the length/buffer, and then
-    handle it as a data character. */
-
-    mclength = PUTCHAR(c, mcbuffer);
-    goto ONE_CHAR;
-
-
-    /* ===================================================================*/
-    /* Handle a literal character. It is guaranteed not to be whitespace or #
-    when the extended flag is set. If we are in a UTF mode, it may be a
-    multi-unit literal character. */
-
-    default:
-    NORMAL_CHAR:
-    mclength = 1;
-    mcbuffer[0] = c;
-
-#ifdef SUPPORT_UNICODE
-    if (utf && HAS_EXTRALEN(c))
-      ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr));
-#endif
-
-    /* At this point we have the character's bytes in mcbuffer, and the length
-    in mclength. When not in UTF mode, the length is always 1. */
-
-    ONE_CHAR:
-    previous = code;
-
-    /* For caseless UTF mode, check whether this character has more than one
-    other case. If so, generate a special OP_PROP item instead of OP_CHARI. */
-
-#ifdef SUPPORT_UNICODE
-    if (utf && (options & PCRE2_CASELESS) != 0)
-      {
-      GETCHAR(c, mcbuffer);
-      if ((c = UCD_CASESET(c)) != 0)
-        {
-        *code++ = OP_PROP;
-        *code++ = PT_CLIST;
-        *code++ = c;
-        if (firstcuflags == REQ_UNSET)
-          firstcuflags = zerofirstcuflags = REQ_NONE;
-        break;
-        }
-      }
-#endif
-
-    /* Caseful matches, or not one of the multicase characters. */
-
-    *code++ = ((options & PCRE2_CASELESS) != 0)? OP_CHARI : OP_CHAR;
-    for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
-
-    /* Remember if \r or \n were seen */
-
-    if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
-      cb->external_flags |= PCRE2_HASCRORLF;
-
-    /* Set the first and required bytes appropriately. If no previous first
-    byte, set it from this character, but revert to none on a zero repeat.
-    Otherwise, leave the firstcu value alone, and don't change it on a zero
-    repeat. */
-
-    if (firstcuflags == REQ_UNSET)
-      {
-      zerofirstcuflags = REQ_NONE;
-      zeroreqcu = reqcu;
-      zeroreqcuflags = reqcuflags;
-
-      /* If the character is more than one byte long, we can set firstcu
-      only if it is not to be matched caselessly. */
-
-      if (mclength == 1 || req_caseopt == 0)
-        {
-        firstcu = mcbuffer[0] | req_caseopt;
-        firstcu = mcbuffer[0];
-        firstcuflags = req_caseopt;
-
-        if (mclength != 1)
-          {
-          reqcu = code[-1];
-          reqcuflags = cb->req_varyopt;
-          }
-        }
-      else firstcuflags = reqcuflags = REQ_NONE;
-      }
-
-    /* firstcu was previously set; we can set reqcu only if the length is
-    1 or the matching is caseful. */
-
-    else
-      {
-      zerofirstcu = firstcu;
-      zerofirstcuflags = firstcuflags;
-      zeroreqcu = reqcu;
-      zeroreqcuflags = reqcuflags;
-      if (mclength == 1 || req_caseopt == 0)
-        {
-        reqcu = code[-1];
-        reqcuflags = req_caseopt | cb->req_varyopt;
-        }
-      }
-
-    break;            /* End of literal character handling */
-    }
-  }                   /* end of big loop */
-
-/* Control never reaches here by falling through, only by a goto for all the
-error states. Pass back the position in the pattern so that it can be displayed
-to the user for diagnosing the error. */
-
-FAILED:
-*ptrptr = ptr;
-return FALSE;
-}
-
-
-
-/*************************************************
-*   Compile regex: a sequence of alternatives    *
-*************************************************/
-
-/* On entry, ptr is pointing past the bracket character, but on return it
-points to the closing bracket, or vertical bar, or end of string. The code
-variable is pointing at the byte into which the BRA operator has been stored.
-This function is used during the pre-compile phase when we are trying to find
-out the amount of memory needed, as well as during the real compile phase. The
-value of lengthptr distinguishes the two phases.
-
-Arguments:
-  options           option bits, including any changes for this subpattern
-  codeptr           -> the address of the current code pointer
-  ptrptr            -> the address of the current pattern pointer
-  errorcodeptr      -> pointer to error code variable
-  lookbehind        TRUE if this is a lookbehind assertion
-  reset_bracount    TRUE to reset the count for each branch
-  skipunits         skip this many code units at start (for brackets and OP_COND)
-  cond_depth        depth of nesting for conditional subpatterns
-  firstcuptr        place to put the first required code unit
-  firstcuflagsptr   place to put the first code unit flags, or a negative number
-  reqcuptr          place to put the last required code unit
-  reqcuflagsptr     place to put the last required code unit flags, or a negative number
-  bcptr             pointer to the chain of currently open branches
-  cb                points to the data block with tables pointers etc.
-  lengthptr         NULL during the real compile phase
-                    points to length accumulator during pre-compile phase
-
-Returns:            TRUE on success
-*/
-
-static BOOL
-compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, PCRE2_SPTR *ptrptr,
-  int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, uint32_t skipunits,
-  int cond_depth, uint32_t *firstcuptr, int32_t *firstcuflagsptr,
-  uint32_t *reqcuptr, int32_t *reqcuflagsptr, branch_chain *bcptr,
-  compile_block *cb, size_t *lengthptr)
-{
-PCRE2_SPTR ptr = *ptrptr;
-PCRE2_UCHAR *code = *codeptr;
-PCRE2_UCHAR *last_branch = code;
-PCRE2_UCHAR *start_bracket = code;
-PCRE2_UCHAR *reverse_count = NULL;
-open_capitem capitem;
-int capnumber = 0;
-uint32_t firstcu, reqcu;
-int32_t firstcuflags, reqcuflags;
-uint32_t branchfirstcu, branchreqcu;
-int32_t branchfirstcuflags, branchreqcuflags;
-size_t length;
-unsigned int orig_bracount;
-unsigned int max_bracount;
-branch_chain bc;
-
-/* If set, call the external function that checks for stack availability. */
-
-if (cb->cx->stack_guard != NULL &&
-    cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data))
-  {
-  *errorcodeptr= ERR33;
-  return FALSE;
-  }
-
-/* Miscellaneous initialization */
-
-bc.outer = bcptr;
-bc.current_branch = code;
-
-firstcu = reqcu = 0;
-firstcuflags = reqcuflags = REQ_UNSET;
-
-/* Accumulate the length for use in the pre-compile phase. Start with the
-length of the BRA and KET and any extra code units that are required at the
-beginning. We accumulate in a local variable to save frequent testing of
-lengthptr for NULL. We cannot do this by looking at the value of 'code' at the
-start and end of each alternative, because compiled items are discarded during
-the pre-compile phase so that the work space is not exceeded. */
-
-length = 2 + 2*LINK_SIZE + skipunits;
-
-/* WARNING: If the above line is changed for any reason, you must also change
-the code that abstracts option settings at the start of the pattern and makes
-them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
-pre-compile phase to find out whether or not anything has yet been compiled.
-
-If this is a capturing subpattern, add to the chain of open capturing items
-so that we can detect them if (*ACCEPT) is encountered. This is also used to
-detect groups that contain recursive back references to themselves. Note that
-only OP_CBRA need be tested here; changing this opcode to one of its variants,
-e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */
-
-if (*code == OP_CBRA)
-  {
-  capnumber = GET2(code, 1 + LINK_SIZE);
-  capitem.number = capnumber;
-  capitem.next = cb->open_caps;
-  capitem.flag = FALSE;
-  cb->open_caps = &capitem;
-  }
-
-/* Offset is set zero to mark that this bracket is still open */
-
-PUT(code, 1, 0);
-code += 1 + LINK_SIZE + skipunits;
-
-/* Loop for each alternative branch */
-
-orig_bracount = max_bracount = cb->bracount;
-
-for (;;)
-  {
-  /* For a (?| group, reset the capturing bracket count so that each branch
-  uses the same numbers. */
-
-  if (reset_bracount) cb->bracount = orig_bracount;
-
-  /* Set up dummy OP_REVERSE if lookbehind assertion */
-
-  if (lookbehind)
-    {
-    *code++ = OP_REVERSE;
-    reverse_count = code;
-    PUTINC(code, 0, 0);
-    length += 1 + LINK_SIZE;
-    }
-
-  /* Now compile the branch; in the pre-compile phase its length gets added
-  into the length. */
-
-  if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstcu,
-        &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc,
-        cond_depth, cb, (lengthptr == NULL)? NULL : &length))
-    {
-    *ptrptr = ptr;
-    return FALSE;
-    }
-
-  /* Keep the highest bracket count in case (?| was used and some branch
-  has fewer than the rest. */
-
-  if (cb->bracount > max_bracount) max_bracount = cb->bracount;
-
-  /* In the real compile phase, there is some post-processing to be done. */
-
-  if (lengthptr == NULL)
-    {
-    /* If this is the first branch, the firstcu and reqcu values for the
-    branch become the values for the regex. */
-
-    if (*last_branch != OP_ALT)
-      {
-      firstcu = branchfirstcu;
-      firstcuflags = branchfirstcuflags;
-      reqcu = branchreqcu;
-      reqcuflags = branchreqcuflags;
-      }
-
-    /* If this is not the first branch, the first char and reqcu have to
-    match the values from all the previous branches, except that if the
-    previous value for reqcu didn't have REQ_VARY set, it can still match,
-    and we set REQ_VARY for the regex. */
-
-    else
-      {
-      /* If we previously had a firstcu, but it doesn't match the new branch,
-      we have to abandon the firstcu for the regex, but if there was
-      previously no reqcu, it takes on the value of the old firstcu. */
-
-      if (firstcuflags != branchfirstcuflags || firstcu != branchfirstcu)
-        {
-        if (firstcuflags >= 0)
-          {
-          if (reqcuflags < 0)
-            {
-            reqcu = firstcu;
-            reqcuflags = firstcuflags;
-            }
-          }
-        firstcuflags = REQ_NONE;
-        }
-
-      /* If we (now or from before) have no firstcu, a firstcu from the
-      branch becomes a reqcu if there isn't a branch reqcu. */
-
-      if (firstcuflags < 0 && branchfirstcuflags >= 0 &&
-          branchreqcuflags < 0)
-        {
-        branchreqcu = branchfirstcu;
-        branchreqcuflags = branchfirstcuflags;
-        }
-
-      /* Now ensure that the reqcus match */
-
-      if (((reqcuflags & ~REQ_VARY) != (branchreqcuflags & ~REQ_VARY)) ||
-          reqcu != branchreqcu)
-        reqcuflags = REQ_NONE;
-      else
-        {
-        reqcu = branchreqcu;
-        reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY */
-        }
-      }
-
-    /* If lookbehind, check that this branch matches a fixed-length string, and
-    put the length into the OP_REVERSE item. Temporarily mark the end of the
-    branch with OP_END. If the branch contains OP_RECURSE, the result is
-    FFL_LATER (a negative value) because there may be forward references that
-    we can't check here. Set a flag to cause another lookbehind check at the
-    end. Why not do it all at the end? Because common errors can be picked up
-    here and the offset of the problem can be shown. */
-
-    if (lookbehind)
-      {
-      int fixed_length;
-      int count = 0;
-      *code = OP_END;
-      fixed_length = find_fixedlength(last_branch,  (options & PCRE2_UTF) != 0,
-        FALSE, cb, NULL, &count);
-      if (fixed_length == FFL_LATER)
-        {
-        cb->check_lookbehind = TRUE;
-        }
-      else if (fixed_length < 0)
-        {
-        *errorcodeptr = fixed_length_errors[-fixed_length];
-        *ptrptr = ptr;
-        return FALSE;
-        }
-      else
-        {
-        if (fixed_length > cb->max_lookbehind)
-          cb->max_lookbehind = fixed_length;
-        PUT(reverse_count, 0, fixed_length);
-        }
-      }
-    }
-
-  /* Reached end of expression, either ')' or end of pattern. In the real
-  compile phase, go back through the alternative branches and reverse the chain
-  of offsets, with the field in the BRA item now becoming an offset to the
-  first alternative. If there are no alternatives, it points to the end of the
-  group. The length in the terminating ket is always the length of the whole
-  bracketed item. Return leaving the pointer at the terminating char. */
-
-  if (*ptr != CHAR_VERTICAL_LINE)
-    {
-    if (lengthptr == NULL)
-      {
-      size_t branch_length = code - last_branch;
-      do
-        {
-        size_t prev_length = GET(last_branch, 1);
-        PUT(last_branch, 1, branch_length);
-        branch_length = prev_length;
-        last_branch -= branch_length;
-        }
-      while (branch_length > 0);
-      }
-
-    /* Fill in the ket */
-
-    *code = OP_KET;
-    PUT(code, 1, (int)(code - start_bracket));
-    code += 1 + LINK_SIZE;
-
-    /* If it was a capturing subpattern, check to see if it contained any
-    recursive back references. If so, we must wrap it in atomic brackets. In
-    any event, remove the block from the chain. */
-
-    if (capnumber > 0)
-      {
-      if (cb->open_caps->flag)
-        {
-        memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
-          CU2BYTES(code - start_bracket));
-        *start_bracket = OP_ONCE;
-        code += 1 + LINK_SIZE;
-        PUT(start_bracket, 1, (int)(code - start_bracket));
-        *code = OP_KET;
-        PUT(code, 1, (int)(code - start_bracket));
-        code += 1 + LINK_SIZE;
-        length += 2 + 2*LINK_SIZE;
-        }
-      cb->open_caps = cb->open_caps->next;
-      }
-
-    /* Retain the highest bracket number, in case resetting was used. */
-
-    cb->bracount = max_bracount;
-
-    /* Set values to pass back */
-
-    *codeptr = code;
-    *ptrptr = ptr;
-    *firstcuptr = firstcu;
-    *firstcuflagsptr = firstcuflags;
-    *reqcuptr = reqcu;
-    *reqcuflagsptr = reqcuflags;
-    if (lengthptr != NULL)
-      {
-      if (OFLOW_MAX - *lengthptr < length)
-        {
-        *errorcodeptr = ERR20;
-        return FALSE;
-        }
-      *lengthptr += length;
-      }
-    return TRUE;
-    }
-
-  /* Another branch follows. In the pre-compile phase, we can move the code
-  pointer back to where it was for the start of the first branch. (That is,
-  pretend that each branch is the only one.)
-
-  In the real compile phase, insert an ALT node. Its length field points back
-  to the previous branch while the bracket remains open. At the end the chain
-  is reversed. It's done like this so that the start of the bracket has a
-  zero offset until it is closed, making it possible to detect recursion. */
-
-  if (lengthptr != NULL)
-    {
-    code = *codeptr + 1 + LINK_SIZE + skipunits;
-    length += 1 + LINK_SIZE;
-    }
-  else
-    {
-    *code = OP_ALT;
-    PUT(code, 1, (int)(code - last_branch));
-    bc.current_branch = last_branch = code;
-    code += 1 + LINK_SIZE;
-    }
-
-  /* Advance past the vertical bar */
-
-  ptr++;
-  }
-/* Control never reaches here */
-}
-
-
-
-/*************************************************
-*          Check for anchored pattern            *
-*************************************************/
-
-/* Try to find out if this is an anchored regular expression. Consider each
-alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
-all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
-it's anchored. However, if this is a multiline pattern, then only OP_SOD will
-be found, because ^ generates OP_CIRCM in that mode.
-
-We can also consider a regex to be anchored if OP_SOM starts all its branches.
-This is the code for \G, which means "match at start of match position, taking
-into account the match offset".
-
-A branch is also implicitly anchored if it starts with .* and DOTALL is set,
-because that will try the rest of the pattern at all possible matching points,
-so there is no point trying again.... er ....
-
-.... except when the .* appears inside capturing parentheses, and there is a
-subsequent back reference to those parentheses. We haven't enough information
-to catch that case precisely.
-
-At first, the best we could do was to detect when .* was in capturing brackets
-and the highest back reference was greater than or equal to that level.
-However, by keeping a bitmap of the first 31 back references, we can catch some
-of the more common cases more precisely.
-
-... A second exception is when the .* appears inside an atomic group, because
-this prevents the number of characters it matches from being adjusted.
-
-Arguments:
-  code           points to start of the compiled pattern
-  bracket_map    a bitmap of which brackets we are inside while testing; this
-                   handles up to substring 31; after that we just have to take
-                   the less precise approach
-  cb             points to the compile data block
-  atomcount      atomic group level
-
-Returns:     TRUE or FALSE
-*/
-
-static BOOL
-is_anchored(register PCRE2_SPTR code, unsigned int bracket_map,
-  compile_block *cb, int atomcount)
-{
-do {
-   PCRE2_SPTR scode = first_significant_code(
-     code + PRIV(OP_lengths)[*code], FALSE);
-   register int op = *scode;
-
-   /* Non-capturing brackets */
-
-   if (op == OP_BRA  || op == OP_BRAPOS ||
-       op == OP_SBRA || op == OP_SBRAPOS)
-     {
-     if (!is_anchored(scode, bracket_map, cb, atomcount)) return FALSE;
-     }
-
-   /* Capturing brackets */
-
-   else if (op == OP_CBRA  || op == OP_CBRAPOS ||
-            op == OP_SCBRA || op == OP_SCBRAPOS)
-     {
-     int n = GET2(scode, 1+LINK_SIZE);
-     int new_map = bracket_map | ((n < 32)? (1u << n) : 1);
-     if (!is_anchored(scode, new_map, cb, atomcount)) return FALSE;
-     }
-
-   /* Positive forward assertions and conditions */
-
-   else if (op == OP_ASSERT || op == OP_COND)
-     {
-     if (!is_anchored(scode, bracket_map, cb, atomcount)) return FALSE;
-     }
-
-   /* Atomic groups */
-
-   else if (op == OP_ONCE || op == OP_ONCE_NC)
-     {
-     if (!is_anchored(scode, bracket_map, cb, atomcount + 1))
-       return FALSE;
-     }
-
-   /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
-   it isn't in brackets that are or may be referenced or inside an atomic
-   group. There is also an option that disables auto-anchoring. */
-
-   else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
-             op == OP_TYPEPOSSTAR))
-     {
-     if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 ||
-         atomcount > 0 || cb->had_pruneorskip ||
-         (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)
-       return FALSE;
-     }
-
-   /* Check for explicit anchoring */
-
-   else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
-
-   code += GET(code, 1);
-   }
-while (*code == OP_ALT);   /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-*         Check for starting with ^ or .*        *
-*************************************************/
-
-/* This is called to find out if every branch starts with ^ or .* so that
-"first char" processing can be done to speed things up in multiline
-matching and for non-DOTALL patterns that start with .* (which must start at
-the beginning or after \n). As in the case of is_anchored() (see above), we
-have to take account of back references to capturing brackets that contain .*
-because in that case we can't make the assumption. Also, the appearance of .*
-inside atomic brackets or in a pattern that contains *PRUNE or *SKIP does not
-count, because once again the assumption no longer holds.
-
-Arguments:
-  code           points to start of the compiled pattern or a group
-  bracket_map    a bitmap of which brackets we are inside while testing; this
-                   handles up to substring 31; after that we just have to take
-                   the less precise approach
-  cb             points to the compile data
-  atomcount      atomic group level
-
-Returns:         TRUE or FALSE
-*/
-
-static BOOL
-is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb,
-  int atomcount)
-{
-do {
-   PCRE2_SPTR scode = first_significant_code(
-     code + PRIV(OP_lengths)[*code], FALSE);
-   register int op = *scode;
-
-   /* If we are at the start of a conditional assertion group, *both* the
-   conditional assertion *and* what follows the condition must satisfy the test
-   for start of line. Other kinds of condition fail. Note that there may be an
-   auto-callout at the start of a condition. */
-
-   if (op == OP_COND)
-     {
-     scode += 1 + LINK_SIZE;
-
-     if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
-       else if (*scode == OP_CALLOUT_STR) scode += GET(scode, 1 + 2*LINK_SIZE);
-
-     switch (*scode)
-       {
-       case OP_CREF:
-       case OP_DNCREF:
-       case OP_RREF:
-       case OP_DNRREF:
-       case OP_FAIL:
-       case OP_FALSE:
-       case OP_TRUE:
-       return FALSE;
-
-       default:     /* Assertion */
-       if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE;
-       do scode += GET(scode, 1); while (*scode == OP_ALT);
-       scode += 1 + LINK_SIZE;
-       break;
-       }
-     scode = first_significant_code(scode, FALSE);
-     op = *scode;
-     }
-
-   /* Non-capturing brackets */
-
-   if (op == OP_BRA  || op == OP_BRAPOS ||
-       op == OP_SBRA || op == OP_SBRAPOS)
-     {
-     if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE;
-     }
-
-   /* Capturing brackets */
-
-   else if (op == OP_CBRA  || op == OP_CBRAPOS ||
-            op == OP_SCBRA || op == OP_SCBRAPOS)
-     {
-     int n = GET2(scode, 1+LINK_SIZE);
-     int new_map = bracket_map | ((n < 32)? (1u << n) : 1);
-     if (!is_startline(scode, new_map, cb, atomcount)) return FALSE;
-     }
-
-   /* Positive forward assertions */
-
-   else if (op == OP_ASSERT)
-     {
-     if (!is_startline(scode, bracket_map, cb, atomcount)) return FALSE;
-     }
-
-   /* Atomic brackets */
-
-   else if (op == OP_ONCE || op == OP_ONCE_NC)
-     {
-     if (!is_startline(scode, bracket_map, cb, atomcount + 1)) return FALSE;
-     }
-
-   /* .* means "start at start or after \n" if it isn't in atomic brackets or
-   brackets that may be referenced, as long as the pattern does not contain
-   *PRUNE or *SKIP, because these break the feature. Consider, for example,
-   /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab", i.e. not at the
-   start of a line. There is also an option that disables this optimization. */
-
-   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 ||
-         (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)
-       return FALSE;
-     }
-
-   /* Check for explicit circumflex; anything else gives a FALSE result. Note
-   in particular that this includes atomic brackets OP_ONCE and OP_ONCE_NC
-   because the number of characters matched by .* cannot be adjusted inside
-   them. */
-
-   else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
-
-   /* Move on to the next alternative */
-
-   code += GET(code, 1);
-   }
-while (*code == OP_ALT);  /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
 *    Check for asserted fixed first code unit    *
 *************************************************/
 
@@ -8150,15 +8106,15 @@
 Arguments:
   code       points to start of compiled pattern
   flags      points to the first code unit flags
-  inassert   TRUE if in an assertion
+  inassert   non-zero if in an assertion
 
 Returns:     the fixed first code unit, or 0 with REQ_NONE in flags
 */
 
 static uint32_t
-find_firstassertedcu(PCRE2_SPTR code, int32_t *flags, BOOL inassert)
+find_firstassertedcu(PCRE2_SPTR code, int32_t *flags, uint32_t inassert)
 {
-register uint32_t c = 0;
+uint32_t c = 0;
 int cflags = REQ_NONE;
 
 *flags = REQ_NONE;
@@ -8168,7 +8124,7 @@
    int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
              *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
    PCRE2_SPTR scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE);
-   register PCRE2_UCHAR op = *scode;
+   PCRE2_UCHAR op = *scode;
 
    switch(op)
      {
@@ -8183,8 +8139,7 @@
      case OP_SCBRAPOS:
      case OP_ASSERT:
      case OP_ONCE:
-     case OP_ONCE_NC:
-     d = find_firstassertedcu(scode, &dflags, op == OP_ASSERT);
+     d = find_firstassertedcu(scode, &dflags, inassert + ((op==OP_ASSERT)?1:0));
      if (dflags < 0)
        return 0;
      if (cflags < 0) { c = d; cflags = dflags; }
@@ -8199,7 +8154,7 @@
      case OP_PLUS:
      case OP_MINPLUS:
      case OP_POSPLUS:
-     if (!inassert) return 0;
+     if (inassert == 0) return 0;
      if (cflags < 0) { c = scode[1]; cflags = 0; }
        else if (c != scode[1]) return 0;
      break;
@@ -8212,7 +8167,7 @@
      case OP_PLUSI:
      case OP_MINPLUSI:
      case OP_POSPLUSI:
-     if (!inassert) return 0;
+     if (inassert == 0) return 0;
      if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; }
        else if (c != scode[1]) return 0;
      break;
@@ -8241,18 +8196,19 @@
   name         the name to add
   length       the length of the name
   groupno      the group number
+  tablecount   the count of names in the table so far
 
 Returns:       nothing
 */
 
 static void
 add_name_to_table(compile_block *cb, PCRE2_SPTR name, int length,
-  unsigned int groupno)
+  unsigned int groupno, uint32_t tablecount)
 {
-int i;
+uint32_t i;
 PCRE2_UCHAR *slot = cb->name_table;
 
-for (i = 0; i < cb->names_found; i++)
+for (i = 0; i < tablecount; i++)
   {
   int crc = memcmp(name, slot+IMM2_SIZE, CU2BYTES(length));
   if (crc == 0 && slot[IMM2_SIZE+length] != 0)
@@ -8266,7 +8222,7 @@
   if (crc < 0)
     {
     memmove(slot + cb->name_entry_size, slot,
-      CU2BYTES((cb->names_found - i) * cb->name_entry_size));
+      CU2BYTES((tablecount - i) * cb->name_entry_size));
     break;
     }
 
@@ -8277,7 +8233,6 @@
 
 PUT2(slot, 0, groupno);
 memcpy(slot + IMM2_SIZE, name, CU2BYTES(length));
-cb->names_found++;
 
 /* Add a terminating zero and fill the rest of the slot with zeroes so that
 the memory is all initialized. Otherwise valgrind moans about uninitialized
@@ -8290,6 +8245,723 @@
 
 
 /*************************************************
+*             Skip in parsed pattern             *
+*************************************************/
+
+/* This function is called to skip parts of the parsed pattern when finding the
+length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find
+the end of the branch, it is called to skip over an internal lookaround, and it
+is also called to skip to the end of a class, during which it will never
+encounter nested groups (but there's no need to have special code for that).
+
+When called to find the end of a branch or group, pptr must point to the first
+meta code inside the branch, not the branch-starting code. In other cases it
+can point to the item that causes the function to be called.
+
+Arguments:
+  pptr       current pointer to skip from
+  skiptype   PSKIP_CLASS when skipping to end of class
+             PSKIP_ALT when META_ALT ends the skip
+             PSKIP_KET when only META_KET ends the skip
+
+Returns:     new value of pptr
+             NULL if META_END is reached - should never occur
+               or for an unknown meta value - likewise
+*/
+
+static uint32_t *
+parsed_skip(uint32_t *pptr, uint32_t skiptype)
+{
+uint32_t nestlevel = 0;
+
+for (;; pptr++)
+  {
+  uint32_t meta = META_CODE(*pptr);
+
+  switch(meta)
+    {
+    default:  /* Just skip over most items */
+    if (meta < META_END) continue;  /* Literal */
+    break;
+
+    /* This should never occur. */
+
+    case META_END:
+    return NULL;
+
+    /* The data for these items is variable in length. */
+
+    case META_BACKREF:  /* Offset is present only if group >= 10 */
+    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;
+      }
+    break;
+
+    case META_MARK:     /* Add the length of the name. */
+    case META_PRUNE_ARG:
+    case META_SKIP_ARG:
+    case META_THEN_ARG:
+    pptr += pptr[1];
+    break;
+
+    /* These are the "active" items in this loop. */
+
+    case META_CLASS_END:
+    if (skiptype == PSKIP_CLASS) return pptr;
+    break;
+
+    case META_ATOMIC:
+    case META_CAPTURE:
+    case META_COND_ASSERT:
+    case META_COND_DEFINE:
+    case META_COND_NAME:
+    case META_COND_NUMBER:
+    case META_COND_RNAME:
+    case META_COND_RNUMBER:
+    case META_COND_VERSION:
+    case META_LOOKAHEAD:
+    case META_LOOKAHEADNOT:
+    case META_LOOKBEHIND:
+    case META_LOOKBEHINDNOT:
+    case META_NOCAPTURE:
+    nestlevel++;
+    break;
+
+    case META_ALT:
+    if (nestlevel == 0 && skiptype == PSKIP_ALT) return pptr;
+    break;
+
+    case META_KET:
+    if (nestlevel == 0) return pptr;
+    nestlevel--;
+    break;
+    }
+
+  /* The extra data item length for each meta is in a table. */
+
+  meta = (meta >> 16) & 0x7fff;
+  if (meta >= sizeof(meta_extra_lengths)) return NULL;
+  pptr += meta_extra_lengths[meta];
+  }
+/* Control never reaches here */
+return pptr;
+}
+
+
+
+/*************************************************
+*       Find length of a parsed group            *
+*************************************************/
+
+/* This is called for nested groups within a branch of a lookbehind whose
+length is being computed. If all the branches in the nested group have the same
+length, that is OK. On entry, the pointer must be at the first element after
+the group initializing code. On exit it points to OP_KET. Caching is used to
+improve processing speed when the same capturing group occurs many times.
+
+Arguments:
+  pptrptr     pointer to pointer in the parsed pattern
+  isinline    FALSE if a reference or recursion; TRUE for inline group
+  errcodeptr  pointer to the errorcode
+  lcptr       pointer to the loop counter
+  group       number of captured group or -1 for a non-capturing group
+  recurses    chain of recurse_check to catch mutual recursion
+  cb          pointer to the compile data
+
+Returns:      the group length or a negative number
+*/
+
+static int
+get_grouplength(uint32_t **pptrptr, BOOL isinline, int *errcodeptr, int *lcptr,
+  int group, parsed_recurse_check *recurses, compile_block *cb)
+{
+int branchlength;
+int grouplength = -1;
+
+/* The cache can be used only if there is no possibility of there being two
+groups with the same number. We do not need to set the end pointer for a group
+that is being processed as a back reference or recursion, but we must do so for
+an inline group. */
+
+if (group > 0 && (cb->external_flags & PCRE2_DUPCAPUSED) == 0)
+  {
+  uint32_t groupinfo = cb->groupinfo[group];
+  if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return -1;
+  if ((groupinfo & GI_SET_FIXED_LENGTH) != 0)
+    {
+    if (isinline) *pptrptr = parsed_skip(*pptrptr, PSKIP_KET);
+    return groupinfo & GI_FIXED_LENGTH_MASK;
+    }
+  }
+
+/* Scan the group. In this case we find the end pointer of necessity. */
+
+for(;;)
+  {
+  branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb);
+  if (branchlength < 0) goto ISNOTFIXED;
+  if (grouplength == -1) grouplength = branchlength;
+    else if (grouplength != branchlength) goto ISNOTFIXED;
+  if (**pptrptr == META_KET) break;
+  *pptrptr += 1;   /* Skip META_ALT */
+  }
+
+if (group > 0)
+  cb->groupinfo[group] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength);
+return grouplength;
+
+ISNOTFIXED:
+if (group > 0) cb->groupinfo[group] |= GI_NOT_FIXED_LENGTH;
+return -1;
+}
+
+
+
+/*************************************************
+*        Find length of a parsed branch          *
+*************************************************/
+
+/* Return a fixed length for a branch in a lookbehind, giving an error if the
+length is not fixed. If any lookbehinds are encountered on the way, they get
+their length set. On entry, *pptrptr points to the first element inside the
+branch. On exit it is set to point to the ALT or KET.
+
+Arguments:
+  pptrptr     pointer to pointer in the parsed pattern
+  errcodeptr  pointer to error code
+  lcptr       pointer to loop counter
+  recurses    chain of recurse_check to catch mutual recursion
+  cb          pointer to compile block
+
+Returns:      the length, or a negative value on error
+*/
+
+static int
+get_branchlength(uint32_t **pptrptr, int *errcodeptr, int *lcptr,
+  parsed_recurse_check *recurses, compile_block *cb)
+{
+int branchlength = 0;
+int grouplength;
+uint32_t lastitemlength = 0;
+uint32_t *pptr = *pptrptr;
+PCRE2_SIZE offset;
+parsed_recurse_check this_recurse;
+
+/* A large and/or complex regex can take too long to process. This can happen
+more often when (?| groups are present in the pattern because their length
+cannot be cached. */
+
+if ((*lcptr)++ > 2000)
+  {
+  *errcodeptr = ERR35;  /* Lookbehind is too complicated */
+  return -1;
+  }
+
+/* Scan the branch, accumulating the length. */
+
+for (;; pptr++)
+  {
+  parsed_recurse_check *r;
+  uint32_t *gptr, *gptrend;
+  uint32_t escape;
+  uint32_t group = 0;
+  uint32_t itemlength = 0;
+
+  if (*pptr < META_END)
+    {
+    itemlength = 1;
+    }
+
+  else switch (META_CODE(*pptr))
+    {
+    case META_KET:
+    case META_ALT:
+    goto EXIT;
+
+    /* (*ACCEPT) and (*FAIL) terminate the branch, but we must skip to the
+    actual termination. */
+
+    case META_ACCEPT:
+    case META_FAIL:
+    pptr = parsed_skip(pptr, PSKIP_ALT);
+    if (pptr == NULL) goto PARSED_SKIP_FAILED;
+    goto EXIT;
+
+    case META_MARK:
+    case META_PRUNE_ARG:
+    case META_SKIP_ARG:
+    case META_THEN_ARG:
+    pptr += pptr[1] + 1;
+    break;
+
+    case META_CIRCUMFLEX:
+    case META_COMMIT:
+    case META_DOLLAR:
+    case META_PRUNE:
+    case META_SKIP:
+    case META_THEN:
+    break;
+
+    case META_OPTIONS:
+    pptr += 1;
+    break;
+
+    case META_BIGVALUE:
+    itemlength = 1;
+    pptr += 1;
+    break;
+
+    case META_CLASS:
+    case META_CLASS_NOT:
+    itemlength = 1;
+    pptr = parsed_skip(pptr, PSKIP_CLASS);
+    if (pptr == NULL) goto PARSED_SKIP_FAILED;
+    break;
+
+    case META_CLASS_EMPTY_NOT:
+    case META_DOT:
+    itemlength = 1;
+    break;
+
+    case META_CALLOUT_NUMBER:
+    pptr += 3;
+    break;
+
+    case META_CALLOUT_STRING:
+    pptr += 3 + SIZEOFFSET;
+    break;
+
+    /* Only some escapes consume a character. Of those, \R and \X are never
+    allowed because they might match more than character. \C is allowed only in
+    32-bit and non-UTF 8/16-bit modes. */
+
+    case META_ESCAPE:
+    escape = META_DATA(*pptr);
+    if (escape == ESC_R || escape == ESC_X) return -1;
+    if (escape > ESC_b && escape < ESC_Z)
+      {
+#if PCRE2_CODE_UNIT_WIDTH != 32
+      if ((cb->external_options & PCRE2_UTF) != 0 && escape == ESC_C)
+        {
+        *errcodeptr = ERR36;
+        return -1;
+        }
+#endif
+      itemlength = 1;
+      if (escape == ESC_p || escape == ESC_P) pptr++;  /* Skip prop data */
+      }
+    break;
+
+    /* Lookaheads can be ignored, but we must start the skip inside the group
+    so that it isn't treated as a group within the branch. */
+
+    case META_LOOKAHEAD:
+    case META_LOOKAHEADNOT:
+    pptr = parsed_skip(pptr + 1, PSKIP_KET);
+    if (pptr == NULL) goto PARSED_SKIP_FAILED;
+    break;
+
+    /* Lookbehinds can be ignored, but must themselves be checked. */
+
+    case META_LOOKBEHIND:
+    case META_LOOKBEHINDNOT:
+    if (!set_lookbehind_lengths(&pptr, errcodeptr, lcptr, recurses, cb))
+      return -1;
+    break;
+
+    /* Back references and recursions are handled by very similar code. At this
+    stage, the names generated in the parsing pass are available, but the main
+    name table has not yet been created. So for the named varieties, scan the
+    list of names in order to get the number of the first one in the pattern,
+    and whether or not this name is duplicated. */
+
+    case META_BACKREF_BYNAME:
+    if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0)
+      goto ISNOTFIXED;
+    /* Fall through */
+
+    case META_RECURSE_BYNAME:
+      {
+      int i;
+      PCRE2_SPTR name;
+      BOOL is_dupname = FALSE;
+      named_group *ng = cb->named_groups;
+      uint32_t meta_code = META_CODE(*pptr);
+      uint32_t length = *(++pptr);
+
+      GETPLUSOFFSET(offset, pptr);
+      name = cb->start_pattern + offset;
+      for (i = 0; i < cb->names_found; i++, ng++)
+        {
+        if (length == ng->length && PRIV(strncmp)(name, ng->name, length) == 0)
+          {
+          group = ng->number;
+          is_dupname = ng->isdup;
+          break;
+          }
+        }
+
+      if (group == 0)
+        {
+        *errcodeptr = ERR15;  /* Non-existent subpattern */
+        cb->erroroffset = offset;
+        return -1;
+        }
+
+      /* A numerical back reference can be fixed length if duplicate capturing
+      groups are not being used. A non-duplicate named back reference can also
+      be handled. */
+
+      if (meta_code == META_RECURSE_BYNAME ||
+          (!is_dupname && (cb->external_flags & PCRE2_DUPCAPUSED) == 0))
+        goto RECURSE_OR_BACKREF_LENGTH;  /* Handle as a numbered version. */
+      }
+    goto ISNOTFIXED;                     /* Duplicate name or number */
+
+    /* The offset values for back references < 10 are in a separate vector
+    because otherwise they would use more than two parsed pattern elements on
+    64-bit systems. */
+
+    case META_BACKREF:
+    if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0 ||
+        (cb->external_flags & PCRE2_DUPCAPUSED) != 0)
+      goto ISNOTFIXED;
+    group = META_DATA(*pptr);
+    if (group < 10)
+      {
+      offset = cb->small_ref_offset[group];
+      goto RECURSE_OR_BACKREF_LENGTH;
+      }
+
+    /* Fall through */
+    /* For groups >= 10 - picking up group twice does no harm. */
+
+    /* A true recursion implies not fixed length, but a subroutine call may
+    be OK. Back reference "recursions" are also failed. */
+
+    case META_RECURSE:
+    group = META_DATA(*pptr);
+    GETPLUSOFFSET(offset, pptr);
+
+    RECURSE_OR_BACKREF_LENGTH:
+    if (group > cb->bracount)
+      {
+      cb->erroroffset = offset;
+      *errcodeptr = ERR15;  /* Non-existent subpattern */
+      return -1;
+      }
+    if (group == 0) goto ISNOTFIXED;  /* Local recursion */
+    for (gptr = cb->parsed_pattern; *gptr != META_END; gptr++)
+      {
+      if (META_CODE(*gptr) == META_BIGVALUE) gptr++;
+        else if (*gptr == (META_CAPTURE | group)) break;
+      }
+
+    /* We must start the search for the end of the group at the first meta code
+    inside the group. Otherwise it will be treated as an enclosed group. */
+
+    gptrend = parsed_skip(gptr + 1, PSKIP_KET);
+    if (gptrend == NULL) goto PARSED_SKIP_FAILED;
+    if (pptr > gptr && pptr < gptrend) goto ISNOTFIXED;  /* Local recursion */
+    for (r = recurses; r != NULL; r = r->prev) if (r->groupptr == gptr) break;
+    if (r != NULL) goto ISNOTFIXED;   /* Mutual recursion */
+    this_recurse.prev = recurses;
+    this_recurse.groupptr = gptr;
+
+    /* We do not need to know the position of the end of the group, that is,
+    gptr is not used after the call to get_grouplength(). Setting the second
+    argument FALSE stops it scanning for the end when the length can be found
+    in the cache. */
+
+    gptr++;
+    grouplength = get_grouplength(&gptr, FALSE, errcodeptr, lcptr, group,
+      &this_recurse, cb);
+    if (grouplength < 0)
+      {
+      if (*errcodeptr == 0) goto ISNOTFIXED;
+      return -1;  /* Error already set */
+      }
+    itemlength = grouplength;
+    break;
+
+    /* Check nested groups - advance past the initial data for each type and
+    then seek a fixed length with get_grouplength(). */
+
+    case META_COND_NAME:
+    case META_COND_NUMBER:
+    case META_COND_RNAME:
+    case META_COND_RNUMBER:
+    case META_COND_DEFINE:
+    pptr += 2 + SIZEOFFSET;
+    goto CHECK_GROUP;
+
+    case META_COND_ASSERT:
+    pptr += 1;
+    goto CHECK_GROUP;
+
+    case META_COND_VERSION:
+    pptr += 4;
+    goto CHECK_GROUP;
+
+    case META_CAPTURE:
+    group = META_DATA(*pptr);
+    /* Fall through */
+
+    case META_ATOMIC:
+    case META_NOCAPTURE:
+    pptr++;
+    CHECK_GROUP:
+    grouplength = get_grouplength(&pptr, TRUE, errcodeptr, lcptr, group,
+      recurses, cb);
+    if (grouplength < 0) return -1;
+    itemlength = grouplength;
+    break;
+
+    /* Exact repetition is OK; variable repetition is not. A repetition of zero
+    must subtract the length that has already been added. */
+
+    case META_MINMAX:
+    case META_MINMAX_PLUS:
+    case META_MINMAX_QUERY:
+    if (pptr[1] == pptr[2])
+      {
+      if (pptr[1] == 0) branchlength -= lastitemlength;
+        else itemlength = (pptr[1] - 1) * lastitemlength;
+      pptr += 2;
+      break;
+      }
+    /* Fall through */
+
+    /* Any other item means this branch does not have a fixed length. */
+
+    default:
+    ISNOTFIXED:
+    *errcodeptr = ERR25;   /* Not fixed length */
+    return -1;
+    }
+
+  /* Add the item length to the branchlength, and save it for use if the next
+  thing is a quantifier. */
+
+  branchlength += itemlength;
+  lastitemlength = itemlength;
+
+  /* Ensure that the length does not overflow the limit. */
+
+  if (branchlength > LOOKBEHIND_MAX)
+    {
+    *errcodeptr = ERR87;
+    return -1;
+    }
+  }
+
+EXIT:
+*pptrptr = pptr;
+if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength;
+return branchlength;
+
+PARSED_SKIP_FAILED:
+*errcodeptr = ERR90;
+return -1;
+}
+
+
+
+/*************************************************
+*        Set lengths in a lookbehind             *
+*************************************************/
+
+/* This function is called for each lookbehind, to set the lengths in its
+branches. An error occurs if any branch does not have a fixed length that is
+less than the maximum (65535). On exit, the pointer must be left on the final
+ket.
+
+Arguments:
+  pptrptr     pointer to pointer in the parsed pattern
+  errcodeptr  pointer to error code
+  lcptr       pointer to loop counter
+  recurses    chain of recurse_check to catch mutual recursion
+  cb          pointer to compile block
+
+Returns:      TRUE if all is well
+              FALSE otherwise, with error code and offset set
+*/
+
+static BOOL
+set_lookbehind_lengths(uint32_t **pptrptr, int *errcodeptr, int *lcptr,
+  parsed_recurse_check *recurses, compile_block *cb)
+{
+PCRE2_SIZE offset;
+int branchlength;
+uint32_t *bptr = *pptrptr;
+
+READPLUSOFFSET(offset, bptr);  /* Offset for error messages */
+*pptrptr += SIZEOFFSET;
+
+do
+  {
+  *pptrptr += 1;
+  branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb);
+  if (branchlength < 0)
+    {
+    /* The errorcode and offset may already be set from a nested lookbehind. */
+    if (*errcodeptr == 0) *errcodeptr = ERR25;
+    if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset;
+    return FALSE;
+    }
+  *bptr |= branchlength;  /* branchlength never more than 65535 */
+  bptr = *pptrptr;
+  }
+while (*bptr == META_ALT);
+
+return TRUE;
+}
+
+
+
+/*************************************************
+*         Check parsed pattern lookbehinds       *
+*************************************************/
+
+/* This function is called at the end of parsing a pattern if any lookbehinds
+were encountered. It scans the parsed pattern for them, calling
+set_lookbehind_lengths() for each one. At the start, the errorcode is zero and
+the error offset is marked unset. The enables the functions above not to
+override settings from deeper nestings.
+
+Arguments cb      points to the compile block
+Returns:          0 on success, or an errorcode (cb->erroroffset will be set)
+*/
+
+static int
+check_lookbehinds(compile_block *cb)
+{
+uint32_t *pptr;
+int errorcode = 0;
+int loopcount = 0;
+
+cb->erroroffset = PCRE2_UNSET;
+
+for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
+  {
+  if (*pptr < META_END) continue;  /* Literal */
+
+  switch (META_CODE(*pptr))
+    {
+    default:
+    return ERR70;  /* Unrecognized meta code */
+
+    case META_ESCAPE:
+    if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p)
+      pptr += 1;
+    break;
+
+    case META_ACCEPT:
+    case META_ALT:
+    case META_ASTERISK:
+    case META_ASTERISK_PLUS:
+    case META_ASTERISK_QUERY:
+    case META_ATOMIC:
+    case META_BACKREF:
+    case META_CAPTURE:
+    case META_CIRCUMFLEX:
+    case META_CLASS:
+    case META_CLASS_EMPTY:
+    case META_CLASS_EMPTY_NOT:
+    case META_CLASS_END:
+    case META_CLASS_NOT:
+    case META_COMMIT:
+    case META_COND_ASSERT:
+    case META_DOLLAR:
+    case META_DOT:
+    case META_FAIL:
+    case META_KET:
+    case META_LOOKAHEAD:
+    case META_LOOKAHEADNOT:
+    case META_NOCAPTURE:
+    case META_PLUS:
+    case META_PLUS_PLUS:
+    case META_PLUS_QUERY:
+    case META_PRUNE:
+    case META_QUERY:
+    case META_QUERY_PLUS:
+    case META_QUERY_QUERY:
+    case META_RANGE_ESCAPED:
+    case META_RANGE_LITERAL:
+    case META_SKIP:
+    case META_THEN:
+    break;
+
+    case META_RECURSE:
+    pptr += SIZEOFFSET;
+    break;
+
+    case META_BACKREF_BYNAME:
+    case META_COND_DEFINE:
+    case META_COND_NAME:
+    case META_COND_NUMBER:
+    case META_COND_RNAME:
+    case META_COND_RNUMBER:
+    case META_RECURSE_BYNAME:
+    pptr += 1 + SIZEOFFSET;
+    break;
+
+    case META_CALLOUT_STRING:
+    pptr += 3 + SIZEOFFSET;
+    break;
+
+    case META_BIGVALUE:
+    case META_OPTIONS:
+    case META_POSIX:
+    case META_POSIX_NEG:
+    pptr += 1;
+    break;
+
+    case META_MINMAX:
+    case META_MINMAX_QUERY:
+    case META_MINMAX_PLUS:
+    pptr += 2;
+    break;
+
+    case META_CALLOUT_NUMBER:
+    case META_COND_VERSION:
+    pptr += 3;
+    break;
+
+    case META_MARK:
+    case META_PRUNE_ARG:
+    case META_SKIP_ARG:
+    case META_THEN_ARG:
+    pptr += 1 + pptr[1];
+    break;
+
+    case META_LOOKBEHIND:
+    case META_LOOKBEHINDNOT:
+    if (!set_lookbehind_lengths(&pptr, &errorcode, &loopcount, NULL, cb))
+      return errorcode;
+    break;
+    }
+  }
+
+return 0;
+}
+
+
+
+/*************************************************
 *     External function to compile a pattern     *
 *************************************************/
 
@@ -8312,43 +8984,51 @@
 pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options,
    int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext)
 {
-BOOL utf;                               /* Set TRUE for UTF mode */
-pcre2_real_code *re = NULL;             /* What we will return */
-compile_block cb;                       /* "Static" compile-time data */
-const uint8_t *tables;                  /* Char tables base pointer */
+BOOL utf;                             /* Set TRUE for UTF mode */
+BOOL has_lookbehind = FALSE;          /* Set TRUE if a lookbehind is found */
+BOOL zero_terminated;                 /* Set TRUE for zero-terminated pattern */
+pcre2_real_code *re = NULL;           /* What we will return */
+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_SPTR ptr;                         /* Current pointer in pattern */
+PCRE2_UCHAR *code;                    /* Current pointer in compiled code */
+PCRE2_SPTR codestart;                 /* Start of compiled code */
+PCRE2_SPTR ptr;                       /* Current pointer in pattern */
+uint32_t *pptr;                       /* Current pointer in parsed pattern */
 
-size_t length = 1;                      /* Allow or final END opcode */
-size_t usedlength;                      /* Actual length used */
-size_t re_blocksize;                    /* Size of memory block */
+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 */
 
-int32_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 */
+int32_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 skipatstart;                   /* When checking (*UTF) etc */
-uint32_t limit_match = UINT32_MAX;      /* Unset match limits */
-uint32_t limit_recursion = UINT32_MAX;
+uint32_t skipatstart;                 /* When checking (*UTF) etc */
+uint32_t limit_heap  = UINT32_MAX;
+uint32_t limit_match = UINT32_MAX;    /* Unset match limits */
+uint32_t limit_depth = UINT32_MAX;
 
-int newline = 0;                        /* Unset; can be set by the pattern */
-int bsr = 0;                            /* Unset; can be set by the pattern */
-int errorcode = 0;                      /* Initialize to avoid compiler warn */
+int newline = 0;                      /* Unset; can be set by the pattern */
+int bsr = 0;                          /* Unset; can be set by the pattern */
+int errorcode = 0;                    /* Initialize to avoid compiler warn */
+int regexrc;                          /* Return from compile */
+
+uint32_t i;                           /* Local loop counter */
 
 /* Comments at the head of this file explain about these variables. */
 
-PCRE2_UCHAR *copied_pattern = NULL;
-PCRE2_UCHAR stack_copied_pattern[COPIED_PATTERN_SIZE];
+uint32_t stack_groupinfo[GROUPINFO_DEFAULT_SIZE];
+uint32_t stack_parsed_pattern[PARSED_PATTERN_DEFAULT_SIZE];
 named_group named_groups[NAMED_GROUP_LIST_SIZE];
 
 /* The workspace is used in different ways in the different compiling phases.
-It needs to be 16-bit aligned for the preliminary group scan, and 32-bit
-aligned for the group information cache. */
+It needs to be 16-bit aligned for the preliminary parsing scan. */
 
-uint32_t c32workspace[C32_WORK_SIZE];
-PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c32workspace;
+uint32_t c16workspace[C16_WORK_SIZE];
+PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c16workspace;
 
 
 /* -------------- Check arguments and set up the pattern ----------------- */
@@ -8367,57 +9047,44 @@
   return NULL;
   }
 
-/* Check that all undefined public option bits are zero. */
-
-if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
-  {
-  *errorptr = ERR17;
-  return NULL;
-  }
-
 /* A NULL compile context means "use a default context" */
 
 if (ccontext == NULL)
   ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context));
 
-/* A zero-terminated pattern is indicated by the special length value
-PCRE2_ZERO_TERMINATED. Otherwise, we make a copy of the pattern and add a zero,
-to ensure that it is always possible to look one code unit beyond the end of
-the pattern's characters. In both cases, check that the pattern is overlong. */
+/* Check that all undefined public option bits are zero. */
 
-if (patlen == PCRE2_ZERO_TERMINATED)
+if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0 ||
+    (ccontext->extra_options & ~PUBLIC_COMPILE_EXTRA_OPTIONS) != 0)
   {
+  *errorptr = ERR17;
+  return NULL;
+  }
+
+if ((options & PCRE2_LITERAL) != 0 &&
+    ((options & ~PUBLIC_LITERAL_COMPILE_OPTIONS) != 0 ||
+     (ccontext->extra_options & ~PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS) != 0))
+  {
+  *errorptr = ERR92;
+  return NULL;
+  }
+
+/* A zero-terminated pattern is indicated by the special length value
+PCRE2_ZERO_TERMINATED. Check for an overlong pattern. */
+
+if ((zero_terminated = (patlen == PCRE2_ZERO_TERMINATED)))
   patlen = PRIV(strlen)(pattern);
-  if (patlen > ccontext->max_pattern_length)
-    {
-    *errorptr = ERR88;
-    return NULL;
-    }
-  }
-else
+
+if (patlen > ccontext->max_pattern_length)
   {
-  if (patlen > ccontext->max_pattern_length)
-    {
-    *errorptr = ERR88;
-    return NULL;
-    }
-  if (patlen < COPIED_PATTERN_SIZE)
-    copied_pattern = stack_copied_pattern;
-  else
-    {
-    copied_pattern = ccontext->memctl.malloc(CU2BYTES(patlen + 1),
-      ccontext->memctl.memory_data);
-    if (copied_pattern == NULL)
-      {
-      *errorptr = ERR21;
-      return NULL;
-      }
-    }
-  memcpy(copied_pattern, pattern, CU2BYTES(patlen));
-  copied_pattern[patlen] = 0;
-  pattern = copied_pattern;
+  *errorptr = ERR88;
+  return NULL;
   }
 
+/* From here on, all returns from this function should end up going via the
+EXIT label. */
+
+
 /* ------------ Initialize the "static" compile data -------------- */
 
 tables = (ccontext->tables != NULL)? ccontext->tables : PRIV(default_tables);
@@ -8428,16 +9095,16 @@
 cb.ctypes = tables + ctypes_offset;
 
 cb.assert_depth = 0;
-cb.bracount = cb.final_bracount = 0;
+cb.bracount = 0;
 cb.cx = ccontext;
 cb.dupnames = FALSE;
 cb.end_pattern = pattern + patlen;
-cb.nestptr[0] = cb.nestptr[1] = NULL;
+cb.erroroffset = 0;
 cb.external_flags = 0;
 cb.external_options = options;
-cb.groupinfo = c32workspace;
+cb.groupinfo = stack_groupinfo;
 cb.had_recurse = FALSE;
-cb.iscondassert = FALSE;
+cb.lastcapture = 0;
 cb.max_lookbehind = 0;
 cb.name_entry_size = 0;
 cb.name_table = NULL;
@@ -8446,6 +9113,7 @@
 cb.names_found = 0;
 cb.open_caps = NULL;
 cb.parens_depth = 0;
+cb.parsed_pattern = stack_parsed_pattern;
 cb.req_varyopt = 0;
 cb.start_code = cworkspace;
 cb.start_pattern = pattern;
@@ -8459,77 +9127,103 @@
 cb.top_backref = 0;
 cb.backref_map = 0;
 
+/* Escape sequences \1 to \9 are always back references, but as they are only
+two characters long, only two elements can be used in the parsed_pattern
+vector. The first contains the reference, and we'd like to use the second to
+record the offset in the pattern, so that forward references to non-existent
+groups can be diagnosed later with an offset. However, on 64-bit systems,
+PCRE2_SIZE won't fit. Instead, we have a vector of offsets for the first
+occurrence of \1 to \9, indexed by the second parsed_pattern value. All other
+references have enough space for the offset to be put into the parsed pattern.
+*/
+
+for (i = 0; i < 10; i++) cb.small_ref_offset[i] = PCRE2_UNSET;
+
+
 /* --------------- Start looking at the pattern --------------- */
 
-/* Check for global one-time option settings at the start of the pattern, and
-remember the offset to the actual regex. */
+/* Unless PCRE2_LITERAL is set, check for global one-time option settings at
+the start of the pattern, and remember the offset to the actual regex. With
+valgrind support, make the terminator of a zero-terminated pattern
+inaccessible. This catches bugs that would otherwise only show up for
+non-zero-terminated patterns. */
+
+#ifdef SUPPORT_VALGRIND
+if (zero_terminated) VALGRIND_MAKE_MEM_NOACCESS(pattern + patlen, CU2BYTES(1));
+#endif
 
 ptr = pattern;
 skipatstart = 0;
 
-while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
-       ptr[skipatstart+1] == CHAR_ASTERISK)
+if ((options & PCRE2_LITERAL) == 0)
   {
-  unsigned int i;
-  for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++)
+  while (patlen - skipatstart >= 2 &&
+         ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
+         ptr[skipatstart+1] == CHAR_ASTERISK)
     {
-    pso *p = pso_list + i;
-
-    if (PRIV(strncmp_c8)(ptr+skipatstart+2, (char *)(p->name), p->length) == 0)
+    for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++)
       {
       uint32_t c, pp;
+      pso *p = pso_list + i;
 
-      skipatstart += p->length + 2;
-      switch(p->type)
+      if (patlen - skipatstart - 2 >= p->length &&
+          PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name),
+            p->length) == 0)
         {
-        case PSO_OPT:
-        cb.external_options |= p->value;
-        break;
-
-        case PSO_FLG:
-        setflags |= p->value;
-        break;
-
-        case PSO_NL:
-        newline = p->value;
-        setflags |= PCRE2_NL_SET;
-        break;
-
-        case PSO_BSR:
-        bsr = p->value;
-        setflags |= PCRE2_BSR_SET;
-        break;
-
-        case PSO_LIMM:
-        case PSO_LIMR:
-        c = 0;
-        pp = skipatstart;
-        if (!IS_DIGIT(ptr[pp]))
+        skipatstart += p->length + 2;
+        switch(p->type)
           {
-          errorcode = ERR60;
-          ptr += pp;
-          goto HAD_ERROR;
+          case PSO_OPT:
+          cb.external_options |= p->value;
+          break;
+
+          case PSO_FLG:
+          setflags |= p->value;
+          break;
+
+          case PSO_NL:
+          newline = p->value;
+          setflags |= PCRE2_NL_SET;
+          break;
+
+          case PSO_BSR:
+          bsr = p->value;
+          setflags |= PCRE2_BSR_SET;
+          break;
+
+          case PSO_LIMM:
+          case PSO_LIMD:
+          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]))
+            {
+            if (c > UINT32_MAX / 10 - 1) break;   /* Integer overflow */
+            c = c*10 + (ptr[pp++] - CHAR_0);
+            }
+          if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS)
+            {
+            errorcode = ERR60;
+            ptr += pp;
+            goto HAD_EARLY_ERROR;
+            }
+          if (p->type == PSO_LIMH) limit_heap = c;
+            else if (p->type == PSO_LIMM) limit_match = c;
+            else limit_depth = c;
+          skipatstart += pp - skipatstart;
+          break;
           }
-        while (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)
-          {
-          errorcode = ERR60;
-          ptr += pp;
-          goto HAD_ERROR;
-          }
-        if (p->type == PSO_LIMM) limit_match = c;
-          else limit_recursion = c;
-        skipatstart += pp - skipatstart;
-        break;
+        break;   /* Out of the table scan loop */
         }
-      break;   /* Out of the table scan loop */
       }
+    if (i >= sizeof(pso_list)/sizeof(pso)) break;   /* Out of pso loop */
     }
-  if (i >= sizeof(pso_list)/sizeof(pso)) break;   /* Out of pso loop */
   }
 
 /* End of pattern-start options; advance to start of real regex. */
@@ -8542,12 +9236,14 @@
 if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0)
   {
   errorcode = ERR32;
-  goto HAD_ERROR;
+  goto HAD_EARLY_ERROR;
   }
 #endif
 
 /* Check UTF. We have the original options in 'options', with that value as
-modified by (*UTF) etc in cb->external_options. */
+modified by (*UTF) etc in cb->external_options. The extra option
+PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not permitted in UTF-16 mode because the
+surrogate code points cannot be represented in UTF-16. */
 
 utf = (cb.external_options & PCRE2_UTF) != 0;
 if (utf)
@@ -8555,11 +9251,19 @@
   if ((options & PCRE2_NEVER_UTF) != 0)
     {
     errorcode = ERR74;
-    goto HAD_ERROR;
+    goto HAD_EARLY_ERROR;
     }
   if ((options & PCRE2_NO_UTF_CHECK) == 0 &&
        (errorcode = PRIV(valid_utf)(pattern, patlen, erroroffset)) != 0)
-    goto HAD_UTF_ERROR;
+    goto HAD_ERROR;  /* Offset was set by valid_utf() */
+
+#if PCRE2_CODE_UNIT_WIDTH == 16
+  if ((ccontext->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) != 0)
+    {
+    errorcode = ERR91;
+    goto HAD_EARLY_ERROR;
+    }
+#endif
   }
 
 /* Check UCP lockout. */
@@ -8568,7 +9272,7 @@
     (PCRE2_UCP|PCRE2_NEVER_UCP))
   {
   errorcode = ERR75;
-  goto HAD_ERROR;
+  goto HAD_EARLY_ERROR;
   }
 
 /* Process the BSR setting. */
@@ -8591,6 +9295,11 @@
   cb.nl[0] = CHAR_NL;
   break;
 
+  case PCRE2_NEWLINE_NUL:
+  cb.nllen = 1;
+  cb.nl[0] = CHAR_NUL;
+  break;
+
   case PCRE2_NEWLINE_CRLF:
   cb.nllen = 2;
   cb.nl[0] = CHAR_CR;
@@ -8607,23 +9316,107 @@
 
   default:
   errorcode = ERR56;
-  goto HAD_ERROR;
+  goto HAD_EARLY_ERROR;
   }
 
-/* Before we do anything else, do a pre-scan of the pattern in order to
-discover the named groups and their numerical equivalents, so that this
-information is always available for the remaining processing. */
+/* Pre-scan the pattern to do two things: (1) Discover the named groups and
+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).
 
-errorcode = scan_for_captures(&ptr, cb.external_options, &cb);
-if (errorcode != 0) goto HAD_ERROR;
+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. */
 
-/* For obscure debugging this code can be enabled. */
-
-#if 0
+#if PCRE2_CODE_UNIT_WIDTH == 32
+if (!utf)
   {
-  int i;
+  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. 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 = patlen - skipatstart + big32count;
+
+if ((ccontext->extra_options &
+     (PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_MATCH_LINE)) != 0)
+  parsed_size_needed += 4;
+
+if ((options & PCRE2_AUTO_CALLOUT) != 0)
+  parsed_size_needed = (parsed_size_needed + 1) * 5;
+
+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);
+  if (heap_parsed_pattern == NULL)
+    {
+    *errorptr = ERR21;
+    goto EXIT;
+    }
+  cb.parsed_pattern = heap_parsed_pattern;
+  }
+cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1;
+
+/* Do the parsing scan. */
+
+errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb);
+if (errorcode != 0) goto HAD_CB_ERROR;
+
+/* Workspace is needed to remember information about numbered groups: whether a
+group can match an empty string and what its fixed length is. This is done to
+avoid the possibility of recursive references causing very long compile times
+when checking these features. Unnumbered groups do not have this exposure since
+they cannot be referenced. We use an indexed vector for this purpose. If there
+are sufficiently few groups, the default vector on the stack, as set up above,
+can be used. Otherwise we have to get/free a special vector. The vector must be
+initialized to zero. */
+
+if (cb.bracount >= GROUPINFO_DEFAULT_SIZE)
+  {
+  cb.groupinfo = ccontext->memctl.malloc(
+    (cb.bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data);
+  if (cb.groupinfo == NULL)
+    {
+    errorcode = ERR21;
+    cb.erroroffset = 0;
+    goto HAD_CB_ERROR;
+    }
+  }
+memset(cb.groupinfo, 0, (cb.bracount + 1) * sizeof(uint32_t));
+
+/* If there were any lookbehinds, scan the parsed pattern to figure out their
+lengths. */
+
+if (has_lookbehind)
+  {
+  errorcode = check_lookbehinds(&cb);
+  if (errorcode != 0) goto HAD_CB_ERROR;
+  }
+
+/* For debugging, there is a function that shows the parsed data vector. */
+
+#ifdef DEBUG_SHOW_PARSED
+fprintf(stderr, "+++ Pre-scan complete:\n");
+show_parsed(&cb);
+#endif
+
+/* For debugging capturing information this code can be enabled. */
+
+#ifdef DEBUG_SHOW_CAPTURES
+  {
   named_group *ng = cb.named_groups;
-  fprintf(stderr, "+++Captures: %d\n", cb.final_bracount);
+  fprintf(stderr, "+++Captures: %d\n", cb.bracount);
   for (i = 0; i < cb.names_found; i++, ng++)
     {
     fprintf(stderr, "+++%3d %.*s\n", ng->number, ng->length, ng->name);
@@ -8631,12 +9424,6 @@
   }
 #endif
 
-/* Reset current bracket count to zero and current pointer to the start of the
-pattern. */
-
-cb.bracount = 0;
-ptr = pattern + skipatstart;
-
 /* Pretend to compile the pattern while actually just accumulating the amount
 of memory required in the 'length' variable. This behaviour is triggered by
 passing a non-NULL final argument to compile_regex(). We pass a block of
@@ -8645,24 +9432,26 @@
 workspace will never overflow, though there is a test for its doing so.
 
 On error, errorcode will be set non-zero, so we don't need to look at the
-result of the function. The initial options have been put into the cb block so
-that they can be changed if an option setting is found within the regex right
-at the beginning. Bringing initial option settings outside can help speed up
-starting point checks. We still have to pass a separate options variable (the
-first argument) because that may change as the pattern is processed. */
+result of the function. The initial options have been put into the cb block,
+but we still have to pass a separate options variable (the first argument)
+because the options may change as the pattern is processed. */
 
+cb.erroroffset = patlen;   /* For any subsequent errors that do not set it */
+pptr = cb.parsed_pattern;
 code = cworkspace;
 *code = OP_BRA;
 
-(void)compile_regex(cb.external_options, &code, &ptr, &errorcode, FALSE,
-  FALSE, 0, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL,
-  &cb, &length);
+(void)compile_regex(cb.external_options, &code, &pptr, &errorcode, 0, &firstcu,
+   &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, &length);
 
-if (errorcode != 0) goto HAD_ERROR;
+if (errorcode != 0) goto HAD_CB_ERROR;  /* Offset is in cb.erroroffset */
+
+/* This should be caught in compile_regex(), but just in case... */
+
 if (length > MAX_PATTERN_SIZE)
   {
   errorcode = ERR20;
-  goto HAD_ERROR;
+  goto HAD_CB_ERROR;
   }
 
 /* Compute the size of, and then get and initialize, the data block for storing
@@ -8671,15 +9460,23 @@
 cb.name_entry_size. */
 
 re_blocksize = sizeof(pcre2_real_code) +
-  CU2BYTES(length + cb.names_found * cb.name_entry_size);
+  CU2BYTES(length +
+  (PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size);
 re = (pcre2_real_code *)
   ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);
 if (re == NULL)
   {
   errorcode = ERR21;
-  goto HAD_ERROR;
+  goto HAD_CB_ERROR;
   }
 
+/* The compiler may put padding at the end of the pcre2_real_code structure in
+order to round it up to a multiple of 4 or 8 bytes. This means that when a
+compiled pattern is copied (for example, when serialized) undefined bytes are
+read, and this annoys debuggers such as valgrind. To avoid this, we explicitly
+write to the last 8 bytes of the structure before setting the fields. */
+
+memset((char *)re + sizeof(pcre2_real_code) - 8, 0, 8);
 re->memctl = ccontext->memctl;
 re->tables = tables;
 re->executable_jit = NULL;
@@ -8688,9 +9485,11 @@
 re->magic_number = MAGIC_NUMBER;
 re->compile_options = options;
 re->overall_options = cb.external_options;
+re->extra_options = ccontext->extra_options;
 re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags;
+re->limit_heap = limit_heap;
 re->limit_match = limit_match;
-re->limit_recursion = limit_recursion;
+re->limit_depth = limit_depth;
 re->first_codeunit = 0;
 re->last_codeunit = 0;
 re->bsr_convention = bsr;
@@ -8708,44 +9507,19 @@
 codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) +
   re->name_entry_size * re->name_count;
 
-/* Workspace is needed to remember information about numbered groups: whether a
-group can match an empty string and what its fixed length is. This is done to
-avoid the possibility of recursive references causing very long compile times
-when checking these features. Unnumbered groups do not have this exposure since
-they cannot be referenced. We use an indexed vector for this purpose. If there
-are sufficiently few groups, it can be the c32workspace vector, as set up
-above. Otherwise we have to get/free a special vector. The vector must be
-initialized to zero. */
-
-if (cb.final_bracount >= C32_WORK_SIZE)
-  {
-  cb.groupinfo = ccontext->memctl.malloc(
-    (cb.final_bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data);
-  if (cb.groupinfo == NULL)
-    {
-    errorcode = ERR21;
-    goto HAD_ERROR;
-    }
-  }
-memset(cb.groupinfo, 0, (cb.final_bracount + 1) * sizeof(uint32_t));
-
 /* 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
 compile data block. The start/end pattern and initial options are already set
-from the pre-compile phase, as is the name_entry_size field. Reset the bracket
-count and the names_found field. */
+from the pre-compile phase, as is the name_entry_size field. */
 
 cb.parens_depth = 0;
 cb.assert_depth = 0;
-cb.bracount = 0;
-cb.max_lookbehind = 0;
+cb.lastcapture = 0;
 cb.name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));
 cb.start_code = codestart;
-cb.iscondassert = FALSE;
 cb.req_varyopt = 0;
 cb.had_accept = FALSE;
 cb.had_pruneorskip = FALSE;
-cb.check_lookbehind = FALSE;
 cb.open_caps = NULL;
 
 /* If any named groups were found, create the name/number table from the list
@@ -8753,23 +9527,21 @@
 
 if (cb.names_found > 0)
   {
-  int i = cb.names_found;
   named_group *ng = cb.named_groups;
-  cb.names_found = 0;
-  for (; i > 0; i--, ng++)
-    add_name_to_table(&cb, ng->name, ng->length, ng->number);
+  for (i = 0; i < cb.names_found; i++, ng++)
+    add_name_to_table(&cb, ng->name, ng->length, ng->number, i);
   }
 
 /* Set up a starting, non-extracting bracket, then compile the expression. On
 error, errorcode will be set non-zero, so we don't need to look at the result
 of the function here. */
 
-ptr = pattern + skipatstart;
+pptr = cb.parsed_pattern;
 code = (PCRE2_UCHAR *)codestart;
 *code = OP_BRA;
-(void)compile_regex(re->overall_options, &code, &ptr, &errorcode, FALSE, FALSE,
-   0, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL);
-
+regexrc = compile_regex(re->overall_options, &code, &pptr, &errorcode, 0,
+  &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL);
+if (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY;
 re->top_bracket = cb.bracount;
 re->top_backref = cb.top_backref;
 re->max_lookbehind = cb.max_lookbehind;
@@ -8805,7 +9577,7 @@
   {
   PCRE2_UCHAR *rcode;
   PCRE2_SPTR rgroup;
-  int ccount = 0;
+  unsigned int ccount = 0;
   int start = RSCAN_CACHE_SIZE;
   recurse_cache rc[RSCAN_CACHE_SIZE];
 
@@ -8813,16 +9585,16 @@
        rcode != NULL;
        rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf))
     {
-    int i, p, recno;
+    int p, groupnumber;
 
-    recno = (int)GET(rcode, 1);
-    if (recno == 0) rgroup = codestart; else
+    groupnumber = (int)GET(rcode, 1);
+    if (groupnumber == 0) rgroup = codestart; else
       {
       PCRE2_SPTR search_from = codestart;
       rgroup = NULL;
       for (i = 0, p = start; i < ccount; i++, p = (p + 1) & 7)
         {
-        if (recno == rc[p].recno)
+        if (groupnumber == rc[p].groupnumber)
           {
           rgroup = rc[p].group;
           break;
@@ -8832,19 +9604,19 @@
         search time below when the new group number is greater than any of the
         previously found groups. */
 
-        if (recno > rc[p].recno) search_from = rc[p].group;
+        if (groupnumber > rc[p].groupnumber) search_from = rc[p].group;
         }
 
       if (rgroup == NULL)
         {
-        rgroup = PRIV(find_bracket)(search_from, utf, recno);
+        rgroup = PRIV(find_bracket)(search_from, utf, groupnumber);
         if (rgroup == NULL)
           {
           errorcode = ERR53;
           break;
           }
         if (--start < 0) start = RSCAN_CACHE_SIZE - 1;
-        rc[start].recno = recno;
+        rc[start].groupnumber = groupnumber;
         rc[start].group = rgroup;
         if (ccount < RSCAN_CACHE_SIZE) ccount++;
         }
@@ -8857,93 +9629,27 @@
 /* In rare debugging situations we sometimes need to look at the compiled code
 at this stage. */
 
-#ifdef CALL_PRINTINT
+#ifdef DEBUG_CALL_PRINTINT
 pcre2_printint(re, stderr, TRUE);
 fprintf(stderr, "Length=%lu Used=%lu\n", length, usedlength);
 #endif
 
-/* After a successful compile, give an error if there's back reference to a
-non-existent capturing subpattern. Then, unless disabled, check whether any
-single character iterators can be auto-possessified. The function overwrites
-the appropriate opcode values, so the type of the pointer must be cast. NOTE:
-the intermediate variable "temp" is 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. */
+/* Unless disabled, check whether any single character iterators can be
+auto-possessified. The function overwrites the appropriate opcode values, so
+the type of the pointer must be cast. NOTE: the intermediate variable "temp" is
+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)
+if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0)
   {
-  if (re->top_backref > re->top_bracket) errorcode = ERR15;
-  else if ((re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0)
-    {
-    PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;
-    if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80;
-    }
+  PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;
+  if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80;
   }
 
-/* If there were any lookbehind assertions that contained OP_RECURSE
-(recursions or subroutine calls), a flag is set for them to be checked here,
-because they may contain forward references. Actual recursions cannot be fixed
-length, but subroutine calls can. It is done like this so that those without
-OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The
-exceptional ones forgo this. We scan the pattern to check that they are fixed
-length, and set their lengths. */
+/* Failed to compile, or error while post-processing. */
 
-if (errorcode == 0 && cb.check_lookbehind)
-  {
-  PCRE2_UCHAR *cc = (PCRE2_UCHAR *)codestart;
-
-  /* Loop, searching for OP_REVERSE items, and process those that do not have
-  their length set. (Actually, it will also re-process any that have a length
-  of zero, but that is a pathological case, and it does no harm.) When we find
-  one, we temporarily terminate the branch it is in while we scan it. Note that
-  calling find_bracket() with a negative group number returns a pointer to the
-  OP_REVERSE item, not the actual lookbehind. */
-
-  for (cc = (PCRE2_UCHAR *)PRIV(find_bracket)(codestart, utf, -1);
-       cc != NULL;
-       cc = (PCRE2_UCHAR *)PRIV(find_bracket)(cc, utf, -1))
-    {
-    if (GET(cc, 1) == 0)
-      {
-      int fixed_length;
-      int count = 0;
-      PCRE2_UCHAR *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
-      int end_op = *be;
-      *be = OP_END;
-      fixed_length = find_fixedlength(cc, utf, TRUE, &cb, NULL, &count);
-      *be = end_op;
-      if (fixed_length < 0)
-        {
-        errorcode = fixed_length_errors[-fixed_length];
-        break;
-        }
-      if (fixed_length > cb.max_lookbehind) cb.max_lookbehind = fixed_length;
-      PUT(cc, 1, fixed_length);
-      }
-    cc += 1 + LINK_SIZE;
-    }
-
-  /* The previous value of the maximum lookbehind was transferred to the
-  compiled regex block above. We could have updated this value in the loop
-  above, but keep the two values in step, just in case some later code below
-  uses the cb value. */
-
-  re->max_lookbehind = cb.max_lookbehind;
-  }
-
-/* Failed to compile, or error while post-processing. Earlier errors get here
-via the dreaded goto. */
-
-if (errorcode != 0)
-  {
-  HAD_ERROR:
-  *erroroffset = (int)(ptr - pattern);
-  HAD_UTF_ERROR:
-  *errorptr = errorcode;
-  pcre2_code_free(re);
-  re = NULL;
-  goto EXIT;
-  }
+if (errorcode != 0) goto HAD_CB_ERROR;
 
 /* Successful compile. If the anchored option was not passed, set it if
 we can determine that the pattern is anchored by virtue of ^ characters or \A
@@ -8952,19 +9658,24 @@
 disable this case). */
 
 if ((re->overall_options & PCRE2_ANCHORED) == 0 &&
-     is_anchored(codestart, 0, &cb, 0))
+     is_anchored(codestart, 0, &cb, 0, FALSE))
   re->overall_options |= PCRE2_ANCHORED;
 
-/* If the pattern is still not anchored and we do not have a first code unit,
-see if there is one that is asserted (these are not saved during the compile
-because they can cause conflicts with actual literals that follow). This code
-need not be obeyed if PCRE2_NO_START_OPTIMIZE is set, as the data it would
-create will not be used. */
+/* 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
+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_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0)
+if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
   {
+  /* If we do not have a first code unit, see if there is one that is asserted
+  (these are not saved during the compile because they can cause conflicts with
+  actual literals that follow). */
+
   if (firstcuflags < 0)
-    firstcu = find_firstassertedcu(codestart, &firstcuflags, FALSE);
+    firstcu = find_firstassertedcu(codestart, &firstcuflags, 0);
 
   /* Save the data for a first code unit. */
 
@@ -8995,87 +9706,86 @@
       }
     }
 
-  /* When there is no first code unit, see if we can set the PCRE2_STARTLINE
-  flag. This is helpful for multiline matches when all branches start with ^
-  and also when all branches start with non-atomic .* for non-DOTALL matches
-  when *PRUNE and SKIP are not present. (There is an option that disables this
-  case.) */
+  /* When there is no first code unit, for non-anchored patterns, see if we can
+  set the PCRE2_STARTLINE flag. This is helpful for multiline matches when all
+  branches start with ^ and also when all branches start with non-atomic .* for
+  non-DOTALL matches when *PRUNE and SKIP are not present. (There is an option
+  that disables this case.) */
 
-  else if (is_startline(codestart, 0, &cb, 0)) re->flags |= PCRE2_STARTLINE;
-  }
+  else if ((re->overall_options & PCRE2_ANCHORED) == 0 &&
+           is_startline(codestart, 0, &cb, 0, FALSE))
+    re->flags |= PCRE2_STARTLINE;
 
-/* Handle the "required code unit", if one is set. In the case of an anchored
-pattern, do this only if it follows a variable length item in the pattern.
-Again, skip this if PCRE2_NO_START_OPTIMIZE is set. */
+  /* Handle the "required code unit", if one is set. In the case of an anchored
+  pattern, do this only if it follows a variable length item in the pattern. */
 
-if (reqcuflags >= 0 &&
-     ((re->overall_options & (PCRE2_ANCHORED|PCRE2_NO_START_OPTIMIZE)) == 0 ||
-      (reqcuflags & REQ_VARY) != 0))
-  {
-  re->last_codeunit = reqcu;
-  re->flags |= PCRE2_LASTSET;
-
-  /* Handle caseless required code units as for first code units (above). */
-
-  if ((reqcuflags & REQ_CASELESS) != 0)
+  if (reqcuflags >= 0 &&
+       ((re->overall_options & PCRE2_ANCHORED) == 0 ||
+        (reqcuflags & REQ_VARY) != 0))
     {
-    if (reqcu < 128 || (!utf && reqcu < 255))
+    re->last_codeunit = reqcu;
+    re->flags |= PCRE2_LASTSET;
+
+    /* Handle caseless required code units as for first code units (above). */
+
+    if ((reqcuflags & REQ_CASELESS) != 0)
       {
-      if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
-      }
+      if (reqcu < 128 || (!utf && reqcu < 255))
+        {
+        if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
+        }
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
-    else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu)
-      re->flags |= PCRE2_LASTCASELESS;
+      else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu)
+        re->flags |= PCRE2_LASTCASELESS;
 #endif
+      }
     }
-  }
 
-/* Check for a pattern than can match an empty string, so that this information
-can be provided to applications. */
+  /* Finally, study the compiled pattern to set up information such as a bitmap
+  of starting code units and a minimum matching length. */
 
-do
-  {
-  int count = 0;
-  int rc = could_be_empty_branch(codestart, code, utf, &cb, TRUE, NULL, &count);
-  if (rc < 0)
+  if (PRIV(study)(re) != 0)
     {
-    errorcode = ERR86;
-    goto HAD_ERROR;
+    errorcode = ERR31;
+    goto HAD_CB_ERROR;
     }
-  if (rc > 0)
-    {
-    re->flags |= PCRE2_MATCH_EMPTY;
-    break;
-    }
-  codestart += GET(codestart, 1);
-  }
-while (*codestart == OP_ALT);
+  }   /* End of start-of-match optimizations. */
 
-/* Finally, unless PCRE2_NO_START_OPTIMIZE is set, study the compiled pattern
-to set up information such as a bitmap of starting code units and a minimum
-matching length. */
-
-if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 &&
-    PRIV(study)(re) != 0)
-  {
-  errorcode = ERR31;
-  goto HAD_ERROR;
-  }
-
-/* Control ends up here in all cases. If memory was obtained for a
-zero-terminated copy of the pattern, remember to 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. */
+/* Control ends up here in all cases. When running under valgrind, make a
+pattern's terminating zero defined again. If memory was obtained for the parsed
+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. */
 
 EXIT:
-if (copied_pattern != stack_copied_pattern)
-  ccontext->memctl.free(copied_pattern, ccontext->memctl.memory_data);
+#ifdef SUPPORT_VALGRIND
+if (zero_terminated) VALGRIND_MAKE_MEM_DEFINED(pattern + patlen, CU2BYTES(1));
+#endif
+if (cb.parsed_pattern != stack_parsed_pattern)
+  ccontext->memctl.free(cb.parsed_pattern, ccontext->memctl.memory_data);
 if (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE)
   ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data);
-if (cb.groupinfo != c32workspace)
+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
+block. Errors discovered before it is called must compute it from the ptr
+value. After parse_regex() is called, the offset in the compile block is set to
+the end of the pattern, but certain errors in compile_regex() may reset it if
+an offset is available in the parsed pattern. */
+
+HAD_CB_ERROR:
+ptr = pattern + cb.erroroffset;
+
+HAD_EARLY_ERROR:
+*erroroffset = ptr - pattern;
+
+HAD_ERROR:
+*errorptr = errorcode;
+pcre2_code_free(re);
+re = NULL;
+goto EXIT;
 }
 
 /* End of pcre2_compile.c */
diff --git a/dist2/src/pcre2_config.c b/dist2/src/pcre2_config.c
index e99272f..e487b10 100644
--- a/dist2/src/pcre2_config.c
+++ b/dist2/src/pcre2_config.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -84,13 +84,16 @@
     return PCRE2_ERROR_BADOPTION;
 
     case PCRE2_CONFIG_BSR:
+    case PCRE2_CONFIG_COMPILED_WIDTHS:
+    case PCRE2_CONFIG_DEPTHLIMIT:
+    case PCRE2_CONFIG_HEAPLIMIT:
     case PCRE2_CONFIG_JIT:
     case PCRE2_CONFIG_LINKSIZE:
     case PCRE2_CONFIG_MATCHLIMIT:
+    case PCRE2_CONFIG_NEVER_BACKSLASH_C:
     case PCRE2_CONFIG_NEWLINE:
     case PCRE2_CONFIG_PARENSLIMIT:
-    case PCRE2_CONFIG_RECURSIONLIMIT:
-    case PCRE2_CONFIG_STACKRECURSE:
+    case PCRE2_CONFIG_STACKRECURSE:    /* Obsolete */
     case PCRE2_CONFIG_UNICODE:
     return sizeof(uint32_t);
 
@@ -116,6 +119,28 @@
 #endif
   break;
 
+  case PCRE2_CONFIG_COMPILED_WIDTHS:
+  *((uint32_t *)where) = 0
+#ifdef SUPPORT_PCRE2_8
+  + 1
+#endif
+#ifdef SUPPORT_PCRE2_16
+  + 2
+#endif
+#ifdef SUPPORT_PCRE2_32
+  + 4
+#endif
+  ;
+  break;
+
+  case PCRE2_CONFIG_DEPTHLIMIT:
+  *((uint32_t *)where) = MATCH_LIMIT_DEPTH;
+  break;
+
+  case PCRE2_CONFIG_HEAPLIMIT:
+  *((uint32_t *)where) = HEAP_LIMIT;
+  break;
+
   case PCRE2_CONFIG_JIT:
 #ifdef SUPPORT_JIT
   *((uint32_t *)where) = 1;
@@ -147,20 +172,23 @@
   *((uint32_t *)where) = NEWLINE_DEFAULT;
   break;
 
+  case PCRE2_CONFIG_NEVER_BACKSLASH_C:
+#ifdef NEVER_BACKSLASH_C
+  *((uint32_t *)where) = 1;
+#else
+  *((uint32_t *)where) = 0;
+#endif
+  break;
+
   case PCRE2_CONFIG_PARENSLIMIT:
   *((uint32_t *)where) = PARENS_NEST_LIMIT;
   break;
 
-  case PCRE2_CONFIG_RECURSIONLIMIT:
-  *((uint32_t *)where) = MATCH_LIMIT_RECURSION;
-  break;
+  /* This is now obsolete. The stack is no longer used via recursion for
+  handling backtracking in pcre2_match(). */
 
   case PCRE2_CONFIG_STACKRECURSE:
-#ifdef HEAP_MATCH_RECURSE
   *((uint32_t *)where) = 0;
-#else
-  *((uint32_t *)where) = 1;
-#endif
   break;
 
   case PCRE2_CONFIG_UNICODE_VERSION:
diff --git a/dist2/src/pcre2_context.c b/dist2/src/pcre2_context.c
index ae050fe..2c14df0 100644
--- a/dist2/src/pcre2_context.c
+++ b/dist2/src/pcre2_context.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -138,7 +138,8 @@
   PCRE2_UNSET,                               /* Max pattern length */
   BSR_DEFAULT,                               /* Backslash R default */
   NEWLINE_DEFAULT,                           /* Newline convention */
-  PARENS_NEST_LIMIT };                       /* As it says */
+  PARENS_NEST_LIMIT,                         /* As it says */
+  0 };                                       /* Extra options */
 
 /* The create function copies the default into the new memory, but must
 override the default memory handling functions if a gcontext was provided. */
@@ -161,9 +162,6 @@
 
 const pcre2_match_context PRIV(default_match_context) = {
   { default_malloc, default_free, NULL },
-#ifdef HEAP_MATCH_RECURSE
-  { default_malloc, default_free, NULL },
-#endif
 #ifdef SUPPORT_JIT
   NULL,
   NULL,
@@ -171,8 +169,9 @@
   NULL,
   NULL,
   PCRE2_UNSET,   /* Offset limit */
+  HEAP_LIMIT,
   MATCH_LIMIT,
-  MATCH_LIMIT_RECURSION };
+  MATCH_LIMIT_DEPTH };
 
 /* The create function copies the default into the new memory, but must
 override the default memory handling functions if a gcontext was provided. */
@@ -190,6 +189,36 @@
 }
 
 
+/* 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) = {
+  { default_malloc, default_free, NULL },    /* Default memory handling */
+#ifdef _WIN32
+  CHAR_BACKSLASH,                            /* Default path separator */
+  CHAR_GRAVE_ACCENT                          /* Default escape character */
+#else  /* Not Windows */
+  CHAR_SLASH,                                /* Default path separator */
+  CHAR_BACKSLASH                             /* Default escape character */
+#endif
+  };
+
+/* The create function copies the default into the new memory, but must
+override the default memory handling functions if a gcontext was provided. */
+
+PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
+pcre2_convert_context_create(pcre2_general_context *gcontext)
+{
+pcre2_convert_context *ccontext = PRIV(memctl_malloc)(
+  sizeof(pcre2_real_convert_context), (pcre2_memctl *)gcontext);
+if (ccontext == NULL) return NULL;
+*ccontext = PRIV(default_convert_context);
+if (gcontext != NULL)
+  *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext);
+return ccontext;
+}
+
+
 /*************************************************
 *              Context copy functions            *
 *************************************************/
@@ -231,11 +260,22 @@
 
 
 
+PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
+pcre2_convert_context_copy(pcre2_convert_context *ccontext)
+{
+pcre2_convert_context *new =
+  ccontext->memctl.malloc(sizeof(pcre2_real_convert_context),
+  ccontext->memctl.memory_data);
+if (new == NULL) return NULL;
+memcpy(new, ccontext, sizeof(pcre2_real_convert_context));
+return new;
+}
+
+
 /*************************************************
 *              Context free functions            *
 *************************************************/
 
-
 PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
 pcre2_general_context_free(pcre2_general_context *gcontext)
 {
@@ -260,6 +300,12 @@
 }
 
 
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_convert_context_free(pcre2_convert_context *ccontext)
+{
+if (ccontext != NULL)
+  ccontext->memctl.free(ccontext, ccontext->memctl.memory_data);
+}
 
 
 /*************************************************
@@ -271,7 +317,7 @@
 data. */
 
 
-/* ------------ Compile contexts ------------ */
+/* ------------ Compile context ------------ */
 
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_set_character_tables(pcre2_compile_context *ccontext,
@@ -313,6 +359,7 @@
   case PCRE2_NEWLINE_CRLF:
   case PCRE2_NEWLINE_ANY:
   case PCRE2_NEWLINE_ANYCRLF:
+  case PCRE2_NEWLINE_NUL:
   ccontext->newline_convention = newline;
   return 0;
 
@@ -329,6 +376,13 @@
 }
 
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_compile_extra_options(pcre2_compile_context *ccontext, uint32_t options)
+{
+ccontext->extra_options = options;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
   int (*guard)(uint32_t, void *), void *user_data)
 {
@@ -338,7 +392,7 @@
 }
 
 
-/* ------------ Match contexts ------------ */
+/* ------------ Match context ------------ */
 
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_set_callout(pcre2_match_context *mcontext,
@@ -350,6 +404,13 @@
 }
 
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit)
+{
+mcontext->heap_limit = limit;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit)
 {
 mcontext->match_limit = limit;
@@ -357,17 +418,26 @@
 }
 
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit)
+{
+mcontext->depth_limit = limit;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit)
 {
 mcontext->offset_limit = limit;
 return 0;
 }
 
+/* This function became obsolete at release 10.30. It is kept as a synonym for
+backwards compatibility. */
+
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)
 {
-mcontext->recursion_limit = limit;
-return 0;
+return pcre2_set_depth_limit(mcontext, limit);
 }
 
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
@@ -375,17 +445,32 @@
   void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *),
   void *mydata)
 {
-#ifdef HEAP_MATCH_RECURSE
-mcontext->stack_memctl.malloc = mymalloc;
-mcontext->stack_memctl.free = myfree;
-mcontext->stack_memctl.memory_data = mydata;
-#else
 (void)mcontext;
 (void)mymalloc;
 (void)myfree;
 (void)mydata;
-#endif
+return 0;
+}
+
+/* ------------ Convert context ------------ */
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_glob_separator(pcre2_convert_context *ccontext, uint32_t separator)
+{
+if (separator != CHAR_SLASH && separator != CHAR_BACKSLASH &&
+    separator != CHAR_DOT) return PCRE2_ERROR_BADDATA;
+ccontext->glob_separator = separator;
+return 0;
+}
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape)
+{
+if (escape > 255 || (escape != 0 && !ispunct(escape)))
+  return PCRE2_ERROR_BADDATA;
+ccontext->glob_escape = escape;
 return 0;
 }
 
 /* End of pcre2_context.c */
+
diff --git a/dist2/src/pcre2_convert.c b/dist2/src/pcre2_convert.c
new file mode 100644
index 0000000..bdf9b86
--- /dev/null
+++ b/dist2/src/pcre2_convert.c
@@ -0,0 +1,1176 @@
+/*************************************************
+*      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-2017 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_internal.h"
+
+#define TYPE_OPTIONS (PCRE2_CONVERT_GLOB| \
+  PCRE2_CONVERT_POSIX_BASIC|PCRE2_CONVERT_POSIX_EXTENDED)
+
+#define ALL_OPTIONS (PCRE2_CONVERT_UTF|PCRE2_CONVERT_NO_UTF_CHECK| \
+  PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR| \
+  PCRE2_CONVERT_GLOB_NO_STARSTAR| \
+  TYPE_OPTIONS)
+
+#define DUMMY_BUFFER_SIZE 100
+
+/* Generated pattern fragments */
+
+#define STR_BACKSLASH_A STR_BACKSLASH STR_A
+#define STR_BACKSLASH_z STR_BACKSLASH STR_z
+#define STR_COLON_RIGHT_SQUARE_BRACKET STR_COLON STR_RIGHT_SQUARE_BRACKET
+#define STR_DOT_STAR_LOOKBEHIND STR_DOT STR_ASTERISK STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_LESS_THAN_SIGN STR_EQUALS_SIGN
+#define STR_LOOKAHEAD_NOT_DOT STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_EXCLAMATION_MARK STR_BACKSLASH STR_DOT STR_RIGHT_PARENTHESIS
+#define STR_QUERY_s STR_LEFT_PARENTHESIS STR_QUESTION_MARK STR_s STR_RIGHT_PARENTHESIS
+#define STR_STAR_NUL STR_LEFT_PARENTHESIS STR_ASTERISK STR_N STR_U STR_L STR_RIGHT_PARENTHESIS
+
+/* States for range and POSIX processing */
+
+enum { RANGE_NOT_STARTED, RANGE_STARTING, RANGE_STARTED };
+enum { POSIX_START_REGEX, POSIX_ANCHORED, POSIX_NOT_BRACKET,
+       POSIX_CLASS_NOT_STARTED, POSIX_CLASS_STARTING, POSIX_CLASS_STARTED };
+
+/* Macro to add a character string to the output buffer, checking for overflow. */
+
+#define PUTCHARS(string) \
+  { \
+  for (s = (char *)(string); *s != 0; s++) \
+    { \
+    if (p >= endp) return PCRE2_ERROR_NOMEMORY; \
+    *p++ = *s; \
+    } \
+  }
+
+/* Literals that must be escaped: \ ? * + | . ^ $ { } [ ] ( ) */
+
+static const char *pcre2_escaped_literals =
+  STR_BACKSLASH STR_QUESTION_MARK STR_ASTERISK STR_PLUS
+  STR_VERTICAL_LINE STR_DOT STR_CIRCUMFLEX_ACCENT STR_DOLLAR_SIGN
+  STR_LEFT_CURLY_BRACKET STR_RIGHT_CURLY_BRACKET
+  STR_LEFT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
+  STR_LEFT_PARENTHESIS STR_RIGHT_PARENTHESIS;
+
+/* Recognized escaped metacharacters in POSIX basic patterns. */
+
+static const char *posix_meta_escapes =
+  STR_LEFT_PARENTHESIS STR_RIGHT_PARENTHESIS
+  STR_LEFT_CURLY_BRACKET STR_RIGHT_CURLY_BRACKET
+  STR_1 STR_2 STR_3 STR_4 STR_5 STR_6 STR_7 STR_8 STR_9;
+
+
+
+/*************************************************
+*           Convert a POSIX pattern              *
+*************************************************/
+
+/* This function handles both basic and extended POSIX patterns.
+
+Arguments:
+  pattype        the pattern type
+  pattern        the pattern
+  plength        length in code units
+  utf            TRUE if UTF
+  use_buffer     where to put the output
+  use_length     length of use_buffer
+  bufflenptr     where to put the used length
+  dummyrun       TRUE if a dummy run
+  ccontext       the convert context
+
+Returns:         0 => success
+                !0 => error code
+*/
+
+static int
+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;
+PCRE2_UCHAR *endp = p + use_length - 1;  /* Allow for trailing zero */
+PCRE2_SIZE convlength = 0;
+
+uint32_t bracount = 0;
+uint32_t posix_state = POSIX_START_REGEX;
+uint32_t lastspecial = 0;
+BOOL extended = (pattype & PCRE2_CONVERT_POSIX_EXTENDED) != 0;
+BOOL nextisliteral = FALSE;
+
+(void)utf;       /* Not used when Unicode not supported */
+(void)ccontext;  /* Not currently used */
+
+/* Initialize default for error offset as end of input. */
+
+*bufflenptr = plength;
+PUTCHARS(STR_STAR_NUL);
+
+/* Now scan the input. */
+
+while (plength > 0)
+  {
+  uint32_t c, sc;
+  int clength = 1;
+
+  /* Add in the length of the last item, then, if in the dummy run, pull the
+  pointer back to the start of the (temporary) buffer and then remember the
+  start of the next item. */
+
+  convlength += p - pp;
+  if (dummyrun) p = use_buffer;
+  pp = p;
+
+  /* Pick up the next character */
+
+#ifndef SUPPORT_UNICODE
+  c = *posix;
+#else
+  GETCHARLENTEST(c, posix, clength);
+#endif
+  posix += clength;
+  plength -= clength;
+
+  sc = nextisliteral? 0 : c;
+  nextisliteral = FALSE;
+
+  /* Handle a character within a class. */
+
+  if (posix_state >= POSIX_CLASS_NOT_STARTED)
+    {
+    if (c == CHAR_RIGHT_SQUARE_BRACKET)
+      {
+      PUTCHARS(STR_RIGHT_SQUARE_BRACKET);
+      posix_state = POSIX_NOT_BRACKET;
+      }
+
+    /* Not the end of the class */
+
+    else
+      {
+      switch (posix_state)
+        {
+        case POSIX_CLASS_STARTED:
+        if (c <= 127 && islower(c)) break;  /* Remain in started state */
+        posix_state = POSIX_CLASS_NOT_STARTED;
+        if (c == CHAR_COLON  && plength > 0 &&
+            *posix == CHAR_RIGHT_SQUARE_BRACKET)
+          {
+          PUTCHARS(STR_COLON_RIGHT_SQUARE_BRACKET);
+          plength--;
+          posix++;
+          continue;    /* With next character after :] */
+          }
+        /* Fall through */
+
+        case POSIX_CLASS_NOT_STARTED:
+        if (c == CHAR_LEFT_SQUARE_BRACKET)
+          posix_state = POSIX_CLASS_STARTING;
+        break;
+
+        case POSIX_CLASS_STARTING:
+        if (c == CHAR_COLON) posix_state = POSIX_CLASS_STARTED;
+        break;
+        }
+
+      if (c == CHAR_BACKSLASH) PUTCHARS(STR_BACKSLASH);
+      if (p + clength > endp) return PCRE2_ERROR_NOMEMORY;
+      memcpy(p, posix - clength, CU2BYTES(clength));
+      p += clength;
+      }
+    }
+
+  /* Handle a character not within a class. */
+
+  else switch(sc)
+    {
+    case CHAR_LEFT_SQUARE_BRACKET:
+    PUTCHARS(STR_LEFT_SQUARE_BRACKET);
+
+#ifdef NEVER
+    /* We could handle special cases [[:<:]] and [[:>:]] (which PCRE does
+    support) but they are not part of POSIX 1003.1. */
+
+    if (plength >= 6)
+      {
+      if (posix[0] == CHAR_LEFT_SQUARE_BRACKET &&
+          posix[1] == CHAR_COLON &&
+          (posix[2] == CHAR_LESS_THAN_SIGN ||
+           posix[2] == CHAR_GREATER_THAN_SIGN) &&
+          posix[3] == CHAR_COLON &&
+          posix[4] == CHAR_RIGHT_SQUARE_BRACKET &&
+          posix[5] == CHAR_RIGHT_SQUARE_BRACKET)
+        {
+        if (p + 6 > endp) return PCRE2_ERROR_NOMEMORY;
+        memcpy(p, posix, CU2BYTES(6));
+        p += 6;
+        posix += 6;
+        plength -= 6;
+        continue;  /* With next character */
+        }
+      }
+#endif
+
+    /* Handle start of "normal" character classes */
+
+    posix_state = POSIX_CLASS_NOT_STARTED;
+
+    /* Handle ^ and ] as first characters */
+
+    if (plength > 0)
+      {
+      if (*posix == CHAR_CIRCUMFLEX_ACCENT)
+        {
+        posix++;
+        plength--;
+        PUTCHARS(STR_CIRCUMFLEX_ACCENT);
+        }
+      if (plength > 0 && *posix == CHAR_RIGHT_SQUARE_BRACKET)
+        {
+        posix++;
+        plength--;
+        PUTCHARS(STR_RIGHT_SQUARE_BRACKET);
+        }
+      }
+    break;
+
+    case CHAR_BACKSLASH:
+    if (plength <= 0) return PCRE2_ERROR_END_BACKSLASH;
+    if (extended) nextisliteral = TRUE; else
+      {
+      if (*posix < 127 && strchr(posix_meta_escapes, *posix) != NULL)
+        {
+        if (isdigit(*posix)) PUTCHARS(STR_BACKSLASH);
+        if (p + 1 > endp) return PCRE2_ERROR_NOMEMORY;
+        lastspecial = *p++ = *posix++;
+        plength--;
+        }
+      else nextisliteral = TRUE;
+      }
+    break;
+
+    case CHAR_RIGHT_PARENTHESIS:
+    if (!extended || bracount == 0) goto ESCAPE_LITERAL;
+    bracount--;
+    goto COPY_SPECIAL;
+
+    case CHAR_LEFT_PARENTHESIS:
+    bracount++;
+    /* Fall through */
+
+    case CHAR_QUESTION_MARK:
+    case CHAR_PLUS:
+    case CHAR_LEFT_CURLY_BRACKET:
+    case CHAR_RIGHT_CURLY_BRACKET:
+    case CHAR_VERTICAL_LINE:
+    if (!extended) goto ESCAPE_LITERAL;
+    /* Fall through */
+
+    case CHAR_DOT:
+    case CHAR_DOLLAR_SIGN:
+    posix_state = POSIX_NOT_BRACKET;
+    COPY_SPECIAL:
+    lastspecial = c;
+    if (p + 1 > endp) return PCRE2_ERROR_NOMEMORY;
+    *p++ = c;
+    break;
+
+    case CHAR_ASTERISK:
+    if (lastspecial != CHAR_ASTERISK)
+      {
+      if (!extended && (posix_state < POSIX_NOT_BRACKET ||
+          lastspecial == CHAR_LEFT_PARENTHESIS))
+        goto ESCAPE_LITERAL;
+      goto COPY_SPECIAL;
+      }
+    break;   /* Ignore second and subsequent asterisks */
+
+    case CHAR_CIRCUMFLEX_ACCENT:
+    if (extended) goto COPY_SPECIAL;
+    if (posix_state == POSIX_START_REGEX ||
+        lastspecial == CHAR_LEFT_PARENTHESIS)
+      {
+      posix_state = POSIX_ANCHORED;
+      goto COPY_SPECIAL;
+      }
+    /* Fall through */
+
+    default:
+    if (c < 128 && strchr(pcre2_escaped_literals, c) != NULL)
+      {
+      ESCAPE_LITERAL:
+      PUTCHARS(STR_BACKSLASH);
+      }
+    lastspecial = 0xff;  /* Indicates nothing special */
+    if (p + clength > endp) return PCRE2_ERROR_NOMEMORY;
+    memcpy(p, posix - clength, CU2BYTES(clength));
+    p += clength;
+    posix_state = POSIX_NOT_BRACKET;
+    break;
+    }
+  }
+
+if (posix_state >= POSIX_CLASS_NOT_STARTED)
+  return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
+convlength += p - pp;        /* Final segment */
+*bufflenptr = convlength;
+*p++ = 0;
+return 0;
+}
+
+
+/*************************************************
+*           Convert a glob pattern               *
+*************************************************/
+
+/* Context for writing the output into a buffer. */
+
+typedef struct pcre2_output_context {
+  PCRE2_UCHAR *output;                  /* current output position */
+  PCRE2_SPTR output_end;                /* output end */
+  PCRE2_SIZE output_size;               /* size of the output */
+  uint8_t out_str[8];                   /* string copied to the output */
+} pcre2_output_context;
+
+
+/* Write a character into the output.
+
+Arguments:
+  out            output context
+  chr            the next character
+*/
+
+static void
+convert_glob_write(pcre2_output_context *out, PCRE2_UCHAR chr)
+{
+out->output_size++;
+
+if (out->output < out->output_end)
+  *out->output++ = chr;
+}
+
+
+/* Write a string into the output.
+
+Arguments:
+  out            output context
+  length         length of out->out_str
+*/
+
+static void
+convert_glob_write_str(pcre2_output_context *out, PCRE2_SIZE length)
+{
+uint8_t *out_str = out->out_str;
+PCRE2_UCHAR *output = out->output;
+PCRE2_SPTR output_end = out->output_end;
+PCRE2_SIZE output_size = out->output_size;
+
+do
+  {
+  output_size++;
+
+  if (output < output_end)
+    *output++ = *out_str++;
+  }
+while (--length != 0);
+
+out->output = output;
+out->output_size = output_size;
+}
+
+
+/* Prints the separator into the output.
+
+Arguments:
+  out            output context
+  separator      glob separator
+  with_escape    backslash is needed before separator
+*/
+
+static void
+convert_glob_print_separator(pcre2_output_context *out,
+  PCRE2_UCHAR separator, BOOL with_escape)
+{
+if (with_escape)
+  convert_glob_write(out, CHAR_BACKSLASH);
+
+convert_glob_write(out, separator);
+}
+
+
+/* Prints a wildcard into the output.
+
+Arguments:
+  out            output context
+  separator      glob separator
+  with_escape    backslash is needed before separator
+*/
+
+static void
+convert_glob_print_wildcard(pcre2_output_context *out,
+  PCRE2_UCHAR separator, BOOL with_escape)
+{
+out->out_str[0] = CHAR_LEFT_SQUARE_BRACKET;
+out->out_str[1] = CHAR_CIRCUMFLEX_ACCENT;
+convert_glob_write_str(out, 2);
+
+convert_glob_print_separator(out, separator, with_escape);
+
+convert_glob_write(out, CHAR_RIGHT_SQUARE_BRACKET);
+}
+
+
+/* Parse a posix class.
+
+Arguments:
+  from           starting point of scanning the range
+  pattern_end    end of pattern
+  out            output context
+
+Returns:  >0 => class index
+          0  => malformed class
+*/
+
+static int
+convert_glob_parse_class(PCRE2_SPTR *from, PCRE2_SPTR pattern_end,
+  pcre2_output_context *out)
+{
+static const char *posix_classes = "alnum:alpha:ascii:blank:cntrl:digit:"
+  "graph:lower:print:punct:space:upper:word:xdigit:";
+PCRE2_SPTR start = *from + 1;
+PCRE2_SPTR pattern = start;
+const char *class_ptr;
+PCRE2_UCHAR c;
+int class_index;
+
+while (TRUE)
+  {
+  if (pattern >= pattern_end) return 0;
+
+  c = *pattern++;
+
+  if (c < CHAR_a || c > CHAR_z) break;
+  }
+
+if (c != CHAR_COLON || pattern >= pattern_end ||
+    *pattern != CHAR_RIGHT_SQUARE_BRACKET)
+  return 0;
+
+class_ptr = posix_classes;
+class_index = 1;
+
+while (TRUE)
+  {
+  if (*class_ptr == CHAR_NUL) return 0;
+
+  pattern = start;
+
+  while (*pattern == (PCRE2_UCHAR) *class_ptr)
+    {
+    if (*pattern == CHAR_COLON)
+      {
+      pattern += 2;
+      start -= 2;
+
+      do convert_glob_write(out, *start++); while (start < pattern);
+
+      *from = pattern;
+      return class_index;
+      }
+    pattern++;
+    class_ptr++;
+    }
+
+  while (*class_ptr != CHAR_COLON) class_ptr++;
+  class_ptr++;
+  class_index++;
+  }
+}
+
+/* Checks whether the character is in the class.
+
+Arguments:
+  class_index    class index
+  c              character
+
+Returns:   !0 => character is found in the class
+            0 => otherwise
+*/
+
+static BOOL
+convert_glob_char_in_class(int class_index, PCRE2_UCHAR c)
+{
+switch (class_index)
+  {
+  case 1: return isalnum(c);
+  case 2: return isalpha(c);
+  case 3: return 1;
+  case 4: return c == CHAR_HT || c == CHAR_SPACE;
+  case 5: return iscntrl(c);
+  case 6: return isdigit(c);
+  case 7: return isgraph(c);
+  case 8: return islower(c);
+  case 9: return isprint(c);
+  case 10: return ispunct(c);
+  case 11: return isspace(c);
+  case 12: return isupper(c);
+  case 13: return isalnum(c) || c == CHAR_UNDERSCORE;
+  default: return isxdigit(c);
+  }
+}
+
+/* Parse a range of characters.
+
+Arguments:
+  from           starting point of scanning the range
+  pattern_end    end of pattern
+  out            output context
+  separator      glob separator
+  with_escape    backslash is needed before separator
+
+Returns:         0 => success
+                !0 => error code
+*/
+
+static int
+convert_glob_parse_range(PCRE2_SPTR *from, PCRE2_SPTR pattern_end,
+  pcre2_output_context *out, BOOL utf, PCRE2_UCHAR separator,
+  BOOL with_escape, PCRE2_UCHAR escape, BOOL no_wildsep)
+{
+BOOL is_negative = FALSE;
+BOOL separator_seen = FALSE;
+BOOL has_prev_c;
+PCRE2_SPTR pattern = *from;
+PCRE2_SPTR char_start = NULL;
+uint32_t c, prev_c;
+int len, class_index;
+
+(void)utf; /* Avoid compiler warning. */
+
+if (pattern >= pattern_end)
+  {
+  *from = pattern;
+  return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
+  }
+
+if (*pattern == CHAR_EXCLAMATION_MARK
+    || *pattern == CHAR_CIRCUMFLEX_ACCENT)
+  {
+  pattern++;
+
+  if (pattern >= pattern_end)
+    {
+    *from = pattern;
+    return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
+    }
+
+  is_negative = TRUE;
+
+  out->out_str[0] = CHAR_LEFT_SQUARE_BRACKET;
+  out->out_str[1] = CHAR_CIRCUMFLEX_ACCENT;
+  len = 2;
+
+  if (!no_wildsep)
+    {
+    if (with_escape)
+      {
+      out->out_str[len] = CHAR_BACKSLASH;
+      len++;
+      }
+    out->out_str[len] = (uint8_t) separator;
+    }
+
+  convert_glob_write_str(out, len + 1);
+  }
+else
+  convert_glob_write(out, CHAR_LEFT_SQUARE_BRACKET);
+
+has_prev_c = FALSE;
+prev_c = 0;
+
+if (*pattern == CHAR_RIGHT_SQUARE_BRACKET)
+  {
+  out->out_str[0] = CHAR_BACKSLASH;
+  out->out_str[1] = CHAR_RIGHT_SQUARE_BRACKET;
+  convert_glob_write_str(out, 2);
+  has_prev_c = TRUE;
+  prev_c = CHAR_RIGHT_SQUARE_BRACKET;
+  pattern++;
+  }
+
+while (pattern < pattern_end)
+  {
+  char_start = pattern;
+  GETCHARINCTEST(c, pattern);
+
+  if (c == CHAR_RIGHT_SQUARE_BRACKET)
+    {
+    convert_glob_write(out, c);
+
+    if (!is_negative && !no_wildsep && separator_seen)
+      {
+      out->out_str[0] = CHAR_LEFT_PARENTHESIS;
+      out->out_str[1] = CHAR_QUESTION_MARK;
+      out->out_str[2] = CHAR_LESS_THAN_SIGN;
+      out->out_str[3] = CHAR_EXCLAMATION_MARK;
+      convert_glob_write_str(out, 4);
+
+      convert_glob_print_separator(out, separator, with_escape);
+      convert_glob_write(out, CHAR_RIGHT_PARENTHESIS);
+      }
+
+    *from = pattern;
+    return 0;
+    }
+
+  if (pattern >= pattern_end) break;
+
+  if (c == CHAR_LEFT_SQUARE_BRACKET && *pattern == CHAR_COLON)
+    {
+    *from = pattern;
+    class_index = convert_glob_parse_class(from, pattern_end, out);
+
+    if (class_index != 0)
+      {
+      pattern = *from;
+
+      has_prev_c = FALSE;
+      prev_c = 0;
+
+      if (!is_negative &&
+          convert_glob_char_in_class (class_index, separator))
+        separator_seen = TRUE;
+      continue;
+      }
+    }
+  else if (c == CHAR_MINUS && has_prev_c &&
+           *pattern != CHAR_RIGHT_SQUARE_BRACKET)
+    {
+    convert_glob_write(out, CHAR_MINUS);
+
+    char_start = pattern;
+    GETCHARINCTEST(c, pattern);
+
+    if (pattern >= pattern_end) break;
+
+    if (escape != 0 && c == escape)
+      {
+      char_start = pattern;
+      GETCHARINCTEST(c, pattern);
+      }
+    else if (c == CHAR_LEFT_SQUARE_BRACKET && *pattern == CHAR_COLON)
+      {
+      *from = pattern;
+      return PCRE2_ERROR_CONVERT_SYNTAX;
+      }
+
+    if (prev_c > c)
+      {
+      *from = pattern;
+      return PCRE2_ERROR_CONVERT_SYNTAX;
+      }
+
+    if (prev_c < separator && separator < c) separator_seen = TRUE;
+
+    has_prev_c = FALSE;
+    prev_c = 0;
+    }
+  else
+    {
+    if (escape != 0 && c == escape)
+      {
+      char_start = pattern;
+      GETCHARINCTEST(c, pattern);
+
+      if (pattern >= pattern_end) break;
+      }
+
+    has_prev_c = TRUE;
+    prev_c = c;
+    }
+
+  if (c == CHAR_LEFT_SQUARE_BRACKET || c == CHAR_RIGHT_SQUARE_BRACKET ||
+      c == CHAR_BACKSLASH || c == CHAR_MINUS)
+    convert_glob_write(out, CHAR_BACKSLASH);
+
+  if (c == separator) separator_seen = TRUE;
+
+  do convert_glob_write(out, *char_start++); while (char_start < pattern);
+  }
+
+*from = pattern;
+return PCRE2_ERROR_MISSING_SQUARE_BRACKET;
+}
+
+
+/* Prints a (*COMMIT) into the output.
+
+Arguments:
+  out            output context
+*/
+
+static void
+convert_glob_print_commit(pcre2_output_context *out)
+{
+out->out_str[0] = CHAR_LEFT_PARENTHESIS;
+out->out_str[1] = CHAR_ASTERISK;
+out->out_str[2] = CHAR_C;
+out->out_str[3] = CHAR_O;
+out->out_str[4] = CHAR_M;
+out->out_str[5] = CHAR_M;
+out->out_str[6] = CHAR_I;
+out->out_str[7] = CHAR_T;
+convert_glob_write_str(out, 8);
+convert_glob_write(out, CHAR_RIGHT_PARENTHESIS);
+}
+
+
+/* Bash glob converter.
+
+Arguments:
+  pattype        the pattern type
+  pattern        the pattern
+  plength        length in code units
+  utf            TRUE if UTF
+  use_buffer     where to put the output
+  use_length     length of use_buffer
+  bufflenptr     where to put the used length
+  dummyrun       TRUE if a dummy run
+  ccontext       the convert context
+
+Returns:         0 => success
+                !0 => error code
+*/
+
+static int
+convert_glob(uint32_t options, 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)
+{
+pcre2_output_context out;
+PCRE2_SPTR pattern_start = pattern;
+PCRE2_SPTR pattern_end = pattern + plength;
+PCRE2_UCHAR separator = ccontext->glob_separator;
+PCRE2_UCHAR escape = ccontext->glob_escape;
+PCRE2_UCHAR c;
+BOOL no_wildsep = (options & PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR) != 0;
+BOOL no_starstar = (options & PCRE2_CONVERT_GLOB_NO_STARSTAR) != 0;
+BOOL in_atomic = FALSE;
+BOOL after_starstar = FALSE;
+BOOL no_slash_z = FALSE;
+BOOL with_escape, is_start, after_separator;
+int result = 0;
+
+(void)utf; /* Avoid compiler warning. */
+
+#ifdef SUPPORT_UNICODE
+if (utf && (separator >= 128 || escape >= 128))
+  {
+  /* Currently only ASCII characters are supported. */
+  *bufflenptr = 0;
+  return PCRE2_ERROR_CONVERT_SYNTAX;
+  }
+#endif
+
+with_escape = strchr(pcre2_escaped_literals, separator) != NULL;
+
+/* Initialize default for error offset as end of input. */
+out.output = use_buffer;
+out.output_end = use_buffer + use_length;
+out.output_size = 0;
+
+out.out_str[0] = CHAR_LEFT_PARENTHESIS;
+out.out_str[1] = CHAR_QUESTION_MARK;
+out.out_str[2] = CHAR_s;
+out.out_str[3] = CHAR_RIGHT_PARENTHESIS;
+convert_glob_write_str(&out, 4);
+
+is_start = TRUE;
+
+if (pattern < pattern_end && pattern[0] == CHAR_ASTERISK)
+  {
+  if (no_wildsep)
+    is_start = FALSE;
+  else if (!no_starstar && pattern + 1 < pattern_end &&
+           pattern[1] == CHAR_ASTERISK)
+    is_start = FALSE;
+  }
+
+if (is_start)
+  {
+  out.out_str[0] = CHAR_BACKSLASH;
+  out.out_str[1] = CHAR_A;
+  convert_glob_write_str(&out, 2);
+  }
+
+while (pattern < pattern_end)
+  {
+  c = *pattern++;
+
+  if (c == CHAR_ASTERISK)
+    {
+    is_start = pattern == pattern_start + 1;
+
+    if (in_atomic)
+      {
+      convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);
+      in_atomic = FALSE;
+      }
+
+    if (!no_starstar && pattern < pattern_end && *pattern == CHAR_ASTERISK)
+      {
+      after_separator = is_start || (pattern[-2] == separator);
+
+      do pattern++; while (pattern < pattern_end &&
+                           *pattern == CHAR_ASTERISK);
+
+      if (pattern >= pattern_end)
+        {
+        no_slash_z = TRUE;
+        break;
+        }
+
+      after_starstar = TRUE;
+
+      if (after_separator && escape != 0 && *pattern == escape &&
+          pattern + 1 < pattern_end && pattern[1] == separator)
+        pattern++;
+
+      if (is_start)
+        {
+        if (*pattern != separator) continue;
+
+        out.out_str[0] = CHAR_LEFT_PARENTHESIS;
+        out.out_str[1] = CHAR_QUESTION_MARK;
+        out.out_str[2] = CHAR_COLON;
+        out.out_str[3] = CHAR_BACKSLASH;
+        out.out_str[4] = CHAR_A;
+        out.out_str[5] = CHAR_VERTICAL_LINE;
+        convert_glob_write_str(&out, 6);
+
+        convert_glob_print_separator(&out, separator, with_escape);
+        convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);
+
+        pattern++;
+        continue;
+        }
+
+      convert_glob_print_commit(&out);
+
+      if (!after_separator || *pattern != separator)
+        {
+        out.out_str[0] = CHAR_DOT;
+        out.out_str[1] = CHAR_ASTERISK;
+        out.out_str[2] = CHAR_QUESTION_MARK;
+        convert_glob_write_str(&out, 3);
+        continue;
+        }
+
+      out.out_str[0] = CHAR_LEFT_PARENTHESIS;
+      out.out_str[1] = CHAR_QUESTION_MARK;
+      out.out_str[2] = CHAR_COLON;
+      out.out_str[3] = CHAR_DOT;
+      out.out_str[4] = CHAR_ASTERISK;
+      out.out_str[5] = CHAR_QUESTION_MARK;
+
+      convert_glob_write_str(&out, 6);
+
+      convert_glob_print_separator(&out, separator, with_escape);
+
+      out.out_str[0] = CHAR_RIGHT_PARENTHESIS;
+      out.out_str[1] = CHAR_QUESTION_MARK;
+      out.out_str[2] = CHAR_QUESTION_MARK;
+      convert_glob_write_str(&out, 3);
+
+      pattern++;
+      continue;
+      }
+
+    if (pattern < pattern_end && *pattern == CHAR_ASTERISK)
+      {
+      do pattern++; while (pattern < pattern_end &&
+                           *pattern == CHAR_ASTERISK);
+      }
+
+    if (no_wildsep)
+      {
+      if (pattern >= pattern_end)
+        {
+        no_slash_z = TRUE;
+        break;
+        }
+
+      /* Start check must be after the end check. */
+      if (is_start) continue;
+      }
+
+    if (!is_start)
+      {
+      if (after_starstar)
+        {
+        out.out_str[0] = CHAR_LEFT_PARENTHESIS;
+        out.out_str[1] = CHAR_QUESTION_MARK;
+        out.out_str[2] = CHAR_GREATER_THAN_SIGN;
+        convert_glob_write_str(&out, 3);
+        in_atomic = TRUE;
+        }
+      else
+        convert_glob_print_commit(&out);
+      }
+
+    if (no_wildsep)
+      convert_glob_write(&out, CHAR_DOT);
+    else
+      convert_glob_print_wildcard(&out, separator, with_escape);
+
+    out.out_str[0] = CHAR_ASTERISK;
+    out.out_str[1] = CHAR_QUESTION_MARK;
+    if (pattern >= pattern_end)
+      out.out_str[1] = CHAR_PLUS;
+    convert_glob_write_str(&out, 2);
+    continue;
+    }
+
+  if (c == CHAR_QUESTION_MARK)
+    {
+    if (no_wildsep)
+      convert_glob_write(&out, CHAR_DOT);
+    else
+      convert_glob_print_wildcard(&out, separator, with_escape);
+    continue;
+    }
+
+  if (c == CHAR_LEFT_SQUARE_BRACKET)
+    {
+    result = convert_glob_parse_range(&pattern, pattern_end,
+      &out, utf, separator, with_escape, escape, no_wildsep);
+    if (result != 0) break;
+    continue;
+    }
+
+  if (escape != 0 && c == escape)
+    {
+    if (pattern >= pattern_end)
+      {
+      result = PCRE2_ERROR_CONVERT_SYNTAX;
+      break;
+      }
+    c = *pattern++;
+    }
+
+  if (c < 128 && strchr(pcre2_escaped_literals, c) != NULL)
+    convert_glob_write(&out, CHAR_BACKSLASH);
+
+  convert_glob_write(&out, c);
+  }
+
+if (result == 0)
+  {
+  if (!no_slash_z)
+    {
+    out.out_str[0] = CHAR_BACKSLASH;
+    out.out_str[1] = CHAR_z;
+    convert_glob_write_str(&out, 2);
+    }
+
+  if (in_atomic)
+    convert_glob_write(&out, CHAR_RIGHT_PARENTHESIS);
+
+  convert_glob_write(&out, CHAR_NUL);
+
+  if (!dummyrun && out.output_size != (PCRE2_SIZE) (out.output - use_buffer))
+    result = PCRE2_ERROR_NOMEMORY;
+  }
+
+if (result != 0)
+  {
+  *bufflenptr = pattern - pattern_start;
+  return result;
+  }
+
+*bufflenptr = out.output_size - 1;
+return 0;
+}
+
+
+/*************************************************
+*                Convert pattern                 *
+*************************************************/
+
+/* This is the external-facing function for converting other forms of pattern
+into PCRE2 regular expression patterns. On error, the bufflenptr argument is
+used to return an offset in the original pattern.
+
+Arguments:
+  pattern     the input pattern
+  plength     length of input, or PCRE2_ZERO_TERMINATED
+  options     options bits
+  buffptr     pointer to pointer to output buffer
+  bufflenptr  pointer to length of output buffer
+  ccontext    convert context or NULL
+
+Returns:      0 for success, else an error code (+ve or -ve)
+*/
+
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+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;
+PCRE2_UCHAR dummy_buffer[DUMMY_BUFFER_SIZE];
+PCRE2_UCHAR *use_buffer = dummy_buffer;
+PCRE2_SIZE use_length = DUMMY_BUFFER_SIZE;
+BOOL utf = (options & PCRE2_CONVERT_UTF) != 0;
+uint32_t pattype = options & TYPE_OPTIONS;
+
+if (pattern == NULL || bufflenptr == NULL) return PCRE2_ERROR_NULL;
+if ((options & ~ALL_OPTIONS) != 0 ||        /* Undefined bit set */
+    (pattype & (~pattype+1)) != pattype ||  /* More than one type set */
+    pattype == 0)                           /* No type set */
+  {
+  *bufflenptr = 0;  /* Error offset */
+  return PCRE2_ERROR_BADOPTION;
+  }
+
+if (plength == PCRE2_ZERO_TERMINATED) plength = PRIV(strlen)(pattern);
+if (ccontext == NULL) ccontext =
+  (pcre2_convert_context *)(&PRIV(default_convert_context));
+
+/* Check UTF if required. */
+
+#ifndef SUPPORT_UNICODE
+if (utf) return PCRE2_ERROR_UNICODE_NOT_SUPPORTED;
+#else
+if (utf && (options & PCRE2_CONVERT_NO_UTF_CHECK) == 0)
+  {
+  PCRE2_SIZE erroroffset;
+  rc = PRIV(valid_utf)(pattern, plength, &erroroffset);
+  if (rc != 0)
+    {
+    *bufflenptr = erroroffset;
+    return rc;
+    }
+  }
+#endif
+
+/* If buffptr is not NULL, and what it points to is not NULL, we are being
+provided with a buffer and a length, so set them as the buffer to use. */
+
+if (buffptr != NULL && *buffptr != NULL)
+  {
+  use_buffer = *buffptr;
+  use_length = *bufflenptr;
+  }
+
+/* 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++)
+  {
+  PCRE2_UCHAR *allocated;
+  BOOL dummyrun = buffptr == NULL || *buffptr == NULL;
+
+  switch(pattype)
+    {
+    case PCRE2_CONVERT_GLOB:
+    rc = convert_glob(options & ~PCRE2_CONVERT_GLOB, pattern, plength, utf,
+      use_buffer, use_length, bufflenptr, dummyrun, ccontext);
+    break;
+
+    case PCRE2_CONVERT_POSIX_BASIC:
+    case PCRE2_CONVERT_POSIX_EXTENDED:
+    rc = convert_posix(pattype, pattern, plength, utf, use_buffer, use_length,
+      bufflenptr, dummyrun, ccontext);
+    break;
+
+    default:
+    return PCRE2_ERROR_INTERNAL;
+    }
+
+  if (rc != 0 ||           /* Error */
+      buffptr == NULL ||   /* Just the length is required */
+      *buffptr != NULL)    /* Buffer was provided or allocated */
+    return rc;
+
+  /* Allocate memory for the buffer, with hidden space for an allocator at
+  the start. The next time round the loop runs the conversion for real. */
+
+  allocated = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
+    (*bufflenptr + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)ccontext);
+  if (allocated == NULL) return PCRE2_ERROR_NOMEMORY;
+  *buffptr = (PCRE2_UCHAR *)(((char *)allocated) + sizeof(pcre2_memctl));
+
+  use_buffer = *buffptr;
+  use_length = *bufflenptr + 1;
+  }
+
+/* Control should never get here. */
+
+return PCRE2_ERROR_INTERNAL;
+}
+
+
+/*************************************************
+*            Free converted pattern              *
+*************************************************/
+
+/* This frees a converted pattern that was put in newly-allocated memory.
+
+Argument:   the converted pattern
+Returns:    nothing
+*/
+
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_converted_pattern_free(PCRE2_UCHAR *converted)
+{
+if (converted != NULL)
+  {
+  pcre2_memctl *memctl =
+    (pcre2_memctl *)((char *)converted - sizeof(pcre2_memctl));
+  memctl->free(memctl, memctl->memory_data);
+  }
+}
+
+/* End of pcre2_convert.c */
diff --git a/dist2/src/pcre2_dfa_match.c b/dist2/src/pcre2_dfa_match.c
index 12b31b1..c6184ff 100644
--- a/dist2/src/pcre2_dfa_match.c
+++ b/dist2/src/pcre2_dfa_match.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2018 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -83,7 +83,7 @@
 #include "pcre2_internal.h"
 
 #define PUBLIC_DFA_MATCH_OPTIONS \
-  (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
+  (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
    PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
    PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART)
 
@@ -172,7 +172,7 @@
   0,                             /* Assert not                             */
   0,                             /* Assert behind                          */
   0,                             /* Assert behind not                      */
-  0, 0,                          /* ONCE, ONCE_NC                          */
+  0,                             /* ONCE                                   */
   0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
   0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
   0, 0,                          /* CREF, DNCREF                           */
@@ -245,7 +245,7 @@
   0,                             /* Assert not                             */
   0,                             /* Assert behind                          */
   0,                             /* Assert behind not                      */
-  0, 0,                          /* ONCE, ONCE_NC                          */
+  0,                             /* ONCE                                   */
   0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
   0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
   0, 0,                          /* CREF, DNCREF                           */
@@ -294,6 +294,66 @@
 
 
 /*************************************************
+*               Process a callout                *
+*************************************************/
+
+/* This function is called to perform a callout.
+
+Arguments:
+  code              current code pointer
+  offsets           points to current capture offsets
+  current_subject   start of current subject match
+  ptr               current position in subject
+  mb                the match block
+  extracode         extra code offset when called from condition
+  lengthptr         where to return the callout length
+
+Returns:            the return from the callout
+*/
+
+static int
+do_callout(PCRE2_SPTR code, PCRE2_SIZE *offsets, PCRE2_SPTR current_subject,
+  PCRE2_SPTR ptr, dfa_match_block *mb, PCRE2_SIZE extracode,
+  PCRE2_SIZE *lengthptr)
+{
+pcre2_callout_block *cb = mb->cb;
+
+*lengthptr = (code[extracode] == OP_CALLOUT)?
+  (PCRE2_SIZE)PRIV(OP_lengths)[OP_CALLOUT] :
+  (PCRE2_SIZE)GET(code, 1 + 2*LINK_SIZE + extracode);
+
+if (mb->callout == NULL) return 0;    /* No callout provided */
+
+/* Fixed fields in the callout block are set once and for all at the start of
+matching. */
+
+cb->offset_vector    = offsets;
+cb->start_match      = (PCRE2_SIZE)(current_subject - mb->start_subject);
+cb->current_position = (PCRE2_SIZE)(ptr - mb->start_subject);
+cb->pattern_position = GET(code, 1 + extracode);
+cb->next_item_length = GET(code, 1 + LINK_SIZE + extracode);
+
+if (code[extracode] == OP_CALLOUT)
+  {
+  cb->callout_number = code[1 + 2*LINK_SIZE + extracode];
+  cb->callout_string_offset = 0;
+  cb->callout_string = NULL;
+  cb->callout_string_length = 0;
+  }
+else
+  {
+  cb->callout_number = 0;
+  cb->callout_string_offset = GET(code, 1 + 3*LINK_SIZE + extracode);
+  cb->callout_string = code + (1 + 4*LINK_SIZE + extracode) + 1;
+  cb->callout_string_length = *lengthptr - (1 + 4*LINK_SIZE) - 2;
+  }
+
+return (mb->callout)(cb, mb->callout_data);
+}
+
+
+
+/*************************************************
 *     Match a Regular Expression - DFA engine    *
 *************************************************/
 
@@ -371,18 +431,14 @@
   uint32_t offsetcount,
   int *workspace,
   int wscount,
-  int  rlevel)
+  uint32_t  rlevel)
 {
 stateblock *active_states, *new_states, *temp_states;
 stateblock *next_active_state, *next_new_state;
-
 const uint8_t *ctypes, *lcc, *fcc;
 PCRE2_SPTR ptr;
 PCRE2_SPTR end_code;
-PCRE2_SPTR first_op;
-
 dfa_recursion_info new_recursive;
-
 int active_count, new_count, match_count;
 
 /* Some fields in the mb block are frequently referenced, so we load them into
@@ -400,7 +456,8 @@
 
 BOOL reset_could_continue = FALSE;
 
-rlevel++;
+if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
+if (rlevel++ > mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
 offsetcount &= (uint32_t)(-2);  /* Round down */
 
 wscount -= 2;
@@ -417,21 +474,15 @@
 next_new_state = new_states = active_states + wscount;
 new_count = 0;
 
-first_op = this_start_code + 1 + LINK_SIZE +
-  ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
-    *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
-    ? IMM2_SIZE:0);
-
 /* The first thing in any (sub) pattern is a bracket of some sort. Push all
 the alternative states onto the list, and find out where the end is. This
 makes is possible to use this function recursively, when we want to stop at a
 matching internal ket rather than at the end.
 
-If the first opcode in the first alternative is OP_REVERSE, we are dealing with
-a backward assertion. In that case, we have to find out the maximum amount to
-move back, and set up each alternative appropriately. */
+If we are dealing with a backward assertion we have to find out the maximum
+amount to move back, and set up each alternative appropriately. */
 
-if (*first_op == OP_REVERSE)
+if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)
   {
   size_t max_back = 0;
   size_t gone_back;
@@ -457,7 +508,8 @@
       {
       if (current_subject <= start_subject) break;
       current_subject--;
-      ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--);
+      ACROSSCHAR(current_subject > start_subject, current_subject,
+        current_subject--);
       }
     }
   else
@@ -476,15 +528,17 @@
   if (current_subject < mb->start_used_ptr)
     mb->start_used_ptr = current_subject;
 
-  /* Now we can process the individual branches. */
+  /* Now we can process the individual branches. There will be an OP_REVERSE at
+  the start of each branch, except when the length of the branch is zero. */
 
   end_code = this_start_code;
   do
     {
-    size_t back = (size_t)GET(end_code, 2+LINK_SIZE);
+    uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + LINK_SIZE : 0;
+    size_t back = (revlen == 0)? 0 : (size_t)GET(end_code, 2+LINK_SIZE);
     if (back <= gone_back)
       {
-      int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE);
+      int bstate = (int)(end_code - start_code + 1 + LINK_SIZE + revlen);
       ADD_NEW_DATA(-bstate, 0, (int)(gone_back - back));
       }
     end_code += GET(end_code, 1);
@@ -697,7 +751,7 @@
       case OP_TABLE_LENGTH +
         ((sizeof(coptable) == OP_TABLE_LENGTH) &&
          (sizeof(poptable) == OP_TABLE_LENGTH)):
-      break;
+      return 0;
 
 /* ========================================================================== */
       /* Reached a closing bracket. If not at the end of the pattern, carry
@@ -1371,25 +1425,14 @@
       if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
       if (clen > 0)
         {
-        uint32_t lgb, rgb;
-        PCRE2_SPTR nptr = ptr + clen;
         int ncount = 0;
         if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
           {
           active_count--;           /* Remove non-match possibility */
           next_active_state--;
           }
-        lgb = UCD_GRAPHBREAK(c);
-        while (nptr < end_subject)
-          {
-          dlen = 1;
-          if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
-          rgb = UCD_GRAPHBREAK(d);
-          if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
-          ncount++;
-          lgb = rgb;
-          nptr += dlen;
-          }
+        (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
+          &ncount);
         count++;
         ADD_NEW_DATA(-state_offset, count, ncount);
         }
@@ -1632,8 +1675,6 @@
       ADD_ACTIVE(state_offset + 2, 0);
       if (clen > 0)
         {
-        uint32_t lgb, rgb;
-        PCRE2_SPTR nptr = ptr + clen;
         int ncount = 0;
         if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
             codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
@@ -1641,17 +1682,8 @@
           active_count--;           /* Remove non-match possibility */
           next_active_state--;
           }
-        lgb = UCD_GRAPHBREAK(c);
-        while (nptr < end_subject)
-          {
-          dlen = 1;
-          if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
-          rgb = UCD_GRAPHBREAK(d);
-          if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
-          ncount++;
-          lgb = rgb;
-          nptr += dlen;
-          }
+        (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
+          &ncount);
         ADD_NEW_DATA(-(state_offset + count), 0, ncount);
         }
       break;
@@ -1904,25 +1936,15 @@
       count = current_state->count;  /* Number already matched */
       if (clen > 0)
         {
-        uint32_t lgb, rgb;
-        PCRE2_SPTR nptr = ptr + clen;
+        PCRE2_SPTR nptr;
         int ncount = 0;
         if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
           {
           active_count--;           /* Remove non-match possibility */
           next_active_state--;
           }
-        lgb = UCD_GRAPHBREAK(c);
-        while (nptr < end_subject)
-          {
-          dlen = 1;
-          if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
-          rgb = UCD_GRAPHBREAK(d);
-          if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
-          ncount++;
-          lgb = rgb;
-          nptr += dlen;
-          }
+        nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
+          &ncount);
         if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
             reset_could_continue = TRUE;
         if (++count >= (int)GET2(code, 1))
@@ -2099,20 +2121,9 @@
       case OP_EXTUNI:
       if (clen > 0)
         {
-        uint32_t lgb, rgb;
-        PCRE2_SPTR nptr = ptr + clen;
         int ncount = 0;
-        lgb = UCD_GRAPHBREAK(c);
-        while (nptr < end_subject)
-          {
-          dlen = 1;
-          if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
-          rgb = UCD_GRAPHBREAK(d);
-          if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
-          ncount++;
-          lgb = rgb;
-          nptr += dlen;
-          }
+        PCRE2_SPTR nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject,
+          end_subject, utf, &ncount);
         if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
             reset_could_continue = TRUE;
         ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
@@ -2136,6 +2147,7 @@
         case 0x2029:
 #endif  /* Not EBCDIC */
         if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
+        /* Fall through */
 
         case CHAR_LF:
         ADD_NEW(state_offset + 1, 0);
@@ -2225,7 +2237,7 @@
       case OP_NOTI:
       if (clen > 0)
         {
-        unsigned int otherd;
+        uint32_t otherd;
 #ifdef SUPPORT_UNICODE
         if (utf && d >= 128)
           otherd = UCD_OTHERCASE(d);
@@ -2539,11 +2551,13 @@
           if (isinclass)
             {
             int max = (int)GET2(ecode, 1 + IMM2_SIZE);
-            if (*ecode == OP_CRPOSRANGE)
+
+            if (*ecode == OP_CRPOSRANGE && count >= (int)GET2(ecode, 1))
               {
               active_count--;           /* Remove non-match possibility */
               next_active_state--;
               }
+
             if (++count >= max && max != 0)   /* Max 0 => no limit */
               { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
             else
@@ -2591,7 +2605,7 @@
           sizeof(local_workspace)/sizeof(int),  /* size of same */
           rlevel);                              /* function recursion level */
 
-        if (rc == PCRE2_ERROR_DFA_UITEM) return rc;
+        if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
         if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
             { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
         }
@@ -2613,45 +2627,10 @@
         if (code[LINK_SIZE + 1] == OP_CALLOUT
             || code[LINK_SIZE + 1] == OP_CALLOUT_STR)
           {
-          PCRE2_SIZE callout_length = (code[LINK_SIZE + 1] == OP_CALLOUT)?
-            (PCRE2_SIZE)PRIV(OP_lengths)[OP_CALLOUT] :
-            (PCRE2_SIZE)GET(code, 2 + 3*LINK_SIZE);
-
-          rrc = 0;
-          if (mb->callout != NULL)
-            {
-            pcre2_callout_block cb;
-            cb.version          = 1;
-            cb.capture_top      = 1;
-            cb.capture_last     = 0;
-            cb.offset_vector    = offsets;
-            cb.mark             = NULL;   /* No (*MARK) support */
-            cb.subject          = start_subject;
-            cb.subject_length   = (PCRE2_SIZE)(end_subject - start_subject);
-            cb.start_match      = (PCRE2_SIZE)(current_subject - start_subject);
-            cb.current_position = (PCRE2_SIZE)(ptr - start_subject);
-            cb.pattern_position = GET(code, LINK_SIZE + 2);
-            cb.next_item_length = GET(code, LINK_SIZE + 2 + LINK_SIZE);
-
-            if (code[LINK_SIZE + 1] == OP_CALLOUT)
-              {
-              cb.callout_number = code[2 + 3*LINK_SIZE];
-              cb.callout_string_offset = 0;
-              cb.callout_string = NULL;
-              cb.callout_string_length = 0;
-              }
-            else
-              {
-              cb.callout_number = 0;
-              cb.callout_string_offset = GET(code, 2 + 4*LINK_SIZE);
-              cb.callout_string = code + (2 + 5*LINK_SIZE) + 1;
-              cb.callout_string_length =
-                callout_length - (1 + 4*LINK_SIZE) - 2;
-              }
-
-            if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0)
-              return rrc;   /* Abandon */
-            }
+          PCRE2_SIZE callout_length;
+          rrc = do_callout(code, offsets, current_subject, ptr, mb,
+            1 + LINK_SIZE, &callout_length);
+          if (rrc < 0) return rrc;                 /* Abandon */
           if (rrc > 0) break;                      /* Fail this thread */
           code += callout_length;                  /* Skip callout data */
           }
@@ -2710,7 +2689,7 @@
             sizeof(local_workspace)/sizeof(int),  /* size of same */
             rlevel);                              /* function recursion level */
 
-          if (rc == PCRE2_ERROR_DFA_UITEM) return rc;
+          if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
           if ((rc >= 0) ==
                 (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
             { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
@@ -2889,7 +2868,6 @@
 
       /*-----------------------------------------------------------------*/
       case OP_ONCE:
-      case OP_ONCE_NC:
         {
         PCRE2_SIZE local_offsets[2];
         int local_workspace[1000];
@@ -2984,44 +2962,10 @@
       case OP_CALLOUT:
       case OP_CALLOUT_STR:
         {
-        unsigned int callout_length = (*code == OP_CALLOUT)
-            ? PRIV(OP_lengths)[OP_CALLOUT] : GET(code, 1 + 2*LINK_SIZE);
-        rrc = 0;
-
-        if (mb->callout != NULL)
-          {
-          pcre2_callout_block cb;
-          cb.version          = 1;
-          cb.capture_top      = 1;
-          cb.capture_last     = 0;
-          cb.offset_vector    = offsets;
-          cb.mark             = NULL;   /* No (*MARK) support */
-          cb.subject          = start_subject;
-          cb.subject_length   = (PCRE2_SIZE)(end_subject - start_subject);
-          cb.start_match      = (PCRE2_SIZE)(current_subject - start_subject);
-          cb.current_position = (PCRE2_SIZE)(ptr - start_subject);
-          cb.pattern_position = GET(code, 1);
-          cb.next_item_length = GET(code, 1 + LINK_SIZE);
-
-          if (*code == OP_CALLOUT)
-            {
-            cb.callout_number = code[1 + 2*LINK_SIZE];
-            cb.callout_string_offset = 0;
-            cb.callout_string = NULL;
-            cb.callout_string_length = 0;
-            }
-          else
-            {
-            cb.callout_number = 0;
-            cb.callout_string_offset = GET(code, 1 + 3*LINK_SIZE);
-            cb.callout_string = code + (1 + 4*LINK_SIZE) + 1;
-            cb.callout_string_length =
-              callout_length - (1 + 4*LINK_SIZE) - 2;
-            }
-
-          if ((rrc = (mb->callout)(&cb, mb->callout_data)) < 0)
-            return rrc;   /* Abandon */
-          }
+        PCRE2_SIZE callout_length;
+        rrc = do_callout(code, offsets, current_subject, ptr, mb, 0,
+          &callout_length);
+        if (rrc < 0) return rrc;   /* Abandon */
         if (rrc == 0)
           { ADD_ACTIVE(state_offset + (int)callout_length, 0); }
         }
@@ -3069,7 +3013,7 @@
           )
         )
       match_count = PCRE2_ERROR_PARTIAL;
-    break;        /* In effect, "return", but see the comment below */
+    break;  /* Exit from loop along the subject string */
     }
 
   /* One or more states are active for the next character. */
@@ -3077,11 +3021,13 @@
   ptr += clen;    /* Advance to next subject character */
   }               /* Loop to move along the subject string */
 
-/* Control gets here from "break" a few lines above. We do it this way because
-if we use "return" above, we have compiler trouble. Some compilers warn if
-there's nothing here because they think the function doesn't return a value. On
-the other hand, if we put a dummy statement here, some more clever compilers
-complain that it can't be reached. Sigh. */
+/* Control gets here from "break" a few lines above. If we have a match and
+PCRE2_ENDANCHORED is set, the match fails. */
+
+if (match_count >= 0 &&
+    ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0 &&
+    ptr < end_subject)
+  match_count = PCRE2_ERROR_NOMATCH;
 
 return match_count;
 }
@@ -3115,7 +3061,7 @@
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
   PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
-  pcre2_match_context *mcontext, int *workspace, size_t wscount)
+  pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount)
 {
 const pcre2_real_code *re = (const pcre2_real_code *)code;
 
@@ -3138,6 +3084,7 @@
 /* We need to have mb pointing to a match block, because the IS_NEWLINE macro
 is used below, and it expects NLBLOCK to be defined as a pointer. */
 
+pcre2_callout_block cb;
 dfa_match_block actual_match_block;
 dfa_match_block *mb = &actual_match_block;
 
@@ -3154,6 +3101,13 @@
 if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE;
 if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
 
+/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
+time. */
+
+if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
+   ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
+  return PCRE2_ERROR_BADOPTION;
+
 /* Check that the first field in the block is the magic number. If it is not,
 return with PCRE2_ERROR_BADMAGIC. */
 
@@ -3208,14 +3162,28 @@
 firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
 bumpalong_limit = end_subject;
 
-/* Get data from the match context, if present, and fill in the fields in the
-match block. It is an error to set an offset limit without setting the flag at
-compile time. */
+/* Initialize and set up the fixed fields in the callout block, with a pointer
+in the match block. */
+
+mb->cb = &cb;
+cb.version = 2;
+cb.subject = subject;
+cb.subject_length = (PCRE2_SIZE)(end_subject - subject);
+cb.callout_flags = 0;
+cb.capture_top      = 1;      /* No capture support */
+cb.capture_last     = 0;
+cb.mark             = NULL;   /* No (*MARK) support */
+
+/* Get data from the match context, if present, and fill in the remaining
+fields in the match block. It is an error to set an offset limit without
+setting the flag at compile time. */
 
 if (mcontext == NULL)
   {
   mb->callout = NULL;
   mb->memctl = re->memctl;
+  mb->match_limit = PRIV(default_match_context).match_limit;
+  mb->match_limit_depth = PRIV(default_match_context).depth_limit;
   }
 else
   {
@@ -3228,8 +3196,16 @@
   mb->callout = mcontext->callout;
   mb->callout_data = mcontext->callout_data;
   mb->memctl = mcontext->memctl;
+  mb->match_limit = mcontext->match_limit;
+  mb->match_limit_depth = mcontext->depth_limit;
   }
 
+if (mb->match_limit > re->limit_match)
+  mb->match_limit = re->limit_match;
+
+if (mb->match_limit_depth > re->limit_depth)
+  mb->match_limit_depth = re->limit_depth;
+
 mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
   re->name_count * re->name_entry_size;
 mb->tables = re->tables;
@@ -3238,6 +3214,7 @@
 mb->start_offset = start_offset;
 mb->moptions = options;
 mb->poptions = re->overall_options;
+mb->match_call_count = 0;
 
 /* Process the \R and newline settings. */
 
@@ -3255,6 +3232,11 @@
   mb->nl[0] = CHAR_NL;
   break;
 
+  case PCRE2_NEWLINE_NUL:
+  mb->nllen = 1;
+  mb->nl[0] = CHAR_NUL;
+  break;
+
   case PCRE2_NEWLINE_CRLF:
   mb->nllen = 2;
   mb->nl[0] = CHAR_CR;
@@ -3321,34 +3303,27 @@
   }
 #endif  /* SUPPORT_UNICODE */
 
-/* Set up the first code unit to match, if available. The first_codeunit value
-is never set for an anchored regular expression, but the anchoring may be
-forced at run time, so we have to test for anchoring. The first code unit may
-be unset for an unanchored pattern, of course. If there's no first code unit
-there may be a bitmap of possible first characters. */
+/* Set up the first code unit to match, if available. If there's no first code
+unit there may be a bitmap of possible first characters. */
 
-if (!anchored)
+if ((re->flags & PCRE2_FIRSTSET) != 0)
   {
-  if ((re->flags & PCRE2_FIRSTSET) != 0)
+  has_first_cu = TRUE;
+  first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
+  if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
     {
-    has_first_cu = TRUE;
-    first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
-    if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
-      {
-      first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);
+    first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
-      if (utf && first_cu > 127)
-        first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
+    if (utf && first_cu > 127)
+      first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
 #endif
-      }
     }
-  else
-    if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
-      start_bits = re->start_bitmap;
   }
+else
+  if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
+    start_bits = re->start_bitmap;
 
-/* For anchored or unanchored matches, there may be a "last known required
-character" set. */
+/* There may be a "last known required code unit" set. */
 
 if ((re->flags & PCRE2_LASTSET) != 0)
   {
@@ -3389,13 +3364,13 @@
   if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 &&
       (options & PCRE2_DFA_RESTART) == 0)
     {
-    PCRE2_SPTR save_end_subject = end_subject;
-
     /* 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
-    first newline. Implement this by temporarily adjusting end_subject so that
-    we stop the optimization scans at a newline. If the match fails at the
-    newline, later code breaks this loop. */
+    first newline following the start of matching. Temporarily adjust
+    end_subject so that we stop the optimization scans for a first code unit
+    immediately after the first character of a newline (the first code unit can
+    legitimately be a newline). If the match fails at the newline, later code
+    breaks this loop. */
 
     if (firstline)
       {
@@ -3403,85 +3378,162 @@
 #ifdef SUPPORT_UNICODE
       if (utf)
         {
-        while (t < mb->end_subject && !IS_NEWLINE(t))
+        while (t < end_subject && !IS_NEWLINE(t))
           {
           t++;
-          ACROSSCHAR(t < end_subject, *t, t++);
+          ACROSSCHAR(t < end_subject, t, t++);
           }
         }
       else
 #endif
-      while (t < mb->end_subject && !IS_NEWLINE(t)) t++;
+      while (t < end_subject && !IS_NEWLINE(t)) t++;
       end_subject = t;
       }
 
-    /* Advance to a unique first code unit if there is one. */
+    /* Anchored: check the first code unit if one is recorded. This may seem
+    pointless but it can help in detecting a no match case without scanning for
+    the required code unit. */
 
-    if (has_first_cu)
+    if (anchored)
       {
-      PCRE2_UCHAR smc;
-      if (first_cu != first_cu2)
-        while (start_match < end_subject &&
-          (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2)
-          start_match++;
-      else
-        while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu)
-          start_match++;
-      }
-
-    /* Or to just after a linebreak for a multiline match */
-
-    else if (startline)
-      {
-      if (start_match > mb->start_subject + start_offset)
+      if (has_first_cu || start_bits != NULL)
         {
-#ifdef SUPPORT_UNICODE
-        if (utf)
+        BOOL ok = start_match < end_subject;
+        if (ok)
           {
-          while (start_match < end_subject && !WAS_NEWLINE(start_match))
+          PCRE2_UCHAR c = UCHAR21TEST(start_match);
+          ok = has_first_cu && (c == first_cu || c == first_cu2);
+          if (!ok && start_bits != NULL)
             {
-            start_match++;
-            ACROSSCHAR(start_match < end_subject, *start_match,
-              start_match++);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+            if (c > 255) c = 255;
+#endif
+            ok = (start_bits[c/8] & (1 << (c&7))) != 0;
             }
           }
-        else
-#endif
-        while (start_match < end_subject && !WAS_NEWLINE(start_match))
-          start_match++;
-
-        /* If we have just passed a CR and the newline option is ANY or
-        ANYCRLF, and we are now at a LF, advance the match position by one more
-        code unit. */
-
-        if (start_match[-1] == CHAR_CR &&
-             (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
-             start_match < end_subject &&
-             UCHAR21TEST(start_match) == CHAR_NL)
-          start_match++;
+        if (!ok) break;
         }
       }
 
-    /* Or to a non-unique first code unit if any have been identified. The
-    bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all
-    code units greater than 254 set the 255 bit. */
+    /* Not anchored. Advance to a unique first code unit if there is one. In
+    8-bit mode, the use of memchr() gives a big speed up, even though we have
+    to call it twice in caseless mode, in order to find the earliest occurrence
+    of the character in either of its cases. */
 
-    else if (start_bits != NULL)
+    else
       {
-      while (start_match < end_subject)
+      if (has_first_cu)
         {
-        register uint32_t c = UCHAR21TEST(start_match);
+        if (first_cu != first_cu2)  /* Caseless */
+          {
 #if PCRE2_CODE_UNIT_WIDTH != 8
-        if (c > 255) c = 255;
+          PCRE2_UCHAR smc;
+          while (start_match < end_subject &&
+                (smc = UCHAR21TEST(start_match)) != first_cu &&
+                  smc != first_cu2)
+            start_match++;
+#else  /* 8-bit code units */
+          PCRE2_SPTR pp1 =
+            memchr(start_match, first_cu, end_subject-start_match);
+          PCRE2_SPTR pp2 =
+            memchr(start_match, first_cu2, end_subject-start_match);
+          if (pp1 == NULL)
+            start_match = (pp2 == NULL)? end_subject : pp2;
+          else
+            start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;
 #endif
-        if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
-        start_match++;
+          }
+
+        /* The caseful case */
+
+        else
+          {
+#if PCRE2_CODE_UNIT_WIDTH != 8
+          while (start_match < end_subject && UCHAR21TEST(start_match) !=
+                 first_cu)
+            start_match++;
+#else
+          start_match = memchr(start_match, first_cu, end_subject - start_match);
+          if (start_match == NULL) start_match = end_subject;
+#endif
+          }
+
+        /* If we can't find the required code unit, having reached the true end
+        of the subject, break the bumpalong loop, to force a match failure,
+        except when doing partial matching, when we let the next cycle run at
+        the end of the subject. To see why, consider the pattern /(?<=abc)def/,
+        which partially matches "abc", even though the string does not contain
+        the starting character "d". If we have not reached the true end of the
+        subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified)
+        we also let the cycle run, because the matching string is legitimately
+        allowed to start with the first code unit of a newline. */
+
+        if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&
+            start_match >= mb->end_subject)
+          break;
         }
-      }
+
+      /* If there's no first code unit, advance to just after a linebreak for a
+      multiline match if required. */
+
+      else if (startline)
+        {
+        if (start_match > mb->start_subject + start_offset)
+          {
+#ifdef SUPPORT_UNICODE
+          if (utf)
+            {
+            while (start_match < end_subject && !WAS_NEWLINE(start_match))
+              {
+              start_match++;
+              ACROSSCHAR(start_match < end_subject, start_match, start_match++);
+              }
+            }
+          else
+#endif
+          while (start_match < end_subject && !WAS_NEWLINE(start_match))
+            start_match++;
+
+          /* If we have just passed a CR and the newline option is ANY or
+          ANYCRLF, and we are now at a LF, advance the match position by one
+          more code unit. */
+
+          if (start_match[-1] == CHAR_CR &&
+               (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
+               start_match < end_subject &&
+               UCHAR21TEST(start_match) == CHAR_NL)
+            start_match++;
+          }
+        }
+
+      /* If there's no first code unit or a requirement for a multiline line
+      start, advance to a non-unique first code unit if any have been
+      identified. The bitmap contains only 256 bits. When code units are 16 or
+      32 bits wide, all code units greater than 254 set the 255 bit. */
+
+      else if (start_bits != NULL)
+        {
+        while (start_match < end_subject)
+          {
+          uint32_t c = UCHAR21TEST(start_match);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+          if (c > 255) c = 255;
+#endif
+          if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
+          start_match++;
+          }
+
+        /* See comment above in first_cu checking about the next line. */
+
+        if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&
+            start_match >= mb->end_subject)
+          break;
+        }
+      }  /* End of first code unit handling */
 
     /* Restore fudged end_subject */
 
-    end_subject = save_end_subject;
+    end_subject = mb->end_subject;
 
     /* The following two optimizations are disabled for partial matching. */
 
@@ -3510,7 +3562,7 @@
 
       if (has_req_cu && end_subject - start_match < REQ_CU_MAX)
         {
-        register PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
+        PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
 
         /* We don't need to repeat the search if we haven't yet reached the
         place we found it at last time. */
@@ -3521,7 +3573,7 @@
             {
             while (p < end_subject)
               {
-              register uint32_t pp = UCHAR21INCTEST(p);
+              uint32_t pp = UCHAR21INCTEST(p);
               if (pp == req_cu || pp == req_cu2) { p--; break; }
               }
             }
@@ -3596,8 +3648,7 @@
 #ifdef SUPPORT_UNICODE
   if (utf)
     {
-    ACROSSCHAR(start_match < end_subject, *start_match,
-      start_match++);
+    ACROSSCHAR(start_match < end_subject, start_match, start_match++);
     }
 #endif
   if (start_match > end_subject) break;
diff --git a/dist2/src/pcre2_error.c b/dist2/src/pcre2_error.c
index 77fd5f4..d98cae9 100644
--- a/dist2/src/pcre2_error.c
+++ b/dist2/src/pcre2_error.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -91,13 +91,13 @@
   "failed to allocate heap memory\0"
   "unmatched closing parenthesis\0"
   "internal error: code overflow\0"
-  "letter or underscore expected after (?< or (?'\0"
+  "missing closing parenthesis for condition\0"
   /* 25 */
   "lookbehind assertion is not fixed length\0"
-  "malformed number or name after (?(\0"
+  "a relative value of zero is not allowed\0"
   "conditional group contains more than two branches\0"
   "assertion expected after (?( or (?(?C)\0"
-  "(?R or (?[+-]digits must be followed by )\0"
+  "digit expected after (?+ or (?-\0"
   /* 30 */
   "unknown POSIX class name\0"
   "internal error in pcre2_study(): should not occur\0"
@@ -105,7 +105,7 @@
   "parentheses are too deeply nested (stack check)\0"
   "character code point value in \\x{} or \\o{} is too large\0"
   /* 35 */
-  "invalid condition (?(0)\0"
+  "lookbehind is too complicated\0"
   "\\C is not allowed in a lookbehind assertion in UTF-" XSTRING(PCRE2_CODE_UNIT_WIDTH) " mode\0"
   "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0"
   "number after (?C is greater than 255\0"
@@ -132,13 +132,13 @@
   "missing opening brace after \\o\0"
   "internal error: unknown newline setting\0"
   "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
-  "a numbered reference must not be zero\0"
+  "(?R (recursive pattern call) must be followed by a closing parenthesis\0"
   "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
   /* 60 */
   "(*VERB) not recognized or malformed\0"
-  "number is too big\0"
+  "group number is too big\0"
   "subpattern name expected\0"
-  "digit expected after (?+\0"
+  "internal error: parsed pattern overflow\0"
   "non-octal character in \\o{} (closing brace missing?)\0"
   /* 65 */
   "different names for subpatterns of the same number are not allowed\0"
@@ -151,9 +151,9 @@
 #endif
   "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
   /* 70 */
-  "internal error: unknown opcode in find_fixedlength()\0"
+  "internal error: unknown meta code in check_lookbehinds()\0"
   "\\N is not supported in a class\0"
-  "SPARE ERROR\0"
+  "callout string is too long\0"
   "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
   "using UTF is disabled by the application\0"
   /* 75 */
@@ -161,7 +161,7 @@
   "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{}\0"
-  "syntax error in (?(VERSION condition\0"
+  "syntax error or number too big in (?(VERSION condition\0"
   /* 80 */
   "internal error: unknown opcode in auto_possessify()\0"
   "missing terminating delimiter for callout with string argument\0"
@@ -173,6 +173,11 @@
   "regular expression is too complicated\0"
   "lookbehind assertion is too long\0"
   "pattern string is longer than the limit set by the application\0"
+  "internal error: unknown code in parsed pattern\0"
+  /* 90 */
+  "internal error: bad code value in parsed_skip()\0"
+  "PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode\0"
+  "invalid option bits with PCRE2_LITERAL\0"
   ;
 
 /* Match-time and UTF error texts are in the same format. */
@@ -241,7 +246,7 @@
   "non-unique substring name\0"
   "NULL argument passed\0"
   "nested recursion at the same subject position\0"
-  "recursion limit exceeded\0"
+  "matching depth limit exceeded\0"
   "requested value is not available\0"
   /* 55 */
   "requested value is not set\0"
@@ -253,6 +258,8 @@
   "match with end before start is not supported\0"
   "too many replacements (more than INT_MAX)\0"
   "bad serialized data\0"
+  "heap limit exceeded\0"
+  "invalid syntax\0"
   ;
 
 
@@ -268,17 +275,17 @@
 Arguments:
   enumber       error number
   buffer        where to put the message (zero terminated)
-  size          size of the buffer
+  size          size of the buffer in code units
 
 Returns:        length of message if all is well
                 negative on error
 */
 
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
-pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, size_t size)
+pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, PCRE2_SIZE size)
 {
 const unsigned char *message;
-size_t i;
+PCRE2_SIZE i;
 int n;
 
 if (size == 0) return PCRE2_ERROR_NOMEMORY;
@@ -301,8 +308,8 @@
 
 for (; n > 0; n--)
   {
-  while (*message++ != CHAR_NULL) {};
-  if (*message == CHAR_NULL) return PCRE2_ERROR_BADDATA;
+  while (*message++ != CHAR_NUL) {};
+  if (*message == CHAR_NUL) return PCRE2_ERROR_BADDATA;
   }
 
 for (i = 0; *message != 0; i++)
diff --git a/dist2/src/pcre2_extuni.c b/dist2/src/pcre2_extuni.c
new file mode 100644
index 0000000..11a0bfb
--- /dev/null
+++ b/dist2/src/pcre2_extuni.c
@@ -0,0 +1,148 @@
+/*************************************************
+*      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-2018 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.
+-----------------------------------------------------------------------------
+*/
+
+/* 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
+compiled. Nevertheless, we provide a dummy function when there is no Unicode
+support, because some compilers do not like functionless source files. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "pcre2_internal.h"
+
+
+/* Dummy function */
+
+#ifndef SUPPORT_UNICODE
+PCRE2_SPTR
+PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
+  PCRE2_SPTR end_subject, BOOL utf, int *xcount)
+{
+(void)c;
+(void)eptr;
+(void)start_subject;
+(void)end_subject;
+(void)utf;
+(void)xcount;
+return NULL;
+}
+#else
+
+
+/*************************************************
+*      Match an extended grapheme sequence       *
+*************************************************/
+
+/*
+Arguments:
+  c              the first character
+  eptr           pointer to next character
+  start_subject  pointer to start of subject
+  end_subject    pointer to end of subject
+  utf            TRUE if in UTF mode
+  xcount         pointer to count of additional characters,
+                   or NULL if count not needed
+
+Returns:         pointer after the end of the sequence
+*/
+
+PCRE2_SPTR
+PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
+  PCRE2_SPTR end_subject, BOOL utf, int *xcount)
+{
+int lgb = UCD_GRAPHBREAK(c);
+
+while (eptr < end_subject)
+  {
+  int rgb;
+  int len = 1;
+  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+  rgb = UCD_GRAPHBREAK(c);
+  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+
+  /* Not breaking between Regional Indicators is allowed only if there
+  are an even number of preceding RIs. */
+
+  if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator)
+    {
+    int ricount = 0;
+    PCRE2_SPTR bptr = eptr - 1;
+    if (utf) BACKCHAR(bptr);
+
+    /* bptr is pointing to the left-hand character */
+
+    while (bptr > start_subject)
+      {
+      bptr--;
+      if (utf)
+        {
+        BACKCHAR(bptr);
+        GETCHAR(c, bptr);
+        }
+      else
+      c = *bptr;
+      if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break;
+      ricount++;
+      }
+    if ((ricount & 1) != 0) break;  /* Grapheme break required */
+    }
+
+  /* If Extend follows E_Base[_GAZ] do not update lgb; this allows
+  any number of Extend before a following E_Modifier. */
+
+  if (rgb != ucp_gbExtend ||
+      (lgb != ucp_gbE_Base && lgb != ucp_gbE_Base_GAZ))
+    lgb = rgb;
+
+  eptr += len;
+  if (xcount != NULL) *xcount += 1;
+  }
+
+return eptr;
+}
+
+#endif  /* SUPPORT_UNICODE */
+
+/* End of pcre2_extuni.c */
diff --git a/dist2/src/pcre2_find_bracket.c b/dist2/src/pcre2_find_bracket.c
index 803e719..357385a 100644
--- a/dist2/src/pcre2_find_bracket.c
+++ b/dist2/src/pcre2_find_bracket.c
@@ -71,7 +71,7 @@
 {
 for (;;)
   {
-  register PCRE2_UCHAR c = *code;
+  PCRE2_UCHAR c = *code;
 
   if (c == OP_END) return NULL;
 
diff --git a/dist2/src/pcre2_fuzzsupport.c b/dist2/src/pcre2_fuzzsupport.c
new file mode 100644
index 0000000..48781ff
--- /dev/null
+++ b/dist2/src/pcre2_fuzzsupport.c
@@ -0,0 +1,365 @@
+/***************************************************************************
+Fuzzer driver for PCRE2. Given an arbitrary string of bytes and a length, it
+tries to compile and match it, deriving options from the string itself. If
+STANDALONE is defined, a main program that calls the driver with the contents
+of specified files is compiled, and commentary on what is happening is output.
+If an argument starts with '=' the rest of it it is taken as a literal string
+rather than a file name. This allows easy testing of short strings.
+
+Written by Philip Hazel, October 2016
+***************************************************************************/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include "pcre2.h"
+
+#define MAX_MATCH_SIZE 1000
+
+#define DFA_WORKSPACE_COUNT 100
+
+#define ALLOWED_COMPILE_OPTIONS \
+  (PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
+   PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \
+   PCRE2_DOTALL|PCRE2_DUPNAMES|PCRE2_ENDANCHORED|PCRE2_EXTENDED|PCRE2_FIRSTLINE| \
+   PCRE2_MATCH_UNSET_BACKREF|PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C| \
+   PCRE2_NO_AUTO_CAPTURE| \
+   PCRE2_NO_AUTO_POSSESS|PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_NO_START_OPTIMIZE| \
+   PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_USE_OFFSET_LIMIT| \
+   PCRE2_UTF)
+
+#define ALLOWED_MATCH_OPTIONS \
+  (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
+   PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_HARD| \
+   PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT)
+
+/* This is the callout function. Its only purpose is to halt matching if there
+are more than 100 callouts, as one way of stopping too much time being spent on
+fruitless matches. The callout data is a pointer to the counter. */
+
+static int callout_function(pcre2_callout_block *cb, void *callout_data)
+{
+(void)cb;  /* Avoid unused parameter warning */
+*((uint32_t *)callout_data) += 1;
+return (*((uint32_t *)callout_data) > 100)? PCRE2_ERROR_CALLOUT : 0;
+}
+
+/* Putting in this apparently unnecessary prototype prevents gcc from giving a
+"no previous prototype" warning when compiling at high warning level. */
+
+int LLVMFuzzerTestOneInput(const unsigned char *, size_t);
+
+/* Here's the driving function. */
+
+int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size)
+{
+uint32_t compile_options;
+uint32_t match_options;
+pcre2_match_data *match_data = NULL;
+pcre2_match_context *match_context = NULL;
+size_t match_size;
+int dfa_workspace[DFA_WORKSPACE_COUNT];
+int r1, r2;
+int i;
+
+if (size < 1) return 0;
+
+/* Limiting the length of the subject for matching stops fruitless searches
+in large trees taking too much time. */
+
+match_size = (size > MAX_MATCH_SIZE)? MAX_MATCH_SIZE : size;
+
+/* Figure out some options to use. Initialize the random number to ensure
+repeatability. Ensure that we get a 32-bit unsigned random number for testing
+options. (RAND_MAX is required to be at least 32767, but is commonly
+2147483647, which excludes the top bit.) */
+
+srand((unsigned int)(data[size/2]));
+r1 = rand();
+r2 = rand();
+
+/* Ensure that all undefined option bits are zero (waste of time trying them)
+and also that PCRE2_NO_UTF_CHECK is unset, as there is no guarantee that the
+input is UTF-8. Also unset PCRE2_NEVER_UTF and PCRE2_NEVER_UCP as there is no
+reason to disallow UTF and UCP. Force PCRE2_NEVER_BACKSLASH_C to be set because
+\C in random patterns is highly likely to cause a crash. */
+
+compile_options =
+  ((((uint32_t)r1 << 16) | ((uint32_t)r2 & 0xffff)) & ALLOWED_COMPILE_OPTIONS) |
+  PCRE2_NEVER_BACKSLASH_C;
+  
+match_options =
+  ((((uint32_t)r1 << 16) | ((uint32_t)r2 & 0xffff)) & ALLOWED_MATCH_OPTIONS);
+  
+/* Discard partial matching if PCRE2_ENDANCHORED is set, because they are not
+allowed together and just give an immediate error return. */
+
+if (((compile_options|match_options) & PCRE2_ENDANCHORED) != 0)
+  match_options &= ~(PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT); 
+
+/* Do the compile with and without the options, and after a successful compile,
+likewise do the match with and without the options. */
+
+for (i = 0; i < 2; i++)
+  {
+  uint32_t callout_count;
+  int errorcode;
+  PCRE2_SIZE erroroffset;
+  pcre2_code *code;
+
+#ifdef STANDALONE
+  printf("Compile options %.8x never_backslash_c", compile_options);
+  printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+    ((compile_options & PCRE2_ALT_BSUX) != 0)? ",alt_bsux" : "",
+    ((compile_options & PCRE2_ALT_CIRCUMFLEX) != 0)? ",alt_circumflex" : "",
+    ((compile_options & PCRE2_ALT_VERBNAMES) != 0)? ",alt_verbnames" : "",
+    ((compile_options & PCRE2_ALLOW_EMPTY_CLASS) != 0)? ",allow_empty_class" : "",
+    ((compile_options & PCRE2_ANCHORED) != 0)? ",anchored" : "",
+    ((compile_options & PCRE2_AUTO_CALLOUT) != 0)? ",auto_callout" : "",
+    ((compile_options & PCRE2_CASELESS) != 0)? ",caseless" : "",
+    ((compile_options & PCRE2_DOLLAR_ENDONLY) != 0)? ",dollar_endonly" : "",
+    ((compile_options & PCRE2_DOTALL) != 0)? ",dotall" : "",
+    ((compile_options & PCRE2_DUPNAMES) != 0)? ",dupnames" : "",
+    ((compile_options & PCRE2_ENDANCHORED) != 0)? ",endanchored" : "",
+    ((compile_options & PCRE2_EXTENDED) != 0)? ",extended" : "",
+    ((compile_options & PCRE2_FIRSTLINE) != 0)? ",firstline" : "",
+    ((compile_options & PCRE2_MATCH_UNSET_BACKREF) != 0)? ",match_unset_backref" : "",
+    ((compile_options & PCRE2_MULTILINE) != 0)? ",multiline" : "",
+    ((compile_options & PCRE2_NEVER_UCP) != 0)? ",never_ucp" : "",
+    ((compile_options & PCRE2_NEVER_UTF) != 0)? ",never_utf" : "",
+    ((compile_options & PCRE2_NO_AUTO_CAPTURE) != 0)? ",no_auto_capture" : "",
+    ((compile_options & PCRE2_NO_AUTO_POSSESS) != 0)? ",no_auto_possess" : "",
+    ((compile_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)? ",no_dotstar_anchor" : "",
+    ((compile_options & PCRE2_NO_UTF_CHECK) != 0)? ",no_utf_check" : "",
+    ((compile_options & PCRE2_NO_START_OPTIMIZE) != 0)? ",no_start_optimize" : "",
+    ((compile_options & PCRE2_UCP) != 0)? ",ucp" : "",
+    ((compile_options & PCRE2_UNGREEDY) != 0)? ",ungreedy" : "",
+    ((compile_options & PCRE2_USE_OFFSET_LIMIT) != 0)? ",use_offset_limit" : "",
+    ((compile_options & PCRE2_UTF) != 0)? ",utf" : "");
+#endif
+
+  code = pcre2_compile((PCRE2_SPTR)data, (PCRE2_SIZE)size, compile_options,
+    &errorcode, &erroroffset, NULL);
+
+  /* Compilation succeeded */
+
+  if (code != NULL)
+    {
+    int j;
+    uint32_t save_match_options = match_options;
+
+    /* Create match data and context blocks only when we first need them. Set
+    low match and depth limits to avoid wasting too much searching large
+    pattern trees. Almost all matches are going to fail. */
+
+    if (match_data == NULL)
+      {
+      match_data = pcre2_match_data_create(32, NULL);
+      if (match_data == NULL)
+        {
+#ifdef STANDALONE
+        printf("** Failed to create match data block\n");
+#endif
+        return 0;
+        }
+      }
+
+    if (match_context == NULL)
+      {
+      match_context = pcre2_match_context_create(NULL);
+      if (match_context == NULL)
+        {
+#ifdef STANDALONE
+        printf("** Failed to create match context block\n");
+#endif
+        return 0;
+        }
+      (void)pcre2_set_match_limit(match_context, 100);
+      (void)pcre2_set_depth_limit(match_context, 100);
+      (void)pcre2_set_callout(match_context, callout_function, &callout_count);
+      }
+
+    /* Match twice, with and without options. */
+
+    for (j = 0; j < 2; j++)
+      {
+#ifdef STANDALONE
+      printf("Match options %.8x", match_options);
+      printf("%s%s%s%s%s%s%s%s%s%s\n",
+        ((match_options & PCRE2_ANCHORED) != 0)? ",anchored" : "",
+        ((match_options & PCRE2_ENDANCHORED) != 0)? ",endanchored" : "",
+        ((match_options & PCRE2_NO_JIT) != 0)? ",no_jit" : "",
+        ((match_options & PCRE2_NO_UTF_CHECK) != 0)? ",no_utf_check" : "",
+        ((match_options & PCRE2_NOTBOL) != 0)? ",notbol" : "",
+        ((match_options & PCRE2_NOTEMPTY) != 0)? ",notempty" : "",
+        ((match_options & PCRE2_NOTEMPTY_ATSTART) != 0)? ",notempty_atstart" : "",
+        ((match_options & PCRE2_NOTEOL) != 0)? ",noteol" : "",
+        ((match_options & PCRE2_PARTIAL_HARD) != 0)? ",partial_hard" : "",
+        ((match_options & PCRE2_PARTIAL_SOFT) != 0)? ",partial_soft" : "");
+#endif
+
+      callout_count = 0;
+      errorcode = pcre2_match(code, (PCRE2_SPTR)data, (PCRE2_SIZE)match_size, 0,
+        match_options, match_data, match_context);
+
+#ifdef STANDALONE
+      if (errorcode >= 0) printf("Match returned %d\n", errorcode); else
+        {
+        unsigned char buffer[256];
+        pcre2_get_error_message(errorcode, buffer, 256);
+        printf("Match failed: error %d: %s\n", errorcode, buffer);
+        }
+#endif
+
+      match_options = 0;  /* For second time */
+      }
+
+    /* Match with DFA twice, with and without options. */
+
+    match_options = save_match_options & ~PCRE2_NO_JIT;  /* Not valid for DFA */
+
+    for (j = 0; j < 2; j++)
+      {
+#ifdef STANDALONE
+      printf("DFA match options %.8x", match_options);
+      printf("%s%s%s%s%s%s%s%s%s\n",
+        ((match_options & PCRE2_ANCHORED) != 0)? ",anchored" : "",
+        ((match_options & PCRE2_ENDANCHORED) != 0)? ",endanchored" : "",
+        ((match_options & PCRE2_NO_UTF_CHECK) != 0)? ",no_utf_check" : "",
+        ((match_options & PCRE2_NOTBOL) != 0)? ",notbol" : "",
+        ((match_options & PCRE2_NOTEMPTY) != 0)? ",notempty" : "",
+        ((match_options & PCRE2_NOTEMPTY_ATSTART) != 0)? ",notempty_atstart" : "",
+        ((match_options & PCRE2_NOTEOL) != 0)? ",noteol" : "",
+        ((match_options & PCRE2_PARTIAL_HARD) != 0)? ",partial_hard" : "",
+        ((match_options & PCRE2_PARTIAL_SOFT) != 0)? ",partial_soft" : "");
+#endif
+
+      callout_count = 0;
+      errorcode = pcre2_dfa_match(code, (PCRE2_SPTR)data,
+        (PCRE2_SIZE)match_size, 0, match_options, match_data, match_context,
+        dfa_workspace, DFA_WORKSPACE_COUNT);
+
+#ifdef STANDALONE
+      if (errorcode >= 0) printf("Match returned %d\n", errorcode); else
+        {
+        unsigned char buffer[256];
+        pcre2_get_error_message(errorcode, buffer, 256);
+        printf("Match failed: error %d: %s\n", errorcode, buffer);
+        }
+#endif
+
+      match_options = 0;  /* For second time */
+      }
+
+    match_options = save_match_options;  /* Reset for the second compile */
+    pcre2_code_free(code);
+    }
+
+  /* Compilation failed */
+
+  else
+    {
+    unsigned char buffer[256];
+    pcre2_get_error_message(errorcode, buffer, 256);
+#ifdef STANDALONE
+    printf("Error %d at offset %lu: %s\n", errorcode, erroroffset, buffer);
+#else
+    if (strstr((const char *)buffer, "internal error") != NULL) abort();
+#endif
+    }
+
+  compile_options = PCRE2_NEVER_BACKSLASH_C;  /* For second time */
+  }
+
+if (match_data != NULL) pcre2_match_data_free(match_data);
+if (match_context != NULL) pcre2_match_context_free(match_context);
+
+return 0;
+}
+
+
+/* Optional main program.  */
+
+#ifdef STANDALONE
+int main(int argc, char **argv)
+{
+int i;
+
+if (argc < 2)
+  {
+  printf("** No arguments given\n");
+  return 0;
+  }
+
+for (i = 1; i < argc; i++)
+  {
+  size_t filelen;
+  size_t readsize;
+  unsigned char *buffer;
+  FILE *f;
+
+  /* Handle a literal string. Copy to an exact size buffer so that checks for
+  overrunning work. */
+
+  if (argv[i][0] == '=')
+    {
+    readsize = strlen(argv[i]) - 1;
+    printf("------ <Literal> ------\n");
+    printf("Length = %lu\n", readsize);
+    printf("%.*s\n", (int)readsize, argv[i]+1);
+    buffer = (unsigned char *)malloc(readsize);
+    if (buffer == NULL)
+      printf("** Failed to allocate %lu bytes of memory\n", readsize);
+    else
+      {
+      memcpy(buffer, argv[i]+1, readsize);
+      LLVMFuzzerTestOneInput(buffer, readsize);
+      free(buffer);
+      }
+    continue;
+    }
+
+  /* Handle a string given in a file */
+
+  f = fopen(argv[i], "rb");
+  if (f == NULL)
+    {
+    printf("** Failed to open %s: %s\n", argv[i], strerror(errno));
+    continue;
+    }
+
+  printf("------ %s ------\n", argv[i]);
+
+  fseek(f, 0, SEEK_END);
+  filelen = ftell(f);
+  fseek(f, 0, SEEK_SET);
+
+  buffer = (unsigned char *)malloc(filelen);
+  if (buffer == NULL)
+    {
+    printf("** Failed to allocate %lu bytes of memory\n", filelen);
+    fclose(f);
+    continue;
+    }
+
+  readsize = fread(buffer, 1, filelen, f);
+  fclose(f);
+
+  if (readsize != filelen)
+    printf("** File size is %lu but fread() returned %lu\n", filelen, readsize);
+  else
+    {
+    printf("Length = %lu\n", filelen);
+    LLVMFuzzerTestOneInput(buffer, filelen);
+    }
+  free(buffer);
+  }
+
+return 0;
+}
+#endif  /* STANDALONE */
+
+/* End */
diff --git a/dist2/src/pcre2_internal.h b/dist2/src/pcre2_internal.h
index 5690870..3db9d60 100644
--- a/dist2/src/pcre2_internal.h
+++ b/dist2/src/pcre2_internal.h
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,9 @@
 -----------------------------------------------------------------------------
 */
 
+#ifndef PCRE2_INTERNAL_H_IDEMPOTENT_GUARD
+#define PCRE2_INTERNAL_H_IDEMPOTENT_GUARD
+
 /* We do not support both EBCDIC and Unicode at the same time. The "configure"
 script prevents both being selected, but not everybody uses "configure". EBCDIC
 is only supported for the 8-bit library, but the check for this has to be later
@@ -142,20 +145,6 @@
 #define PCRE2_SPTR CUSTOM_SUBJECT_PTR
 #endif
 
-/* When compiling with the MSVC compiler, it is sometimes necessary to include
-a "calling convention" before exported function names. (This is secondhand
-information; I know nothing about MSVC myself). For example, something like
-
-  void __cdecl function(....)
-
-might be needed. In order so make this easy, all the exported functions have
-PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not
-set, we ensure here that it has no effect. */
-
-#ifndef PCRE2_CALL_CONVENTION
-#define PCRE2_CALL_CONVENTION
-#endif
-
 /* When checking for integer overflow in pcre2_compile(), we need to handle
 large integers. If a 64-bit integer type is available, we can use that.
 Otherwise we have to cast to double, which of course requires floating point
@@ -254,6 +243,16 @@
 
 #define COMPILE_ERROR_BASE 100
 
+/* The initial frames vector for remembering backtracking points in
+pcre2_match() is allocated on the system stack, of this size (bytes). The size
+must be a multiple of sizeof(PCRE2_SPTR) in all environments, so making it a
+multiple of 8 is best. Typical frame sizes are a few hundred bytes (it depends
+on the number of capturing parentheses) so 20K handles quite a few frames. A
+larger vector on the heap is obtained for patterns that need more frames. The
+maximum size of this can be limited. */
+
+#define START_FRAMES_SIZE 20480
+
 /* Define the default BSR convention. */
 
 #ifdef BSR_ANYCRLF
@@ -561,9 +560,14 @@
 #define MAGIC_NUMBER  0x50435245UL   /* 'PCRE' */
 
 /* The maximum remaining length of subject we are prepared to search for a
-req_unit match. */
+req_unit match. In 8-bit mode, memchr() is used and is much faster than the
+search loop that has to be used in 16-bit and 32-bit modes. */
 
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define REQ_CU_MAX 2000
+#else
 #define REQ_CU_MAX 1000
+#endif
 
 /* 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
@@ -682,7 +686,7 @@
 
 /* The remaining definitions work in both environments. */
 
-#define CHAR_NULL                   '\0'
+#define CHAR_NUL                    '\0'
 #define CHAR_HT                     '\t'
 #define CHAR_VT                     '\v'
 #define CHAR_FF                     '\f'
@@ -923,6 +927,7 @@
 #define STRING_CRLF_RIGHTPAR              "CRLF)"
 #define STRING_ANY_RIGHTPAR               "ANY)"
 #define STRING_ANYCRLF_RIGHTPAR           "ANYCRLF)"
+#define STRING_NUL_RIGHTPAR               "NUL)"
 #define STRING_BSR_ANYCRLF_RIGHTPAR       "BSR_ANYCRLF)"
 #define STRING_BSR_UNICODE_RIGHTPAR       "BSR_UNICODE)"
 #define STRING_UTF8_RIGHTPAR              "UTF8)"
@@ -936,7 +941,9 @@
 #define STRING_NO_START_OPT_RIGHTPAR      "NO_START_OPT)"
 #define STRING_NOTEMPTY_RIGHTPAR          "NOTEMPTY)"
 #define STRING_NOTEMPTY_ATSTART_RIGHTPAR  "NOTEMPTY_ATSTART)"
+#define STRING_LIMIT_HEAP_EQ              "LIMIT_HEAP="
 #define STRING_LIMIT_MATCH_EQ             "LIMIT_MATCH="
+#define STRING_LIMIT_DEPTH_EQ             "LIMIT_DEPTH="
 #define STRING_LIMIT_RECURSION_EQ         "LIMIT_RECURSION="
 #define STRING_MARK                       "MARK"
 
@@ -958,7 +965,7 @@
 #define CHAR_ESC                    '\033'
 #define CHAR_DEL                    '\177'
 
-#define CHAR_NULL                   '\0'
+#define CHAR_NUL                    '\0'
 #define CHAR_SPACE                  '\040'
 #define CHAR_EXCLAMATION_MARK       '\041'
 #define CHAR_QUOTATION_MARK         '\042'
@@ -1196,6 +1203,7 @@
 #define STRING_CRLF_RIGHTPAR              STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
 #define STRING_ANY_RIGHTPAR               STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
 #define STRING_ANYCRLF_RIGHTPAR           STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_NUL_RIGHTPAR               STR_N STR_U STR_L STR_RIGHT_PARENTHESIS
 #define STRING_BSR_ANYCRLF_RIGHTPAR       STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
 #define STRING_BSR_UNICODE_RIGHTPAR       STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
 #define STRING_UTF8_RIGHTPAR              STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
@@ -1209,7 +1217,9 @@
 #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_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
 #define STRING_LIMIT_RECURSION_EQ         STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN
 #define STRING_MARK                       STR_M STR_A STR_R STR_K
 
@@ -1298,23 +1308,16 @@
 compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves
 like \N.
 
-The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc.
-when PCRE2_UCP is set and replacement of \d etc by \p sequences is required.
-They must be contiguous, and remain in order so that the replacements can be
-looked up from a table.
-
 Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in
-check_escape(). There are two tests in the code for an escape
-greater than ESC_b and less than ESC_Z to detect the types that may be
-repeated. These are the types that consume characters. If any new escapes are
-put in between that don't consume a character, that code will have to change.
-*/
+check_escape(). There are tests in the code for an escape greater than ESC_b
+and less than ESC_Z to detect the types that may be repeated. These are the
+types that consume characters. If any new escapes are put in between that don't
+consume a character, that code will have to change. */
 
 enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
        ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
        ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
-       ESC_E, ESC_Q, ESC_g, ESC_k,
-       ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu };
+       ESC_E, ESC_Q, ESC_g, ESC_k };
 
 
 /********************** Opcode definitions ******************/
@@ -1380,7 +1383,8 @@
   OP_CIRC,           /* 27 Start of line - not multiline */
   OP_CIRCM,          /* 28 Start of line - multiline */
 
-  /* Single characters; caseful must precede the caseless ones */
+  /* Single characters; caseful must precede the caseless ones, and these
+  must remain in this order, and adjacent. */
 
   OP_CHAR,           /* 29 Match one character, casefully */
   OP_CHARI,          /* 30 Match one character, caselessly */
@@ -1530,68 +1534,67 @@
   OP_ASSERTBACK,     /* 128 Positive lookbehind */
   OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */
 
-  /* ONCE, ONCE_NC, 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. */
+  /* ONCE, 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,           /* 130 Atomic group, contains captures */
-  OP_ONCE_NC,        /* 131 Atomic group containing no captures */
-  OP_BRA,            /* 132 Start of non-capturing bracket */
-  OP_BRAPOS,         /* 133 Ditto, with unlimited, possessive repeat */
-  OP_CBRA,           /* 134 Start of capturing bracket */
-  OP_CBRAPOS,        /* 135 Ditto, with unlimited, possessive repeat */
-  OP_COND,           /* 136 Conditional group */
+  OP_BRA,            /* 131 Start of non-capturing bracket */
+  OP_BRAPOS,         /* 132 Ditto, with unlimited, possessive repeat */
+  OP_CBRA,           /* 133 Start of capturing bracket */
+  OP_CBRAPOS,        /* 134 Ditto, with unlimited, possessive repeat */
+  OP_COND,           /* 135 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,           /* 137 Start of non-capturing bracket, check empty  */
-  OP_SBRAPOS,        /* 138 Ditto, with unlimited, possessive repeat */
-  OP_SCBRA,          /* 139 Start of capturing bracket, check empty */
-  OP_SCBRAPOS,       /* 140 Ditto, with unlimited, possessive repeat */
-  OP_SCOND,          /* 141 Conditional group, check empty */
+  OP_SBRA,           /* 136 Start of non-capturing bracket, check empty  */
+  OP_SBRAPOS,        /* 137 Ditto, with unlimited, possessive repeat */
+  OP_SCBRA,          /* 138 Start of capturing bracket, check empty */
+  OP_SCBRAPOS,       /* 139 Ditto, with unlimited, possessive repeat */
+  OP_SCOND,          /* 140 Conditional group, check empty */
 
   /* The next two pairs must (respectively) be kept together. */
 
-  OP_CREF,           /* 142 Used to hold a capture number as condition */
-  OP_DNCREF,         /* 143 Used to point to duplicate names as a condition */
-  OP_RREF,           /* 144 Used to hold a recursion number as condition */
-  OP_DNRREF,         /* 145 Used to point to duplicate names as a condition */
-  OP_FALSE,          /* 146 Always false (used by DEFINE and VERSION) */
-  OP_TRUE,           /* 147 Always true (used by VERSION) */
+  OP_CREF,           /* 141 Used to hold a capture number as condition */
+  OP_DNCREF,         /* 142 Used to point to duplicate names as a condition */
+  OP_RREF,           /* 143 Used to hold a recursion number as condition */
+  OP_DNRREF,         /* 144 Used to point to duplicate names as a condition */
+  OP_FALSE,          /* 145 Always false (used by DEFINE and VERSION) */
+  OP_TRUE,           /* 146 Always true (used by VERSION) */
 
-  OP_BRAZERO,        /* 148 These two must remain together and in this */
-  OP_BRAMINZERO,     /* 149 order. */
-  OP_BRAPOSZERO,     /* 150 */
+  OP_BRAZERO,        /* 147 These two must remain together and in this */
+  OP_BRAMINZERO,     /* 148 order. */
+  OP_BRAPOSZERO,     /* 149 */
 
   /* These are backtracking control verbs */
 
-  OP_MARK,           /* 151 always has an argument */
-  OP_PRUNE,          /* 152 */
-  OP_PRUNE_ARG,      /* 153 same, but with argument */
-  OP_SKIP,           /* 154 */
-  OP_SKIP_ARG,       /* 155 same, but with argument */
-  OP_THEN,           /* 156 */
-  OP_THEN_ARG,       /* 157 same, but with argument */
-  OP_COMMIT,         /* 158 */
+  OP_MARK,           /* 150 always has an argument */
+  OP_PRUNE,          /* 151 */
+  OP_PRUNE_ARG,      /* 152 same, but with argument */
+  OP_SKIP,           /* 153 */
+  OP_SKIP_ARG,       /* 154 same, but with argument */
+  OP_THEN,           /* 155 */
+  OP_THEN_ARG,       /* 156 same, but with argument */
+  OP_COMMIT,         /* 157 */
 
   /* These are forced failure and success verbs */
 
-  OP_FAIL,           /* 159 */
-  OP_ACCEPT,         /* 160 */
-  OP_ASSERT_ACCEPT,  /* 161 Used inside assertions */
-  OP_CLOSE,          /* 162 Used before OP_ACCEPT to close open captures */
+  OP_FAIL,           /* 158 */
+  OP_ACCEPT,         /* 159 */
+  OP_ASSERT_ACCEPT,  /* 160 Used inside assertions */
+  OP_CLOSE,          /* 161 Used before OP_ACCEPT to close open captures */
 
   /* This is used to skip a subpattern with a {0} quantifier */
 
-  OP_SKIPZERO,       /* 163 */
+  OP_SKIPZERO,       /* 162 */
 
   /* 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,         /* 164 */
+  OP_DEFINE,         /* 163 */
 
   /* 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
@@ -1638,7 +1641,7 @@
   "Recurse", "Callout", "CalloutStr",                             \
   "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos",                  \
   "Reverse", "Assert", "Assert not", "AssertB", "AssertB not",    \
-  "Once", "Once_NC",                                              \
+  "Once",                                                         \
   "Bra", "BraPos", "CBra", "CBraPos",                             \
   "Cond",                                                         \
   "SBra", "SBraPos", "SCBra", "SCBraPos",                         \
@@ -1722,7 +1725,6 @@
   1+LINK_SIZE,                   /* Assert behind                          */ \
   1+LINK_SIZE,                   /* Assert behind not                      */ \
   1+LINK_SIZE,                   /* ONCE                                   */ \
-  1+LINK_SIZE,                   /* ONCE_NC                                */ \
   1+LINK_SIZE,                   /* BRA                                    */ \
   1+LINK_SIZE,                   /* BRAPOS                                 */ \
   1+LINK_SIZE+IMM2_SIZE,         /* CBRA                                   */ \
@@ -1768,6 +1770,7 @@
   struct open_capitem *next;    /* Chain link */
   uint16_t number;              /* Capture number */
   uint16_t flag;                /* Set TRUE if recursive back ref */
+  uint16_t assert_depth;        /* Assertion depth when opened */
 } open_capitem;
 
 /* Layout of the UCP type table that translates property names into types and
@@ -1794,10 +1797,17 @@
 /* UCD access macros */
 
 #define UCD_BLOCK_SIZE 128
-#define GET_UCD(ch) (PRIV(ucd_records) + \
+#define REAL_GET_UCD(ch) (PRIV(ucd_records) + \
         PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \
         UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE])
 
+#if PCRE2_CODE_UNIT_WIDTH == 32
+#define GET_UCD(ch) ((ch > MAX_UTF_CODE_POINT)? \
+  PRIV(dummy_ucd_record) : REAL_GET_UCD(ch))
+#else
+#define GET_UCD(ch) REAL_GET_UCD(ch)
+#endif
+
 #define UCD_CHARTYPE(ch)    GET_UCD(ch)->chartype
 #define UCD_SCRIPT(ch)      GET_UCD(ch)->script
 #define UCD_CATEGORY(ch)    PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
@@ -1852,8 +1862,12 @@
 #define _pcre2_callout_end_delims      PCRE2_SUFFIX(_pcre2_callout_end_delims_)
 #define _pcre2_callout_start_delims    PCRE2_SUFFIX(_pcre2_callout_start_delims_)
 #define _pcre2_default_compile_context PCRE2_SUFFIX(_pcre2_default_compile_context_)
+#define _pcre2_default_convert_context PCRE2_SUFFIX(_pcre2_default_convert_context_)
 #define _pcre2_default_match_context   PCRE2_SUFFIX(_pcre2_default_match_context_)
 #define _pcre2_default_tables          PCRE2_SUFFIX(_pcre2_default_tables_)
+#if PCRE2_CODE_UNIT_WIDTH == 32
+#define _pcre2_dummy_ucd_record        PCRE2_SUFFIX(_pcre2_dummy_ucd_record_)
+#endif
 #define _pcre2_hspace_list             PCRE2_SUFFIX(_pcre2_hspace_list_)
 #define _pcre2_vspace_list             PCRE2_SUFFIX(_pcre2_vspace_list_)
 #define _pcre2_ucd_caseless_sets       PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_)
@@ -1872,12 +1886,16 @@
 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 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_caseless_sets)[];
 extern const ucd_record                PRIV(ucd_records)[];
+#if PCRE2_CODE_UNIT_WIDTH == 32
+extern const ucd_record                PRIV(dummy_ucd_record)[];
+#endif
 extern const uint8_t                   PRIV(ucd_stage1)[];
 extern const uint16_t                  PRIV(ucd_stage2)[];
 extern const uint32_t                  PRIV(ucp_gbtable)[];
@@ -1912,6 +1930,7 @@
 
 #define _pcre2_auto_possessify       PCRE2_SUFFIX(_pcre2_auto_possessify_)
 #define _pcre2_check_escape          PCRE2_SUFFIX(_pcre2_check_escape_)
+#define _pcre2_extuni                PCRE2_SUFFIX(_pcre2_extuni_)
 #define _pcre2_find_bracket          PCRE2_SUFFIX(_pcre2_find_bracket_)
 #define _pcre2_is_newline            PCRE2_SUFFIX(_pcre2_is_newline_)
 #define _pcre2_jit_free_rodata       PCRE2_SUFFIX(_pcre2_jit_free_rodata_)
@@ -1935,6 +1954,8 @@
                       const compile_block *);
 extern int          _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,
                       int *, 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);
 extern BOOL         _pcre2_is_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
                       uint32_t *, BOOL);
@@ -1956,5 +1977,6 @@
                       uint32_t *, BOOL);
 extern BOOL         _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL);
 #endif  /* PCRE2_CODE_UNIT_WIDTH */
+#endif  /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */
 
 /* End of pcre2_internal.h */
diff --git a/dist2/src/pcre2_intmodedep.h b/dist2/src/pcre2_intmodedep.h
index 596d62c..c4c4c3a 100644
--- a/dist2/src/pcre2_intmodedep.h
+++ b/dist2/src/pcre2_intmodedep.h
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2018 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,7 @@
 #undef ACROSSCHAR
 #undef BACKCHAR
 #undef BYTES2CU
+#undef CHMAX_255
 #undef CU2BYTES
 #undef FORWARDCHAR
 #undef FORWARDCHARTEST
@@ -140,7 +141,7 @@
 #undef LINK_SIZE
 #define LINK_SIZE 1
 #define PUT(a,n,d)   \
-  (a[n] = (d))
+  (a[n] = (PCRE2_UCHAR)(d))
 #define GET(a,n) \
   (a[n])
 #define MAX_PATTERN_SIZE (1 << 16)
@@ -200,21 +201,26 @@
 #endif
 
 /* Other macros that are different for 8-bit mode. The MAX_255 macro checks
-whether its argument is less than 256. The maximum length of a MARK name must
-fit in one code unit; currently it is set to 255 or 65535. The TABLE_GET macro
-is used to access elements of tables containing exactly 256 items. When code
-points can be greater than 255, a check is needed before accessing these
-tables. */
+whether its argument, which is assumed to be one code unit, is less than 256.
+The CHMAX_255 macro does not assume one code unit. The maximum length of a MARK
+name must fit in one code unit; currently it is set to 255 or 65535. The
+TABLE_GET macro is used to access elements of tables containing exactly 256
+items. When code points can be greater than 255, a check is needed before
+accessing these tables. */
 
 #if PCRE2_CODE_UNIT_WIDTH == 8
 #define MAX_255(c) TRUE
 #define MAX_MARK ((1u << 8) - 1)
 #ifdef SUPPORT_UNICODE
 #define SUPPORT_WIDE_CHARS
+#define CHMAX_255(c) ((c) <= 255u)
+#else
+#define CHMAX_255(c) TRUE
 #endif  /* SUPPORT_UNICODE */
 #define TABLE_GET(c, table, default) ((table)[c])
 
 #else  /* Code units are 16 or 32 bits */
+#define CHMAX_255(c) ((c) <= 255u)
 #define MAX_255(c) ((c) <= 255u)
 #define MAX_MARK ((1u << 16) - 1)
 #define SUPPORT_WIDE_CHARS
@@ -345,7 +351,7 @@
 
 /* Same as above, but it allows a fully customizable form. */
 #define ACROSSCHAR(condition, eptr, action) \
-  while((condition) && ((eptr) & 0xc0u) == 0x80u) action
+  while((condition) && ((*eptr) & 0xc0u) == 0x80u) action
 
 /* Deposit a character into memory, returning the number of code units. */
 
@@ -451,7 +457,7 @@
 
 /* Same as above, but it allows a fully customizable form. */
 #define ACROSSCHAR(condition, eptr, action) \
-  if ((condition) && ((eptr) & 0xfc00u) == 0xdc00u) action
+  if ((condition) && ((*eptr) & 0xfc00u) == 0xdc00u) action
 
 /* Deposit a character into memory, returning the number of code units. */
 
@@ -566,15 +572,13 @@
   uint16_t bsr_convention;
   uint16_t newline_convention;
   uint32_t parens_nest_limit;
+  uint32_t extra_options;
 } pcre2_real_compile_context;
 
 /* The real match context structure. */
 
 typedef struct pcre2_real_match_context {
   pcre2_memctl memctl;
-#ifdef HEAP_MATCH_RECURSE
-  pcre2_memctl stack_memctl;
-#endif
 #ifdef SUPPORT_JIT
   pcre2_jit_callback jit_callback;
   void *jit_callback_data;
@@ -582,10 +586,19 @@
   int    (*callout)(pcre2_callout_block *, void *);
   void    *callout_data;
   PCRE2_SIZE offset_limit;
+  uint32_t heap_limit;
   uint32_t match_limit;
-  uint32_t recursion_limit;
+  uint32_t depth_limit;
 } pcre2_real_match_context;
 
+/* The real convert context structure. */
+
+typedef struct pcre2_real_convert_context {
+  pcre2_memctl memctl;
+  uint32_t glob_separator;
+  uint32_t glob_escape;
+} pcre2_real_convert_context;
+
 /* The real compiled code structure. The type for the blocksize field is
 defined specially because it is required in pcre2_serialize_decode() when
 copying the size from possibly unaligned memory into a variable of the same
@@ -610,9 +623,11 @@
   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 */
+  uint32_t extra_options;         /* Taken from compile_context */
   uint32_t flags;                 /* Various state flags */
+  uint32_t limit_heap;            /* Limit set in the pattern */
   uint32_t limit_match;           /* Limit set in the pattern */
-  uint32_t limit_recursion;       /* Limit set in the pattern */
+  uint32_t limit_depth;           /* Limit set in the pattern */
   uint32_t first_codeunit;        /* Starting code unit */
   uint32_t last_codeunit;         /* This codeunit must be seen */
   uint16_t bsr_convention;        /* What \R matches */
@@ -625,7 +640,13 @@
   uint16_t name_count;            /* Number of name entries in the table */
 } pcre2_real_code;
 
-/* The real match data structure. */
+/* The real match data structure. Define ovector as large as it can ever
+actually be so that array bound checkers don't grumble. Memory for this
+structure is obtained by calling pcre2_match_data_create(), which sets the size
+as the offset of ovector plus a pair of elements for each capturable string, so
+the size varies from call to call. As the maximum number of capturing
+subpatterns is 65535 we must allow for 65536 strings to include the overall
+match. (See also the heapframe structure below.) */
 
 typedef struct pcre2_real_match_data {
   pcre2_memctl     memctl;
@@ -638,7 +659,7 @@
   uint16_t         matchedby;     /* Type of match (normal, JIT, DFA) */
   uint16_t         oveccount;     /* Number of pairs */
   int              rc;            /* The return code from the match */
-  PCRE2_SIZE       ovector[1];    /* The first field */
+  PCRE2_SIZE       ovector[131072]; /* Must be last in the structure */
 } pcre2_real_match_data;
 
 
@@ -648,18 +669,24 @@
 
 #ifndef PCRE2_PCRE2TEST
 
-/* Structure for checking for mutual recursion when scanning compiled code. */
+/* Structures for checking for mutual recursion when scanning compiled or
+parsed code. */
 
 typedef struct recurse_check {
   struct recurse_check *prev;
   PCRE2_SPTR group;
 } recurse_check;
 
+typedef struct parsed_recurse_check {
+  struct parsed_recurse_check *prev;
+  uint32_t *groupptr;
+} parsed_recurse_check;
+
 /* Structure for building a cache when filling in recursion offsets. */
 
 typedef struct recurse_cache {
   PCRE2_SPTR group;
-  int recno;
+  int groupnumber;
 } recurse_cache;
 
 /* Structure for maintaining a chain of pointers to the currently incomplete
@@ -693,34 +720,37 @@
   PCRE2_SPTR 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_SPTR nestptr[2];           /* Pointer(s) saved for string substitution */
   PCRE2_UCHAR *name_table;         /* The name/number table */
-  size_t workspace_size;           /* Size of workspace */
+  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 */
   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 */
+  uint16_t assert_depth;           /* Depth of nested assertions */
   open_capitem *open_caps;         /* Chain of open capture items */
   named_group *named_groups;       /* Points to vector in pre-compile */
   uint32_t named_group_list_size;  /* Number of entries in the list */
   uint32_t external_options;       /* External (initial) options */
   uint32_t external_flags;         /* External flag bits to be set */
-  uint32_t bracount;               /* Count of capturing parens as we compile */
-  uint32_t final_bracount;         /* Saved value after first pass */
+  uint32_t bracount;               /* Count of capturing parentheses */
+  uint32_t lastcapture;            /* Last capture encountered */
+  uint32_t *parsed_pattern;        /* Parsed pattern buffer */
+  uint32_t *parsed_pattern_end;    /* Parsed pattern should not get here */
   uint32_t *groupinfo;             /* Group info vector */
   uint32_t top_backref;            /* Maximum back reference */
   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 */
   int  max_lookbehind;             /* Maximum lookbehind (characters) */
-  int  parens_depth;               /* Depth of nested parentheses */
-  int  assert_depth;               /* Depth of nested assertions */
   int  req_varyopt;                /* "After variable item" flag for reqbyte */
   BOOL had_accept;                 /* (*ACCEPT) encountered */
   BOOL had_pruneorskip;            /* (*PRUNE) or (*SKIP) encountered */
   BOOL had_recurse;                /* Had a recursion or subroutine call */
-  BOOL check_lookbehind;           /* Lookbehinds need later checking */
   BOOL dupnames;                   /* Duplicate names exist */
-  BOOL iscondassert;               /* Next assert is a condition */
 } compile_block;
 
 /* Structure for keeping the properties of the in-memory stack used
@@ -731,27 +761,8 @@
   void* stack;
 } pcre2_real_jit_stack;
 
-/* Structure for keeping a chain of heap blocks used for saving ovectors
-during pattern recursion when the ovector is larger than can be saved on
-the system stack. */
-
-typedef struct ovecsave_frame {
-  struct ovecsave_frame *next;     /* Next frame on free chain */
-  PCRE2_SIZE saved_ovec[1];        /* First vector element */
-} ovecsave_frame;
-
 /* Structure for items in a linked list that represents an explicit recursive
-call within the pattern; used by pcre_match(). */
-
-typedef struct recursion_info {
-  struct recursion_info *prevrec;  /* Previous recursion record (or NULL) */
-  unsigned int group_num;          /* Number of group that was called */
-  PCRE2_SIZE *ovec_save;           /* Pointer to saved ovector frame */
-  uint32_t saved_capture_last;     /* Last capture number */
-  PCRE2_SPTR subject_position;     /* Position at start of recursion */
-} recursion_info;
-
-/* A similar structure for pcre_dfa_match(). */
+call within the pattern when running pcre_dfa_match(). */
 
 typedef struct dfa_recursion_info {
   struct dfa_recursion_info *prevrec;
@@ -759,35 +770,75 @@
   uint32_t group_num;
 } dfa_recursion_info;
 
-/* Structure for building a chain of data for holding the values of the subject
-pointer at the start of each subpattern, so as to detect when an empty string
-has been matched by a subpattern - to break infinite loops; used by
-pcre2_match(). */
+/* Structure for "stack" frames that are used for remembering backtracking
+positions during matching. As these are used in a vector, with the ovector item
+being extended, the size of the structure must be a multiple of PCRE2_SIZE. The
+only way to check this at compile time is to force an error by generating an
+array with a negative size. By putting this in a typedef (which is never used),
+we don't generate any code when all is well. */
 
-typedef struct eptrblock {
-  struct eptrblock *epb_prev;
-  PCRE2_SPTR epb_saved_eptr;
-} eptrblock;
+typedef struct heapframe {
+
+  /* The first set of fields are variables that have to be preserved over calls
+  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_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 */
+  uint32_t rdepth;           /* "Recursion" depth */
+  uint32_t group_frame_type; /* Type information for group frames */
+  uint32_t temp_32[4];       /* Used for short-term 32-bit or BOOL values */
+  uint8_t return_id;         /* Where to go on in internal "return" */
+  uint8_t op;                /* Processing opcode */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+  PCRE2_UCHAR occu[6];       /* Used for other case code units */
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+  PCRE2_UCHAR occu[2];       /* Used for other case code units */
+#else
+  PCRE2_UCHAR occu[1];       /* Used for other case code units */
+#endif
+
+  /* The rest have to be copied from the previous frame whenever a new frame
+  becomes current. The final field is specified as a large vector so that
+  runtime array bound checks don't catch references to it. However, for any
+  specific call to pcre2_match() the memory allocated for each frame structure
+  allows for exactly the right size ovector for the number of capturing
+  parentheses. (See also the comment for pcre2_real_match_data above.) */
+
+  PCRE2_SPTR eptr;           /* MUST BE FIRST */
+  PCRE2_SPTR start_match;    /* Can be adjusted by \K */
+  PCRE2_SPTR mark;           /* Most recent mark on the success path */
+  uint32_t current_recurse;  /* Current (deepest) recursion number */
+  uint32_t capture_last;     /* Most recent capture */
+  PCRE2_SIZE last_group_offset;  /* Saved offset to most recent group frame */
+  PCRE2_SIZE offset_top;     /* Offset after highest capture */
+  PCRE2_SIZE ovector[131072]; /* Must be last in the structure */
+} heapframe;
+
+typedef char check_heapframe_size[
+  ((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0)? (+1):(-1)];
 
 /* Structure for passing "static" information around between the functions
 doing traditional NFA matching (pcre2_match() and friends). */
 
 typedef struct match_block {
   pcre2_memctl memctl;            /* For general use */
-#ifdef HEAP_MATCH_RECURSE
-  pcre2_memctl stack_memctl;      /* For "stack" frames */
-#endif
-  uint32_t match_call_count;      /* As it says */
+  PCRE2_SIZE frame_vector_size;   /* Size of a backtracking frame */
+  heapframe *match_frames;        /* Points to vector of frames */
+  heapframe *match_frames_top;    /* Points after the end of the vector */
+  heapframe *stack_frames;        /* The original vector on the stack */
+  PCRE2_SIZE heap_limit;          /* As it says */
   uint32_t match_limit;           /* As it says */
-  uint32_t match_limit_recursion; /* As it says */
+  uint32_t match_limit_depth;     /* As it says */
+  uint32_t match_call_count;      /* Number of times a new frame is created */
   BOOL hitend;                    /* Hit the end of the subject at some point */
   BOOL hasthen;                   /* Pattern contains (*THEN) */
   const uint8_t *lcc;             /* Points to lower casing table */
   const uint8_t *fcc;             /* Points to case-flipping table */
   const uint8_t *ctypes;          /* Points to table of type maps */
-  PCRE2_SIZE *ovector;            /* Pointer to the offset vector */
-  PCRE2_SIZE offset_end;          /* One past the end */
-  PCRE2_SIZE offset_max;          /* The maximum usable for return data */
   PCRE2_SIZE start_offset;        /* The start offset value */
   PCRE2_SIZE end_offset_top;      /* Highwater mark at end of match */
   uint16_t partial;               /* PARTIAL options */
@@ -798,30 +849,24 @@
   PCRE2_SPTR start_code;          /* For use when recursing */
   PCRE2_SPTR start_subject;       /* Start of the subject string */
   PCRE2_SPTR end_subject;         /* End of the subject string */
-  PCRE2_SPTR start_match_ptr;     /* Start of matched string */
   PCRE2_SPTR end_match_ptr;       /* Subject position at end match */
   PCRE2_SPTR start_used_ptr;      /* Earliest consulted character */
   PCRE2_SPTR last_used_ptr;       /* Latest consulted character */
   PCRE2_SPTR mark;                /* Mark pointer to pass back on success */
   PCRE2_SPTR nomatch_mark;        /* Mark pointer to pass back on failure */
-  PCRE2_SPTR once_target;         /* Where to back up to for atomic groups */
+  PCRE2_SPTR verb_ecode_ptr;      /* For passing back info */
+  PCRE2_SPTR verb_skip_ptr;       /* For passing back a (*SKIP) name */
+  uint32_t verb_current_recurse;  /* Current recurse when (*VERB) happens */
   uint32_t moptions;              /* Match options */
   uint32_t poptions;              /* Pattern options */
-  uint32_t capture_last;          /* Most recent capture number + overflow flag */
   uint32_t skip_arg_count;        /* For counting SKIP_ARGs */
   uint32_t ignore_skip_arg;       /* For re-run when SKIP arg name not found */
-  uint32_t match_function_type;   /* Set for certain special calls of match() */
   uint32_t nltype;                /* Newline type */
   uint32_t nllen;                 /* Newline string length */
   PCRE2_UCHAR nl[4];              /* Newline string when fixed */
-  eptrblock *eptrchain;           /* Chain of eptrblocks for tail recursions */
-  recursion_info *recursive;      /* Linked list of recursion data */
-  ovecsave_frame *ovecsave_chain; /* Linked list of free ovecsave blocks */
+  pcre2_callout_block *cb;        /* Points to a callout block */
   void  *callout_data;            /* To pass back to callouts */
   int (*callout)(pcre2_callout_block *,void *);  /* Callout function or NULL */
-#ifdef HEAP_MATCH_RECURSE
-  void  *match_frames_base;       /* For remembering malloc'd frames */
-#endif
 } match_block;
 
 /* A similar structure is used for the same purpose by the DFA matching
@@ -836,12 +881,16 @@
   PCRE2_SPTR last_used_ptr;       /* Latest consulted character */
   const uint8_t *tables;          /* Character tables */
   PCRE2_SIZE start_offset;        /* The start offset value */
+  uint32_t match_limit;           /* As it says */
+  uint32_t match_limit_depth;     /* As it says */
+  uint32_t match_call_count;      /* Number of calls of internal function */
   uint32_t moptions;              /* Match options */
   uint32_t poptions;              /* Pattern options */
   uint32_t nltype;                /* Newline type */
   uint32_t nllen;                 /* Newline string length */
   PCRE2_UCHAR nl[4];              /* Newline string when fixed */
   uint16_t bsr_convention;        /* \R interpretation */
+  pcre2_callout_block *cb;        /* Points to a callout block */
   void *callout_data;             /* To pass back to callouts */
   int (*callout)(pcre2_callout_block *,void *);  /* Callout function or NULL */
   dfa_recursion_info *recursive;  /* Linked list of recursion data */
diff --git a/dist2/src/pcre2_jit_compile.c b/dist2/src/pcre2_jit_compile.c
index 8dea90a..80ed1c4 100644
--- a/dist2/src/pcre2_jit_compile.c
+++ b/dist2/src/pcre2_jit_compile.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -228,7 +228,7 @@
   type_then_trap = 1
 };
 
-typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
+typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);
 
 /* The following structure is the key data type for the recursive
 code generator. It is allocated by compile_matchingpath, and contains
@@ -313,16 +313,25 @@
 
 typedef struct recurse_entry {
   struct recurse_entry *next;
-  /* Contains the function entry. */
-  struct sljit_label *entry;
-  /* Collects the calls until the function is not created. */
-  jump_list *calls;
+  /* Contains the function entry label. */
+  struct sljit_label *entry_label;
+  /* Contains the function entry label. */
+  struct sljit_label *backtrack_label;
+  /* Collects the entry calls until the function is not created. */
+  jump_list *entry_calls;
+  /* Collects the backtrack calls until the function is not created. */
+  jump_list *backtrack_calls;
   /* Points to the starting opcode. */
   sljit_sw start;
 } recurse_entry;
 
 typedef struct recurse_backtrack {
   backtrack_common common;
+  /* Return to the matching path. */
+  struct sljit_label *matchingpath;
+  /* Recursive pattern. */
+  recurse_entry *entry;
+  /* Pattern is inlined. */
   BOOL inlined_pattern;
 } recurse_backtrack;
 
@@ -341,11 +350,26 @@
   int framesize;
 } then_trap_backtrack;
 
-#define MAX_RANGE_SIZE 4
+#define MAX_N_CHARS 12
+#define MAX_DIFF_CHARS 5
+
+typedef struct fast_forward_char_data {
+  /* Number of characters in the chars array, 255 for any character. */
+  sljit_u8 count;
+  /* Number of last UTF-8 characters in the chars array. */
+  sljit_u8 last_count;
+  /* Available characters in the current position. */
+  PCRE2_UCHAR chars[MAX_DIFF_CHARS];
+} fast_forward_char_data;
+
+#define MAX_CLASS_RANGE_SIZE 4
+#define MAX_CLASS_CHARS_SIZE 3
 
 typedef struct compiler_common {
   /* The sljit ceneric compiler. */
   struct sljit_compiler *compiler;
+  /* Compiled regular expression. */
+  pcre2_real_code *re;
   /* First byte code. */
   PCRE2_SPTR start;
   /* Maps private data offset to each opcode. */
@@ -402,10 +426,10 @@
   BOOL has_then;
   /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */
   BOOL has_skip_in_assert_back;
-  /* Currently in recurse or negative assert. */
-  BOOL local_exit;
-  /* Currently in a positive assert. */
-  BOOL positive_assert;
+  /* Quit is redirected by recurse, negative assertion, or positive assertion in conditional block. */
+  BOOL local_quit_available;
+  /* Currently in a positive assertion. */
+  BOOL in_positive_assertion;
   /* Newline control. */
   int nltype;
   sljit_u32 nlmax;
@@ -426,7 +450,7 @@
   /* Labels and jump lists. */
   struct sljit_label *partialmatchlabel;
   struct sljit_label *quit_label;
-  struct sljit_label *forced_quit_label;
+  struct sljit_label *abort_label;
   struct sljit_label *accept_label;
   struct sljit_label *ff_newline_shortcut;
   stub_list *stubs;
@@ -435,8 +459,9 @@
   recurse_entry *currententry;
   jump_list *partialmatch;
   jump_list *quit;
-  jump_list *positive_assert_quit;
-  jump_list *forced_quit;
+  jump_list *positive_assertion_quit;
+  jump_list *abort;
+  jump_list *failed_match;
   jump_list *accept;
   jump_list *calllimit;
   jump_list *stackalloc;
@@ -500,14 +525,29 @@
 #undef CMP
 
 /* Used for accessing the elements of the stack. */
-#define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
+#define STACK(i)      ((i) * (int)sizeof(sljit_sw))
+
+#ifdef SLJIT_PREF_SHIFT_REG
+#if SLJIT_PREF_SHIFT_REG == SLJIT_R2
+/* Nothing. */
+#elif SLJIT_PREF_SHIFT_REG == SLJIT_R3
+#define SHIFT_REG_IS_R3
+#else
+#error "Unsupported shift register"
+#endif
+#endif
 
 #define TMP1          SLJIT_R0
+#ifdef SHIFT_REG_IS_R3
+#define TMP2          SLJIT_R3
+#define TMP3          SLJIT_R2
+#else
 #define TMP2          SLJIT_R2
 #define TMP3          SLJIT_R3
-#define STR_PTR       SLJIT_S0
-#define STR_END       SLJIT_S1
-#define STACK_TOP     SLJIT_R1
+#endif
+#define STR_PTR       SLJIT_R1
+#define STR_END       SLJIT_S0
+#define STACK_TOP     SLJIT_S1
 #define STACK_LIMIT   SLJIT_S2
 #define COUNT_MATCH   SLJIT_S3
 #define ARGUMENTS     SLJIT_S4
@@ -533,16 +573,13 @@
 
 #if PCRE2_CODE_UNIT_WIDTH == 8
 #define MOV_UCHAR  SLJIT_MOV_U8
-#define MOVU_UCHAR SLJIT_MOVU_U8
 #define IN_UCHARS(x) (x)
 #elif PCRE2_CODE_UNIT_WIDTH == 16
 #define MOV_UCHAR  SLJIT_MOV_U16
-#define MOVU_UCHAR SLJIT_MOVU_U16
 #define UCHAR_SHIFT (1)
 #define IN_UCHARS(x) ((x) * 2)
 #elif PCRE2_CODE_UNIT_WIDTH == 32
 #define MOV_UCHAR  SLJIT_MOV_U32
-#define MOVU_UCHAR SLJIT_MOVU_U32
 #define UCHAR_SHIFT (2)
 #define IN_UCHARS(x) ((x) * 4)
 #else
@@ -570,13 +607,17 @@
   sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
 #define CMPTO(type, src1, src1w, src2, src2w, label) \
   sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
-#define OP_FLAGS(op, dst, dstw, src, srcw, type) \
-  sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
+#define OP_FLAGS(op, dst, dstw, type) \
+  sljit_emit_op_flags(compiler, (op), (dst), (dstw), (type))
+#define CMOV(type, dst_reg, src, srcw) \
+  sljit_emit_cmov(compiler, (type), (dst_reg), (src), (srcw))
 #define GET_LOCAL_BASE(dst, dstw, offset) \
   sljit_get_local_base(compiler, (dst), (dstw), (offset))
 
 #define READ_CHAR_MAX 0x7fffffff
 
+#define INVALID_UTF_CHAR 888
+
 static PCRE2_SPTR bracketend(PCRE2_SPTR cc)
 {
 SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
@@ -606,8 +647,8 @@
  set_private_data_ptrs
  get_framesize
  init_frame
- get_private_data_copy_length
- copy_private_data
+ get_recurse_data_length
+ copy_recurse_data
  compile_matchingpath
  compile_backtrackingpath
 */
@@ -675,7 +716,6 @@
   case OP_ASSERTBACK:
   case OP_ASSERTBACK_NOT:
   case OP_ONCE:
-  case OP_ONCE_NC:
   case OP_BRA:
   case OP_BRAPOS:
   case OP_CBRA:
@@ -806,7 +846,7 @@
 
   default:
   /* All opcodes are supported now! */
-  SLJIT_ASSERT_STOP();
+  SLJIT_UNREACHABLE();
   return NULL;
   }
 }
@@ -1304,7 +1344,7 @@
   if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
     break;
 
-  if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
+  if (repeat_check && (*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
     {
     if (detect_repeat(common, cc))
       {
@@ -1333,7 +1373,6 @@
     case OP_ASSERTBACK:
     case OP_ASSERTBACK_NOT:
     case OP_ONCE:
-    case OP_ONCE_NC:
     case OP_BRAPOS:
     case OP_SBRA:
     case OP_SBRAPOS:
@@ -1654,11 +1693,11 @@
 return stack_restore ? no_frame : no_stack;
 }
 
-static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop, BOOL recursive)
+static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop)
 {
 DEFINE_COMPILER;
-BOOL setsom_found = recursive;
-BOOL setmark_found = recursive;
+BOOL setsom_found = FALSE;
+BOOL setmark_found = FALSE;
 /* The last capture is a local variable even for recursions. */
 BOOL capture_last_found = FALSE;
 int offset;
@@ -1671,7 +1710,7 @@
 if (ccend == NULL)
   {
   ccend = bracketend(cc) - (1 + LINK_SIZE);
-  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
+  if (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)
     cc = next_opcode(common, cc);
   }
 
@@ -1685,9 +1724,9 @@
       {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       setsom_found = TRUE;
       }
     cc += 1;
@@ -1701,9 +1740,9 @@
       {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       setmark_found = TRUE;
       }
     cc += 1 + 2 + cc[1];
@@ -1714,27 +1753,27 @@
       {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       setsom_found = TRUE;
       }
     if (common->mark_ptr != 0 && !setmark_found)
       {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       setmark_found = TRUE;
       }
     if (common->capture_last_ptr != 0 && !capture_last_found)
       {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       capture_last_found = TRUE;
       }
     cc += 1 + LINK_SIZE;
@@ -1748,20 +1787,20 @@
       {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
-      stackpos += (int)sizeof(sljit_sw);
+      stackpos -= (int)sizeof(sljit_sw);
       capture_last_found = TRUE;
       }
     offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
-    stackpos += (int)sizeof(sljit_sw);
+    stackpos -= (int)sizeof(sljit_sw);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
-    stackpos += (int)sizeof(sljit_sw);
+    stackpos -= (int)sizeof(sljit_sw);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
-    stackpos += (int)sizeof(sljit_sw);
+    stackpos -= (int)sizeof(sljit_sw);
 
     cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;
@@ -1776,21 +1815,127 @@
 SLJIT_ASSERT(stackpos == STACK(stacktop));
 }
 
-static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL needs_control_head)
+#define RECURSE_TMP_REG_COUNT 3
+
+typedef struct delayed_mem_copy_status {
+  struct sljit_compiler *compiler;
+  int store_bases[RECURSE_TMP_REG_COUNT];
+  int store_offsets[RECURSE_TMP_REG_COUNT];
+  int tmp_regs[RECURSE_TMP_REG_COUNT];
+  int saved_tmp_regs[RECURSE_TMP_REG_COUNT];
+  int next_tmp_reg;
+} delayed_mem_copy_status;
+
+static void delayed_mem_copy_init(delayed_mem_copy_status *status, compiler_common *common)
 {
-int private_data_length = needs_control_head ? 3 : 2;
+int i;
+
+for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
+  {
+  SLJIT_ASSERT(status->tmp_regs[i] >= 0);
+  SLJIT_ASSERT(sljit_get_register_index(status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]);
+
+  status->store_bases[i] = -1;
+  }
+status->next_tmp_reg = 0;
+status->compiler = common->compiler;
+}
+
+static void delayed_mem_copy_move(delayed_mem_copy_status *status, int load_base, sljit_sw load_offset,
+  int store_base, sljit_sw store_offset)
+{
+struct sljit_compiler *compiler = status->compiler;
+int next_tmp_reg = status->next_tmp_reg;
+int tmp_reg = status->tmp_regs[next_tmp_reg];
+
+SLJIT_ASSERT(load_base > 0 && store_base > 0);
+
+if (status->store_bases[next_tmp_reg] == -1)
+  {
+  /* Preserve virtual registers. */
+  if (sljit_get_register_index(status->saved_tmp_regs[next_tmp_reg]) < 0)
+    OP1(SLJIT_MOV, status->saved_tmp_regs[next_tmp_reg], 0, tmp_reg, 0);
+  }
+else
+  OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);
+
+OP1(SLJIT_MOV, tmp_reg, 0, SLJIT_MEM1(load_base), load_offset);
+status->store_bases[next_tmp_reg] = store_base;
+status->store_offsets[next_tmp_reg] = store_offset;
+
+status->next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
+}
+
+static void delayed_mem_copy_finish(delayed_mem_copy_status *status)
+{
+struct sljit_compiler *compiler = status->compiler;
+int next_tmp_reg = status->next_tmp_reg;
+int tmp_reg, saved_tmp_reg, i;
+
+for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
+  {
+  if (status->store_bases[next_tmp_reg] != -1)
+    {
+    tmp_reg = status->tmp_regs[next_tmp_reg];
+    saved_tmp_reg = status->saved_tmp_regs[next_tmp_reg];
+
+    OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);
+
+    /* Restore virtual registers. */
+    if (sljit_get_register_index(saved_tmp_reg) < 0)
+      OP1(SLJIT_MOV, tmp_reg, 0, saved_tmp_reg, 0);
+    }
+
+  next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
+  }
+}
+
+#undef RECURSE_TMP_REG_COUNT
+
+static int get_recurse_data_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
+  BOOL *needs_control_head, BOOL *has_quit, BOOL *has_accept)
+{
+int length = 1;
 int size;
 PCRE2_SPTR alternative;
+BOOL quit_found = FALSE;
+BOOL accept_found = FALSE;
+BOOL setsom_found = FALSE;
+BOOL setmark_found = FALSE;
+BOOL capture_last_found = FALSE;
+BOOL control_head_found = FALSE;
+
+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
+SLJIT_ASSERT(common->control_head_ptr != 0);
+control_head_found = TRUE;
+#endif
+
 /* Calculate the sum of the private machine words. */
 while (cc < ccend)
   {
   size = 0;
   switch(*cc)
     {
+    case OP_SET_SOM:
+    SLJIT_ASSERT(common->has_set_som);
+    setsom_found = TRUE;
+    cc += 1;
+    break;
+
+    case OP_RECURSE:
+    if (common->has_set_som)
+      setsom_found = TRUE;
+    if (common->mark_ptr != 0)
+      setmark_found = TRUE;
+    if (common->capture_last_ptr != 0)
+      capture_last_found = TRUE;
+    cc += 1 + LINK_SIZE;
+    break;
+
     case OP_KET:
     if (PRIVATE_DATA(cc) != 0)
       {
-      private_data_length++;
+      length++;
       SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
       cc += PRIVATE_DATA(cc + 1);
       }
@@ -1802,26 +1947,30 @@
     case OP_ASSERTBACK:
     case OP_ASSERTBACK_NOT:
     case OP_ONCE:
-    case OP_ONCE_NC:
     case OP_BRAPOS:
     case OP_SBRA:
     case OP_SBRAPOS:
     case OP_SCOND:
-    private_data_length++;
+    length++;
     SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
     cc += 1 + LINK_SIZE;
     break;
 
     case OP_CBRA:
     case OP_SCBRA:
+    length += 2;
+    if (common->capture_last_ptr != 0)
+      capture_last_found = TRUE;
     if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
-      private_data_length++;
+      length++;
     cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;
 
     case OP_CBRAPOS:
     case OP_SCBRAPOS:
-    private_data_length += 2;
+    length += 2 + 2;
+    if (common->capture_last_ptr != 0)
+      capture_last_found = TRUE;
     cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;
 
@@ -1829,13 +1978,13 @@
     /* Might be a hidden SCOND. */
     alternative = cc + GET(cc, 1);
     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
-      private_data_length++;
+      length++;
     cc += 1 + LINK_SIZE;
     break;
 
     CASE_ITERATOR_PRIVATE_DATA_1
-    if (PRIVATE_DATA(cc))
-      private_data_length++;
+    if (PRIVATE_DATA(cc) != 0)
+      length++;
     cc += 2;
 #ifdef SUPPORT_UNICODE
     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
@@ -1843,8 +1992,8 @@
     break;
 
     CASE_ITERATOR_PRIVATE_DATA_2A
-    if (PRIVATE_DATA(cc))
-      private_data_length += 2;
+    if (PRIVATE_DATA(cc) != 0)
+      length += 2;
     cc += 2;
 #ifdef SUPPORT_UNICODE
     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
@@ -1852,8 +2001,8 @@
     break;
 
     CASE_ITERATOR_PRIVATE_DATA_2B
-    if (PRIVATE_DATA(cc))
-      private_data_length += 2;
+    if (PRIVATE_DATA(cc) != 0)
+      length += 2;
     cc += 2 + IMM2_SIZE;
 #ifdef SUPPORT_UNICODE
     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
@@ -1861,20 +2010,20 @@
     break;
 
     CASE_ITERATOR_TYPE_PRIVATE_DATA_1
-    if (PRIVATE_DATA(cc))
-      private_data_length++;
+    if (PRIVATE_DATA(cc) != 0)
+      length++;
     cc += 1;
     break;
 
     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
-    if (PRIVATE_DATA(cc))
-      private_data_length += 2;
+    if (PRIVATE_DATA(cc) != 0)
+      length += 2;
     cc += 1;
     break;
 
     CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
-    if (PRIVATE_DATA(cc))
-      private_data_length += 2;
+    if (PRIVATE_DATA(cc) != 0)
+      length += 2;
     cc += 1 + IMM2_SIZE;
     break;
 
@@ -1886,11 +2035,51 @@
 #else
     size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
 #endif
-    if (PRIVATE_DATA(cc))
-      private_data_length += get_class_iterator_size(cc + size);
+    if (PRIVATE_DATA(cc) != 0)
+      length += get_class_iterator_size(cc + size);
     cc += size;
     break;
 
+    case OP_MARK:
+    case OP_PRUNE_ARG:
+    case OP_THEN_ARG:
+    SLJIT_ASSERT(common->mark_ptr != 0);
+    if (!setmark_found)
+      setmark_found = TRUE;
+    if (common->control_head_ptr != 0)
+      control_head_found = TRUE;
+    if (*cc != OP_MARK)
+      quit_found = TRUE;
+
+    cc += 1 + 2 + cc[1];
+    break;
+
+    case OP_PRUNE:
+    case OP_SKIP:
+    case OP_COMMIT:
+    quit_found = TRUE;
+    cc++;
+    break;
+
+    case OP_SKIP_ARG:
+    quit_found = TRUE;
+    cc += 1 + 2 + cc[1];
+    break;
+
+    case OP_THEN:
+    SLJIT_ASSERT(common->control_head_ptr != 0);
+    quit_found = TRUE;
+    if (!control_head_found)
+      control_head_found = TRUE;
+    cc++;
+    break;
+
+    case OP_ACCEPT:
+    case OP_ASSERT_ACCEPT:
+    accept_found = TRUE;
+    cc++;
+    break;
+
     default:
     cc = next_opcode(common, cc);
     SLJIT_ASSERT(cc != NULL);
@@ -1898,329 +2087,446 @@
     }
   }
 SLJIT_ASSERT(cc == ccend);
-return private_data_length;
+
+if (control_head_found)
+  length++;
+if (capture_last_found)
+  length++;
+if (quit_found)
+  {
+  if (setsom_found)
+    length++;
+  if (setmark_found)
+    length++;
+  }
+
+*needs_control_head = control_head_found;
+*has_quit = quit_found;
+*has_accept = accept_found;
+return length;
 }
 
-static void copy_private_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
-  BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
+enum copy_recurse_data_types {
+  recurse_copy_from_global,
+  recurse_copy_private_to_global,
+  recurse_copy_shared_to_global,
+  recurse_copy_kept_shared_to_global,
+  recurse_swap_global
+};
+
+static void copy_recurse_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
+  int type, int stackptr, int stacktop, BOOL has_quit)
 {
-DEFINE_COMPILER;
-int srcw[2];
-int count, size;
-BOOL tmp1next = TRUE;
-BOOL tmp1empty = TRUE;
-BOOL tmp2empty = TRUE;
+delayed_mem_copy_status status;
 PCRE2_SPTR alternative;
-enum {
-  start,
-  loop,
-  end
-} status;
+sljit_sw private_srcw[2];
+sljit_sw shared_srcw[3];
+sljit_sw kept_shared_srcw[2];
+int private_count, shared_count, kept_shared_count;
+int from_sp, base_reg, offset, i;
+BOOL setsom_found = FALSE;
+BOOL setmark_found = FALSE;
+BOOL capture_last_found = FALSE;
+BOOL control_head_found = FALSE;
 
-status = save ? start : loop;
-stackptr = STACK(stackptr - 2);
-stacktop = STACK(stacktop - 1);
+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
+SLJIT_ASSERT(common->control_head_ptr != 0);
+control_head_found = TRUE;
+#endif
 
-if (!save)
+switch (type)
   {
-  stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
-  if (stackptr < stacktop)
-    {
-    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
-    stackptr += sizeof(sljit_sw);
-    tmp1empty = FALSE;
-    }
-  if (stackptr < stacktop)
-    {
-    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
-    stackptr += sizeof(sljit_sw);
-    tmp2empty = FALSE;
-    }
-  /* The tmp1next must be TRUE in either way. */
+  case recurse_copy_from_global:
+  from_sp = TRUE;
+  base_reg = STACK_TOP;
+  break;
+
+  case recurse_copy_private_to_global:
+  case recurse_copy_shared_to_global:
+  case recurse_copy_kept_shared_to_global:
+  from_sp = FALSE;
+  base_reg = STACK_TOP;
+  break;
+
+  default:
+  SLJIT_ASSERT(type == recurse_swap_global);
+  from_sp = FALSE;
+  base_reg = TMP2;
+  break;
   }
 
-do
+stackptr = STACK(stackptr);
+stacktop = STACK(stacktop);
+
+status.tmp_regs[0] = TMP1;
+status.saved_tmp_regs[0] = TMP1;
+
+if (base_reg != TMP2)
   {
-  count = 0;
-  switch(status)
+  status.tmp_regs[1] = TMP2;
+  status.saved_tmp_regs[1] = TMP2;
+  }
+else
+  {
+  status.saved_tmp_regs[1] = RETURN_ADDR;
+  if (sljit_get_register_index (RETURN_ADDR) == -1)
+    status.tmp_regs[1] = STR_PTR;
+  else
+    status.tmp_regs[1] = RETURN_ADDR;
+  }
+
+status.saved_tmp_regs[2] = TMP3;
+if (sljit_get_register_index (TMP3) == -1)
+  status.tmp_regs[2] = STR_END;
+else
+  status.tmp_regs[2] = TMP3;
+
+delayed_mem_copy_init(&status, common);
+
+if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
+  {
+  SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);
+
+  if (!from_sp)
+    delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->recursive_head_ptr);
+
+  if (from_sp || type == recurse_swap_global)
+    delayed_mem_copy_move(&status, SLJIT_SP, common->recursive_head_ptr, base_reg, stackptr);
+  }
+
+stackptr += sizeof(sljit_sw);
+
+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
+if (type != recurse_copy_shared_to_global)
+  {
+  if (!from_sp)
+    delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->control_head_ptr);
+
+  if (from_sp || type == recurse_swap_global)
+    delayed_mem_copy_move(&status, SLJIT_SP, common->control_head_ptr, base_reg, stackptr);
+  }
+
+stackptr += sizeof(sljit_sw);
+#endif
+
+while (cc < ccend)
+  {
+  private_count = 0;
+  shared_count = 0;
+  kept_shared_count = 0;
+
+  switch(*cc)
     {
-    case start:
-    SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
-    count = 1;
-    srcw[0] = common->recursive_head_ptr;
-    if (needs_control_head)
+    case OP_SET_SOM:
+    SLJIT_ASSERT(common->has_set_som);
+    if (has_quit && !setsom_found)
       {
-      SLJIT_ASSERT(common->control_head_ptr != 0);
-      count = 2;
-      srcw[1] = common->control_head_ptr;
+      kept_shared_srcw[0] = OVECTOR(0);
+      kept_shared_count = 1;
+      setsom_found = TRUE;
       }
-    status = loop;
+    cc += 1;
     break;
 
-    case loop:
-    if (cc >= ccend)
+    case OP_RECURSE:
+    if (has_quit)
       {
-      status = end;
-      break;
+      if (common->has_set_som && !setsom_found)
+        {
+        kept_shared_srcw[0] = OVECTOR(0);
+        kept_shared_count = 1;
+        setsom_found = TRUE;
+        }
+      if (common->mark_ptr != 0 && !setmark_found)
+        {
+        kept_shared_srcw[kept_shared_count] = common->mark_ptr;
+        kept_shared_count++;
+        setmark_found = TRUE;
+        }
+      }
+    if (common->capture_last_ptr != 0 && !capture_last_found)
+      {
+      shared_srcw[0] = common->capture_last_ptr;
+      shared_count = 1;
+      capture_last_found = TRUE;
+      }
+    cc += 1 + LINK_SIZE;
+    break;
+
+    case OP_KET:
+    if (PRIVATE_DATA(cc) != 0)
+      {
+      private_count = 1;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
+      cc += PRIVATE_DATA(cc + 1);
+      }
+    cc += 1 + LINK_SIZE;
+    break;
+
+    case OP_ASSERT:
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK:
+    case OP_ASSERTBACK_NOT:
+    case OP_ONCE:
+    case OP_BRAPOS:
+    case OP_SBRA:
+    case OP_SBRAPOS:
+    case OP_SCOND:
+    private_count = 1;
+    private_srcw[0] = PRIVATE_DATA(cc);
+    cc += 1 + LINK_SIZE;
+    break;
+
+    case OP_CBRA:
+    case OP_SCBRA:
+    offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
+    shared_srcw[0] = OVECTOR(offset);
+    shared_srcw[1] = OVECTOR(offset + 1);
+    shared_count = 2;
+
+    if (common->capture_last_ptr != 0 && !capture_last_found)
+      {
+      shared_srcw[2] = common->capture_last_ptr;
+      shared_count = 3;
+      capture_last_found = TRUE;
       }
 
-    switch(*cc)
+    if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
       {
-      case OP_KET:
-      if (PRIVATE_DATA(cc) != 0)
-        {
-        count = 1;
-        srcw[0] = PRIVATE_DATA(cc);
-        SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
-        cc += PRIVATE_DATA(cc + 1);
-        }
-      cc += 1 + LINK_SIZE;
-      break;
+      private_count = 1;
+      private_srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+      }
+    cc += 1 + LINK_SIZE + IMM2_SIZE;
+    break;
 
-      case OP_ASSERT:
-      case OP_ASSERT_NOT:
-      case OP_ASSERTBACK:
-      case OP_ASSERTBACK_NOT:
-      case OP_ONCE:
-      case OP_ONCE_NC:
-      case OP_BRAPOS:
-      case OP_SBRA:
-      case OP_SBRAPOS:
-      case OP_SCOND:
-      count = 1;
-      srcw[0] = PRIVATE_DATA(cc);
-      SLJIT_ASSERT(srcw[0] != 0);
-      cc += 1 + LINK_SIZE;
-      break;
+    case OP_CBRAPOS:
+    case OP_SCBRAPOS:
+    offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
+    shared_srcw[0] = OVECTOR(offset);
+    shared_srcw[1] = OVECTOR(offset + 1);
+    shared_count = 2;
 
-      case OP_CBRA:
-      case OP_SCBRA:
-      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
-        {
-        count = 1;
-        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
-        }
-      cc += 1 + LINK_SIZE + IMM2_SIZE;
-      break;
+    if (common->capture_last_ptr != 0 && !capture_last_found)
+      {
+      shared_srcw[2] = common->capture_last_ptr;
+      shared_count = 3;
+      capture_last_found = TRUE;
+      }
 
-      case OP_CBRAPOS:
-      case OP_SCBRAPOS:
-      count = 2;
-      srcw[0] = PRIVATE_DATA(cc);
-      srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
-      SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
-      cc += 1 + LINK_SIZE + IMM2_SIZE;
-      break;
+    private_count = 2;
+    private_srcw[0] = PRIVATE_DATA(cc);
+    private_srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+    cc += 1 + LINK_SIZE + IMM2_SIZE;
+    break;
 
-      case OP_COND:
-      /* Might be a hidden SCOND. */
-      alternative = cc + GET(cc, 1);
-      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
-        {
-        count = 1;
-        srcw[0] = PRIVATE_DATA(cc);
-        SLJIT_ASSERT(srcw[0] != 0);
-        }
-      cc += 1 + LINK_SIZE;
-      break;
+    case OP_COND:
+    /* Might be a hidden SCOND. */
+    alternative = cc + GET(cc, 1);
+    if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+      {
+      private_count = 1;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      }
+    cc += 1 + LINK_SIZE;
+    break;
 
-      CASE_ITERATOR_PRIVATE_DATA_1
-      if (PRIVATE_DATA(cc))
-        {
-        count = 1;
-        srcw[0] = PRIVATE_DATA(cc);
-        }
-      cc += 2;
+    CASE_ITERATOR_PRIVATE_DATA_1
+    if (PRIVATE_DATA(cc))
+      {
+      private_count = 1;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      }
+    cc += 2;
 #ifdef SUPPORT_UNICODE
-      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
 #endif
-      break;
+    break;
 
-      CASE_ITERATOR_PRIVATE_DATA_2A
-      if (PRIVATE_DATA(cc))
-        {
-        count = 2;
-        srcw[0] = PRIVATE_DATA(cc);
-        srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
-        }
-      cc += 2;
+    CASE_ITERATOR_PRIVATE_DATA_2A
+    if (PRIVATE_DATA(cc))
+      {
+      private_count = 2;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
+      }
+    cc += 2;
 #ifdef SUPPORT_UNICODE
-      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
 #endif
-      break;
+    break;
 
-      CASE_ITERATOR_PRIVATE_DATA_2B
-      if (PRIVATE_DATA(cc))
-        {
-        count = 2;
-        srcw[0] = PRIVATE_DATA(cc);
-        srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
-        }
-      cc += 2 + IMM2_SIZE;
+    CASE_ITERATOR_PRIVATE_DATA_2B
+    if (PRIVATE_DATA(cc))
+      {
+      private_count = 2;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
+      }
+    cc += 2 + IMM2_SIZE;
 #ifdef SUPPORT_UNICODE
-      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
 #endif
-      break;
+    break;
 
-      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
-      if (PRIVATE_DATA(cc))
-        {
-        count = 1;
-        srcw[0] = PRIVATE_DATA(cc);
-        }
-      cc += 1;
-      break;
+    CASE_ITERATOR_TYPE_PRIVATE_DATA_1
+    if (PRIVATE_DATA(cc))
+      {
+      private_count = 1;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      }
+    cc += 1;
+    break;
 
-      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
-      if (PRIVATE_DATA(cc))
-        {
-        count = 2;
-        srcw[0] = PRIVATE_DATA(cc);
-        srcw[1] = srcw[0] + sizeof(sljit_sw);
-        }
-      cc += 1;
-      break;
+    CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
+    if (PRIVATE_DATA(cc))
+      {
+      private_count = 2;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
+      }
+    cc += 1;
+    break;
 
-      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
-      if (PRIVATE_DATA(cc))
-        {
-        count = 2;
-        srcw[0] = PRIVATE_DATA(cc);
-        srcw[1] = srcw[0] + sizeof(sljit_sw);
-        }
-      cc += 1 + IMM2_SIZE;
-      break;
+    CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
+    if (PRIVATE_DATA(cc))
+      {
+      private_count = 2;
+      private_srcw[0] = PRIVATE_DATA(cc);
+      private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
+      }
+    cc += 1 + IMM2_SIZE;
+    break;
 
-      case OP_CLASS:
-      case OP_NCLASS:
+    case OP_CLASS:
+    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_XCLASS:
+    i = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);
 #else
-      size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
+    i = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
 #endif
-      if (PRIVATE_DATA(cc))
-        switch(get_class_iterator_size(cc + size))
-          {
-          case 1:
-          count = 1;
-          srcw[0] = PRIVATE_DATA(cc);
-          break;
+    if (PRIVATE_DATA(cc) != 0)
+      switch(get_class_iterator_size(cc + i))
+        {
+        case 1:
+        private_count = 1;
+        private_srcw[0] = PRIVATE_DATA(cc);
+        break;
 
-          case 2:
-          count = 2;
-          srcw[0] = PRIVATE_DATA(cc);
-          srcw[1] = srcw[0] + sizeof(sljit_sw);
-          break;
+        case 2:
+        private_count = 2;
+        private_srcw[0] = PRIVATE_DATA(cc);
+        private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
+        break;
 
-          default:
-          SLJIT_ASSERT_STOP();
-          break;
-          }
-      cc += size;
-      break;
-
-      default:
-      cc = next_opcode(common, cc);
-      SLJIT_ASSERT(cc != NULL);
-      break;
-      }
+        default:
+        SLJIT_UNREACHABLE();
+        break;
+        }
+    cc += i;
     break;
 
-    case end:
-    SLJIT_ASSERT_STOP();
+    case OP_MARK:
+    case OP_PRUNE_ARG:
+    case OP_THEN_ARG:
+    SLJIT_ASSERT(common->mark_ptr != 0);
+    if (has_quit && !setmark_found)
+      {
+      kept_shared_srcw[0] = common->mark_ptr;
+      kept_shared_count = 1;
+      setmark_found = TRUE;
+      }
+    if (common->control_head_ptr != 0 && !control_head_found)
+      {
+      shared_srcw[0] = common->control_head_ptr;
+      shared_count = 1;
+      control_head_found = TRUE;
+      }
+    cc += 1 + 2 + cc[1];
+    break;
+
+    case OP_THEN:
+    SLJIT_ASSERT(common->control_head_ptr != 0);
+    if (!control_head_found)
+      {
+      shared_srcw[0] = common->control_head_ptr;
+      shared_count = 1;
+      control_head_found = TRUE;
+      }
+    cc++;
+    break;
+
+    default:
+    cc = next_opcode(common, cc);
+    SLJIT_ASSERT(cc != NULL);
     break;
     }
 
-  while (count > 0)
+  if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
     {
-    count--;
-    if (save)
-      {
-      if (tmp1next)
-        {
-        if (!tmp1empty)
-          {
-          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
-          stackptr += sizeof(sljit_sw);
-          }
-        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
-        tmp1empty = FALSE;
-        tmp1next = FALSE;
-        }
-      else
-        {
-        if (!tmp2empty)
-          {
-          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
-          stackptr += sizeof(sljit_sw);
-          }
-        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
-        tmp2empty = FALSE;
-        tmp1next = TRUE;
-        }
-      }
-    else
-      {
-      if (tmp1next)
-        {
-        SLJIT_ASSERT(!tmp1empty);
-        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0);
-        tmp1empty = stackptr >= stacktop;
-        if (!tmp1empty)
-          {
-          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
-          stackptr += sizeof(sljit_sw);
-          }
-        tmp1next = FALSE;
-        }
-      else
-        {
-        SLJIT_ASSERT(!tmp2empty);
-        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0);
-        tmp2empty = stackptr >= stacktop;
-        if (!tmp2empty)
-          {
-          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
-          stackptr += sizeof(sljit_sw);
-          }
-        tmp1next = TRUE;
-        }
-      }
-    }
-  }
-while (status != end);
+    SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);
 
-if (save)
-  {
-  if (tmp1next)
-    {
-    if (!tmp1empty)
+    for (i = 0; i < private_count; i++)
       {
-      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
-      stackptr += sizeof(sljit_sw);
-      }
-    if (!tmp2empty)
-      {
-      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+      SLJIT_ASSERT(private_srcw[i] != 0);
+
+      if (!from_sp)
+        delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, private_srcw[i]);
+
+      if (from_sp || type == recurse_swap_global)
+        delayed_mem_copy_move(&status, SLJIT_SP, private_srcw[i], base_reg, stackptr);
+
       stackptr += sizeof(sljit_sw);
       }
     }
   else
+    stackptr += sizeof(sljit_sw) * private_count;
+
+  if (type != recurse_copy_private_to_global && type != recurse_copy_kept_shared_to_global)
     {
-    if (!tmp2empty)
+    SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_swap_global);
+
+    for (i = 0; i < shared_count; i++)
       {
-      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
-      stackptr += sizeof(sljit_sw);
-      }
-    if (!tmp1empty)
-      {
-      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+      SLJIT_ASSERT(shared_srcw[i] != 0);
+
+      if (!from_sp)
+        delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, shared_srcw[i]);
+
+      if (from_sp || type == recurse_swap_global)
+        delayed_mem_copy_move(&status, SLJIT_SP, shared_srcw[i], base_reg, stackptr);
+
       stackptr += sizeof(sljit_sw);
       }
     }
+  else
+    stackptr += sizeof(sljit_sw) * shared_count;
+
+  if (type != recurse_copy_private_to_global && type != recurse_swap_global)
+    {
+    SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_copy_kept_shared_to_global);
+
+    for (i = 0; i < kept_shared_count; i++)
+      {
+      SLJIT_ASSERT(kept_shared_srcw[i] != 0);
+
+      if (!from_sp)
+        delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, kept_shared_srcw[i]);
+
+      if (from_sp || type == recurse_swap_global)
+        delayed_mem_copy_move(&status, SLJIT_SP, kept_shared_srcw[i], base_reg, stackptr);
+
+      stackptr += sizeof(sljit_sw);
+      }
+    }
+  else
+    stackptr += sizeof(sljit_sw) * kept_shared_count;
   }
-SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
+
+SLJIT_ASSERT(cc == ccend && stackptr == stacktop);
+
+delayed_mem_copy_finish(&status);
 }
 
 static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_u8 *current_offset)
@@ -2337,7 +2643,7 @@
 {
 DEFINE_COMPILER;
 
-OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
+OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
 add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
 }
 
@@ -2347,7 +2653,7 @@
 DEFINE_COMPILER;
 
 SLJIT_ASSERT(size > 0);
-OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
+OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
 #ifdef DESTROY_REGISTERS
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
@@ -2355,7 +2661,7 @@
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
 #endif
-add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
+add_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0));
 }
 
 static SLJIT_INLINE void free_stack(compiler_common *common, int size)
@@ -2363,7 +2669,7 @@
 DEFINE_COMPILER;
 
 SLJIT_ASSERT(size > 0);
-OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
+OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
 }
 
 static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
@@ -2403,12 +2709,25 @@
   }
 else
   {
-  GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
-  OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
-  loop = LABEL();
-  OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
-  JUMPTO(SLJIT_NOT_ZERO, loop);
+  if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw)) == SLJIT_SUCCESS)
+    {
+    GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
+    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
+    loop = LABEL();
+    sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw));
+    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
+    JUMPTO(SLJIT_NOT_ZERO, loop);
+    }
+  else
+    {
+    GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START + sizeof(sljit_sw));
+    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
+    loop = LABEL();
+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R0, 0);
+    OP2(SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, sizeof(sljit_sw));
+    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
+    JUMPTO(SLJIT_NOT_ZERO, loop);
+    }
   }
 }
 
@@ -2441,12 +2760,25 @@
   }
 else
   {
-  GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
-  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
-  loop = LABEL();
-  OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
-  OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
-  JUMPTO(SLJIT_NOT_ZERO, loop);
+  if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw)) == SLJIT_SUCCESS)
+    {
+    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
+    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
+    loop = LABEL();
+    sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+    OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
+    JUMPTO(SLJIT_NOT_ZERO, loop);
+    }
+  else
+    {
+    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 * sizeof(sljit_sw));
+    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
+    loop = LABEL();
+    OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
+    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(sljit_sw));
+    OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
+    JUMPTO(SLJIT_NOT_ZERO, loop);
+    }
   }
 
 OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
@@ -2456,37 +2788,38 @@
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
 }
 
-static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)
+static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)
 {
 while (current != NULL)
   {
-  switch (current[-2])
+  switch (current[1])
     {
     case type_then_trap:
     break;
 
     case type_mark:
-    if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[-3]) == 0)
-      return current[-4];
+    if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[2]) == 0)
+      return current[3];
     break;
 
     default:
-    SLJIT_ASSERT_STOP();
+    SLJIT_UNREACHABLE();
     break;
     }
-  SLJIT_ASSERT(current > (sljit_sw*)current[-1]);
-  current = (sljit_sw*)current[-1];
+  SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
+  current = (sljit_sw*)current[0];
   }
-return -1;
+return 0;
 }
 
 static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
 {
 DEFINE_COMPILER;
 struct sljit_label *loop;
+BOOL has_pre;
 
 /* At this point we can freely use all registers. */
 OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
@@ -2503,36 +2836,62 @@
 OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data),
   SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
 
-GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
+has_pre = sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;
+
+GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));
 OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
 
 loop = LABEL();
-OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
-OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
+
+if (has_pre)
+  sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw));
+else
+  {
+  OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0);
+  OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
+  }
+
+OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, sizeof(PCRE2_SIZE));
+OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_R0, 0);
 /* Copy the integer value to the output buffer */
 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
 #endif
+
 SLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8);
-if (sizeof(PCRE2_SIZE) == 4)
-  OP1(SLJIT_MOVU_U32, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0);
-else
-  OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R2), sizeof(PCRE2_SIZE), SLJIT_S1, 0);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
+OP1(((sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV), SLJIT_MEM1(SLJIT_R2), 0, SLJIT_S1, 0);
+
+OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
 JUMPTO(SLJIT_NOT_ZERO, loop);
 
 /* Calculate the return value, which is the maximum ovector value. */
 if (topbracket > 1)
   {
-  GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
-  OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
+  if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))) == SLJIT_SUCCESS)
+    {
+    GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
+    OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
 
-  /* OVECTOR(0) is never equal to SLJIT_S2. */
-  loop = LABEL();
-  OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
-  OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
-  CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
-  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
+    /* OVECTOR(0) is never equal to SLJIT_S2. */
+    loop = LABEL();
+    sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
+    OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
+    CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
+    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
+    }
+  else
+    {
+    GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 * sizeof(sljit_sw));
+    OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
+
+    /* OVECTOR(0) is never equal to SLJIT_S2. */
+    loop = LABEL();
+    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), 0);
+    OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2 * (sljit_sw)sizeof(sljit_sw));
+    OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
+    CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
+    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
+    }
   }
 else
   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
@@ -2543,7 +2902,7 @@
 DEFINE_COMPILER;
 sljit_s32 mov_opcode;
 
-SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2);
+SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S0, str_end_must_be_saved_reg0);
 SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
   && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));
 
@@ -2553,19 +2912,19 @@
 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);
 
 /* Store match begin and end. */
-OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
 OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data));
 
 mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
 
-OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0);
+OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S1, 0);
 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
 OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
 #endif
 OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0);
 
-OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S0, 0);
+OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S1, 0);
 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
 OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT);
 #endif
@@ -3104,8 +3463,8 @@
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
   /* Skip low surrogate if necessary. */
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
-  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
+  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   return;
@@ -3124,6 +3483,7 @@
 if (nltype == NLTYPE_ANY)
   {
   add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+  sljit_set_current_flags(compiler, SLJIT_SET_Z);
   add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));
   }
 else if (nltype == NLTYPE_ANYCRLF)
@@ -3165,7 +3525,7 @@
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
 
 /* Searching for the first zero. */
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
 jump = JUMP(SLJIT_NOT_ZERO);
 /* Two byte sequence. */
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
@@ -3179,7 +3539,7 @@
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
 
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
 jump = JUMP(SLJIT_NOT_ZERO);
 /* Three byte sequence. */
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
@@ -3213,15 +3573,15 @@
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
 
 /* Searching for the first zero. */
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
 jump = JUMP(SLJIT_NOT_ZERO);
 /* Two byte sequence. */
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 
 JUMPHERE(jump);
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO);
+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO);
 /* This code runs only in 8 bit mode. No need to shift the value. */
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
@@ -3244,7 +3604,7 @@
 
 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
 
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
 jump = JUMP(SLJIT_NOT_ZERO);
 /* Two byte sequence. */
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
@@ -3281,10 +3641,30 @@
 /* Search the UCD record for the character comes in TMP1.
 Returns chartype in TMP1 and UCD offset in TMP2. */
 DEFINE_COMPILER;
+#if PCRE2_CODE_UNIT_WIDTH == 32
+struct sljit_jump *jump;
+#endif
+
+#if defined SLJIT_DEBUG && SLJIT_DEBUG
+/* dummy_ucd_record */
+const ucd_record *record = GET_UCD(INVALID_UTF_CHAR);
+SLJIT_ASSERT(record->script == ucp_Common && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther);
+SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0);
+#endif
 
 SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
 
 sljit_emit_fast_enter(compiler, RETURN_ADDR, 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, INVALID_UTF_CHAR);
+  JUMPHERE(jump);
+  }
+#endif
+
 OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
@@ -3299,7 +3679,7 @@
 
 #endif /* SUPPORT_UNICODE */
 
-static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, sljit_u32 overall_options)
+static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common)
 {
 DEFINE_COMPILER;
 struct sljit_label *mainloop;
@@ -3311,6 +3691,8 @@
 struct sljit_jump *singlechar;
 #endif
 jump_list *newline = NULL;
+sljit_u32 overall_options = common->re->overall_options;
+BOOL hascrorlf = (common->re->flags & PCRE2_HASCRORLF) != 0;
 BOOL newlinecheck = FALSE;
 BOOL readuchar = FALSE;
 
@@ -3318,7 +3700,7 @@
     && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
   newlinecheck = TRUE;
 
-SLJIT_ASSERT(common->forced_quit_label == NULL);
+SLJIT_ASSERT(common->abort_label == NULL);
 
 if ((overall_options & PCRE2_FIRSTLINE) != 0)
   {
@@ -3375,7 +3757,7 @@
   OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
   JUMPHERE(end2);
   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
-  add_jump(compiler, &common->forced_quit, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0));
+  add_jump(compiler, &common->abort, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0));
   JUMPHERE(end);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0);
   }
@@ -3388,8 +3770,8 @@
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
   end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
-  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
+  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
@@ -3426,8 +3808,8 @@
   {
   singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   JUMPHERE(singlechar);
@@ -3445,40 +3827,42 @@
 return mainloop;
 }
 
-#define MAX_N_CHARS 16
-#define MAX_DIFF_CHARS 6
 
-static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, PCRE2_UCHAR *chars)
+static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, fast_forward_char_data *chars, BOOL last)
 {
-PCRE2_UCHAR i, len;
+sljit_u32 i, count = chars->count;
 
-len = chars[0];
-if (len == 255)
+if (count == 255)
   return;
 
-if (len == 0)
+if (count == 0)
   {
-  chars[0] = 1;
-  chars[1] = chr;
+  chars->count = 1;
+  chars->chars[0] = chr;
+
+  if (last)
+    chars->last_count = 1;
   return;
   }
 
-for (i = len; i > 0; i--)
-  if (chars[i] == chr)
+for (i = 0; i < count; i++)
+  if (chars->chars[i] == chr)
     return;
 
-if (len >= MAX_DIFF_CHARS - 1)
+if (count >= MAX_DIFF_CHARS)
   {
-  chars[0] = 255;
+  chars->count = 255;
   return;
   }
 
-len++;
-chars[len] = chr;
-chars[0] = len;
+chars->chars[count] = chr;
+chars->count = count + 1;
+
+if (last)
+  chars->last_count++;
 }
 
-static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *chars, int max_chars, sljit_u32 *rec_count)
+static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars, int max_chars, sljit_u32 *rec_count)
 {
 /* Recursive function, which scans prefix literals. */
 BOOL last, any, class, caseless;
@@ -3487,7 +3871,7 @@
 sljit_u8 *bytes, *bytes_end, byte;
 PCRE2_SPTR alternative, cc_save, oc;
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
-PCRE2_UCHAR othercase[8];
+PCRE2_UCHAR othercase[4];
 #elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
 PCRE2_UCHAR othercase[2];
 #else
@@ -3510,6 +3894,7 @@
     {
     case OP_CHARI:
     caseless = TRUE;
+    /* Fall through */
     case OP_CHAR:
     last = FALSE;
     cc++;
@@ -3541,6 +3926,7 @@
     case OP_MINPLUSI:
     case OP_POSPLUSI:
     caseless = TRUE;
+    /* Fall through */
     case OP_PLUS:
     case OP_MINPLUS:
     case OP_POSPLUS:
@@ -3549,6 +3935,7 @@
 
     case OP_EXACTI:
     caseless = TRUE;
+    /* Fall through */
     case OP_EXACT:
     repeat = GET2(cc, 1);
     last = FALSE;
@@ -3559,6 +3946,7 @@
     case OP_MINQUERYI:
     case OP_POSQUERYI:
     caseless = TRUE;
+    /* Fall through */
     case OP_QUERY:
     case OP_MINQUERY:
     case OP_POSQUERY:
@@ -3582,7 +3970,6 @@
     continue;
 
     case OP_ONCE:
-    case OP_ONCE_NC:
     case OP_BRA:
     case OP_BRAPOS:
     case OP_CBRA:
@@ -3703,12 +4090,12 @@
     {
     do
       {
-      chars[0] = 255;
+      chars->count = 255;
 
       consumed++;
       if (--max_chars == 0)
         return consumed;
-      chars += MAX_DIFF_CHARS;
+      chars++;
       }
     while (--repeat > 0);
 
@@ -3752,8 +4139,8 @@
     do
       {
       if (bytes[31] & 0x80)
-        chars[0] = 255;
-      else if (chars[0] != 255)
+        chars->count = 255;
+      else if (chars->count != 255)
         {
         bytes_end = bytes + 32;
         chr = 0;
@@ -3768,7 +4155,7 @@
             do
               {
               if ((byte & 0x1) != 0)
-                add_prefix_char(chr, chars);
+                add_prefix_char(chr, chars, TRUE);
               byte >>= 1;
               chr++;
               }
@@ -3776,14 +4163,14 @@
             chr = (chr + 7) & ~7;
             }
           }
-        while (chars[0] != 255 && bytes < bytes_end);
+        while (chars->count != 255 && bytes < bytes_end);
         bytes = bytes_end - 32;
         }
 
       consumed++;
       if (--max_chars == 0)
         return consumed;
-      chars += MAX_DIFF_CHARS;
+      chars++;
       }
     while (--repeat > 0);
 
@@ -3847,17 +4234,18 @@
     oc = othercase;
     do
       {
-      chr = *cc;
-      add_prefix_char(*cc, chars);
-
-      if (caseless)
-        add_prefix_char(*oc, chars);
-
       len--;
       consumed++;
+
+      chr = *cc;
+      add_prefix_char(*cc, chars, len == 0);
+
+      if (caseless)
+        add_prefix_char(*oc, chars, len == 0);
+
       if (--max_chars == 0)
         return consumed;
-      chars += MAX_DIFF_CHARS;
+      chars++;
       cc++;
       oc++;
       }
@@ -3876,7 +4264,37 @@
   }
 }
 
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+static void jumpto_if_not_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg, struct sljit_label *label)
+{
+#if PCRE2_CODE_UNIT_WIDTH == 8
+OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
+CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0x80, label);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
+CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00, label);
+#else
+#error "Unknown code width"
+#endif
+}
+#endif
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND)
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg)
+{
+#if PCRE2_CODE_UNIT_WIDTH == 8
+OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
+return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
+return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00);
+#else
+#error "Unknown code width"
+#endif
+}
+#endif
 
 static sljit_s32 character_to_int32(PCRE2_UCHAR chr)
 {
@@ -3895,39 +4313,140 @@
 #endif
 }
 
-static SLJIT_INLINE void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
+static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg)
+{
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+sljit_u8 instruction[5];
+#else
+sljit_u8 instruction[4];
+#endif
+
+SLJIT_ASSERT(dst_xmm_reg < 8);
+
+/* MOVDQA xmm1, xmm2/m128 */
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+if (src_general_reg < 8)
+  {
+  instruction[0] = 0x66;
+  instruction[1] = 0x0f;
+  instruction[2] = 0x6f;
+  instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
+  sljit_emit_op_custom(compiler, instruction, 4);
+  }
+else
+  {
+  instruction[0] = 0x66;
+  instruction[1] = 0x41;
+  instruction[2] = 0x0f;
+  instruction[3] = 0x6f;
+  instruction[4] = (dst_xmm_reg << 3) | (src_general_reg & 0x7);
+  sljit_emit_op_custom(compiler, instruction, 4);
+  }
+#else
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+instruction[2] = 0x6f;
+instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
+sljit_emit_op_custom(compiler, instruction, 4);
+#endif
+}
+
+static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, PCRE2_UCHAR char1, PCRE2_UCHAR char2,
+  sljit_u32 bit, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)
+{
+sljit_u8 instruction[4];
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+
+if (char1 == char2 || bit != 0)
+  {
+  if (bit != 0)
+    {
+    /* POR xmm1, xmm2/m128 */
+    /* instruction[0] = 0x66; */
+    /* instruction[1] = 0x0f; */
+    instruction[2] = 0xeb;
+    instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind;
+    sljit_emit_op_custom(compiler, instruction, 4);
+    }
+
+  /* PCMPEQB/W/D xmm1, xmm2/m128 */
+  /* instruction[0] = 0x66; */
+  /* instruction[1] = 0x0f; */
+  instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
+  instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
+  sljit_emit_op_custom(compiler, instruction, 4);
+  }
+else
+  {
+  /* MOVDQA xmm1, xmm2/m128 */
+  /* instruction[0] = 0x66; */
+  /* instruction[1] = 0x0f; */
+  instruction[2] = 0x6f;
+  instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind;
+  sljit_emit_op_custom(compiler, instruction, 4);
+
+  /* PCMPEQB/W/D xmm1, xmm2/m128 */
+  /* instruction[0] = 0x66; */
+  /* instruction[1] = 0x0f; */
+  instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
+  instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
+  sljit_emit_op_custom(compiler, instruction, 4);
+
+  instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind;
+  sljit_emit_op_custom(compiler, instruction, 4);
+
+  /* POR xmm1, xmm2/m128 */
+  /* instruction[0] = 0x66; */
+  /* instruction[1] = 0x0f; */
+  instruction[2] = 0xeb;
+  instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind;
+  sljit_emit_op_custom(compiler, instruction, 4);
+  }
+}
+
+static void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
 {
 DEFINE_COMPILER;
 struct sljit_label *start;
-struct sljit_jump *quit[3];
-struct sljit_jump *nomatch;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_label *restart;
+#endif
+struct sljit_jump *quit;
+struct sljit_jump *partial_quit[2];
 sljit_u8 instruction[8];
 sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
-sljit_s32 tmp2_ind = sljit_get_register_index(TMP2);
 sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
-BOOL load_twice = FALSE;
-PCRE2_UCHAR bit;
+sljit_s32 data_ind = 0;
+sljit_s32 tmp_ind = 1;
+sljit_s32 cmp1_ind = 2;
+sljit_s32 cmp2_ind = 3;
+sljit_u32 bit = 0;
 
-bit = char1 ^ char2;
-if (!is_powerof2(bit))
-  bit = 0;
+SLJIT_UNUSED_ARG(offset);
 
-if ((char1 != char2) && bit == 0)
-  load_twice = TRUE;
+if (char1 != char2)
+  {
+  bit = char1 ^ char2;
+  if (!is_powerof2(bit))
+    bit = 0;
+  }
 
-quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+  add_jump(compiler, &common->failed_match, partial_quit[0]);
 
 /* First part (unaligned start) */
 
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
 
-SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1);
+SLJIT_ASSERT(tmp1_ind < 8);
 
 /* MOVD xmm, r/m32 */
 instruction[0] = 0x66;
 instruction[1] = 0x0f;
 instruction[2] = 0x6e;
-instruction[3] = 0xc0 | (2 << 3) | tmp1_ind;
+instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_ind;
 sljit_emit_op_custom(compiler, instruction, 4);
 
 if (char1 != char2)
@@ -3935,224 +4454,521 @@
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
 
   /* MOVD xmm, r/m32 */
-  instruction[3] = 0xc0 | (3 << 3) | tmp1_ind;
+  instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_ind;
   sljit_emit_op_custom(compiler, instruction, 4);
   }
 
+OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+
 /* PSHUFD xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
 instruction[2] = 0x70;
-instruction[3] = 0xc0 | (2 << 3) | 2;
+instruction[3] = 0xc0 | (cmp1_ind << 3) | 2;
 instruction[4] = 0;
 sljit_emit_op_custom(compiler, instruction, 5);
 
 if (char1 != char2)
   {
   /* PSHUFD xmm1, xmm2/m128, imm8 */
-  instruction[3] = 0xc0 | (3 << 3) | 3;
-  instruction[4] = 0;
+  instruction[3] = 0xc0 | (cmp2_ind << 3) | 3;
   sljit_emit_op_custom(compiler, instruction, 5);
   }
 
-OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 0xf);
-OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
-
-/* MOVDQA xmm1, xmm2/m128 */
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-
-if (str_ptr_ind < 8)
-  {
-  instruction[2] = 0x6f;
-  instruction[3] = (0 << 3) | str_ptr_ind;
-  sljit_emit_op_custom(compiler, instruction, 4);
-
-  if (load_twice)
-    {
-    instruction[3] = (1 << 3) | str_ptr_ind;
-    sljit_emit_op_custom(compiler, instruction, 4);
-    }
-  }
-else
-  {
-  instruction[1] = 0x41;
-  instruction[2] = 0x0f;
-  instruction[3] = 0x6f;
-  instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
-  sljit_emit_op_custom(compiler, instruction, 5);
-
-  if (load_twice)
-    {
-    instruction[4] = (1 << 3) | str_ptr_ind;
-    sljit_emit_op_custom(compiler, instruction, 5);
-    }
-  instruction[1] = 0x0f;
-  }
-
-#else
-
-instruction[2] = 0x6f;
-instruction[3] = (0 << 3) | str_ptr_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (load_twice)
-  {
-  instruction[3] = (1 << 3) | str_ptr_ind;
-  sljit_emit_op_custom(compiler, instruction, 4);
-  }
-
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+restart = LABEL();
 #endif
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
 
-if (bit != 0)
-  {
-  /* POR xmm1, xmm2/m128 */
-  instruction[2] = 0xeb;
-  instruction[3] = 0xc0 | (0 << 3) | 3;
-  sljit_emit_op_custom(compiler, instruction, 4);
-  }
-
-/* PCMPEQB/W/D xmm1, xmm2/m128 */
-instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
-instruction[3] = 0xc0 | (0 << 3) | 2;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (load_twice)
-  {
-  instruction[3] = 0xc0 | (1 << 3) | 3;
-  sljit_emit_op_custom(compiler, instruction, 4);
-  }
+load_from_mem_sse2(compiler, data_ind, str_ptr_ind);
+fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
 
 /* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
 instruction[2] = 0xd7;
 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
 sljit_emit_op_custom(compiler, instruction, 4);
 
-if (load_twice)
-  {
-  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0);
-  instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
-  sljit_emit_op_custom(compiler, instruction, 4);
-
-  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-  OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0);
-  }
-
-OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
 
 /* BSF r32, r/m32 */
 instruction[0] = 0x0f;
 instruction[1] = 0xbc;
 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
 sljit_emit_op_custom(compiler, instruction, 3);
+sljit_set_current_flags(compiler, SLJIT_SET_Z);
 
-nomatch = JUMP(SLJIT_ZERO);
+quit = JUMP(SLJIT_NOT_ZERO);
 
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-quit[1] = JUMP(SLJIT_JUMP);
-
-JUMPHERE(nomatch);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
 
 start = LABEL();
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-quit[2] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+  add_jump(compiler, &common->failed_match, partial_quit[1]);
 
 /* Second part (aligned) */
 
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-
-/* MOVDQA xmm1, xmm2/m128 */
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-
-if (str_ptr_ind < 8)
-  {
-  instruction[2] = 0x6f;
-  instruction[3] = (0 << 3) | str_ptr_ind;
-  sljit_emit_op_custom(compiler, instruction, 4);
-
-  if (load_twice)
-    {
-    instruction[3] = (1 << 3) | str_ptr_ind;
-    sljit_emit_op_custom(compiler, instruction, 4);
-    }
-  }
-else
-  {
-  instruction[1] = 0x41;
-  instruction[2] = 0x0f;
-  instruction[3] = 0x6f;
-  instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
-  sljit_emit_op_custom(compiler, instruction, 5);
-
-  if (load_twice)
-    {
-    instruction[4] = (1 << 3) | str_ptr_ind;
-    sljit_emit_op_custom(compiler, instruction, 5);
-    }
-  instruction[1] = 0x0f;
-  }
-
-#else
-
-instruction[2] = 0x6f;
-instruction[3] = (0 << 3) | str_ptr_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (load_twice)
-  {
-  instruction[3] = (1 << 3) | str_ptr_ind;
-  sljit_emit_op_custom(compiler, instruction, 4);
-  }
-
-#endif
-
-if (bit != 0)
-  {
-  /* POR xmm1, xmm2/m128 */
-  instruction[2] = 0xeb;
-  instruction[3] = 0xc0 | (0 << 3) | 3;
-  sljit_emit_op_custom(compiler, instruction, 4);
-  }
-
-/* PCMPEQB/W/D xmm1, xmm2/m128 */
-instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
-instruction[3] = 0xc0 | (0 << 3) | 2;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (load_twice)
-  {
-  instruction[3] = 0xc0 | (1 << 3) | 3;
-  sljit_emit_op_custom(compiler, instruction, 4);
-  }
+load_from_mem_sse2(compiler, 0, str_ptr_ind);
+fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
 
 /* PMOVMSKB reg, xmm */
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
 instruction[2] = 0xd7;
 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
 sljit_emit_op_custom(compiler, instruction, 4);
 
-if (load_twice)
-  {
-  instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
-  sljit_emit_op_custom(compiler, instruction, 4);
-
-  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-  }
-
 /* BSF r32, r/m32 */
 instruction[0] = 0x0f;
 instruction[1] = 0xbc;
 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
 sljit_emit_op_custom(compiler, instruction, 3);
+sljit_set_current_flags(compiler, SLJIT_SET_Z);
 
 JUMPTO(SLJIT_ZERO, start);
 
+JUMPHERE(quit);
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
 
-start = LABEL();
-SET_LABEL(quit[0], start);
-SET_LABEL(quit[1], start);
-SET_LABEL(quit[2], start);
+if (common->mode != PCRE2_JIT_COMPLETE)
+  {
+  JUMPHERE(partial_quit[0]);
+  JUMPHERE(partial_quit[1]);
+  OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
+  CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
+  }
+else
+  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf && offset > 0)
+  {
+  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
+
+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
+
+  quit = jump_if_utf_char_start(compiler, TMP1);
+
+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+  add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+  OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+  JUMPTO(SLJIT_JUMP, restart);
+
+  JUMPHERE(quit);
+  }
+#endif
 }
 
+#ifndef _WIN64
+
+static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_sse2_offset(void)
+{
+#if PCRE2_CODE_UNIT_WIDTH == 8
+return 15;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+return 7;
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+return 3;
+#else
+#error "Unsupported unit width"
+#endif
+}
+
+static void fast_forward_char_pair_sse2(compiler_common *common, sljit_s32 offs1,
+  PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
+{
+DEFINE_COMPILER;
+sljit_u32 bit1 = 0;
+sljit_u32 bit2 = 0;
+sljit_u32 diff = IN_UCHARS(offs1 - offs2);
+sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
+sljit_s32 tmp2_ind = sljit_get_register_index(TMP2);
+sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
+sljit_s32 data1_ind = 0;
+sljit_s32 data2_ind = 1;
+sljit_s32 tmp_ind = 2;
+sljit_s32 cmp1a_ind = 3;
+sljit_s32 cmp1b_ind = 4;
+sljit_s32 cmp2a_ind = 5;
+sljit_s32 cmp2b_ind = 6;
+struct sljit_label *start;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_label *restart;
+#endif
+struct sljit_jump *jump[2];
+
+sljit_u8 instruction[8];
+
+SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
+SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_sse2_offset()));
+SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1);
+
+/* Initialize. */
+if (common->match_end_ptr != 0)
+  {
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+  OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
+
+  OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
+  CMOV(SLJIT_LESS, STR_END, TMP1, 0);
+  }
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+/* MOVD xmm, r/m32 */
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+instruction[2] = 0x6e;
+
+if (char1a == char1b)
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
+else
+  {
+  bit1 = char1a ^ char1b;
+  if (is_powerof2(bit1))
+    {
+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1));
+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1));
+    }
+  else
+    {
+    bit1 = 0;
+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b));
+    }
+  }
+
+instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (char1a != char1b)
+  {
+  instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_ind;
+  sljit_emit_op_custom(compiler, instruction, 4);
+  }
+
+if (char2a == char2b)
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
+else
+  {
+  bit2 = char2a ^ char2b;
+  if (is_powerof2(bit2))
+    {
+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2));
+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2));
+    }
+  else
+    {
+    bit2 = 0;
+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b));
+    }
+  }
+
+instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (char2a != char2b)
+  {
+  instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_ind;
+  sljit_emit_op_custom(compiler, instruction, 4);
+  }
+
+/* PSHUFD xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x70;
+instruction[4] = 0;
+
+instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+if (char1a != char1b)
+  {
+  instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind;
+  sljit_emit_op_custom(compiler, instruction, 5);
+  }
+
+instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+if (char2a != char2b)
+  {
+  instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind;
+  sljit_emit_op_custom(compiler, instruction, 5);
+  }
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+restart = LABEL();
+#endif
+
+OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1 - offs2));
+OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, ~0xf);
+
+load_from_mem_sse2(compiler, data1_ind, str_ptr_ind);
+
+jump[0] = CMP(SLJIT_EQUAL, STR_PTR, 0, TMP1, 0);
+
+load_from_mem_sse2(compiler, data2_ind, tmp1_ind);
+
+/* MOVDQA xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x6f;
+instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PSLLDQ xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x73;
+instruction[3] = 0xc0 | (7 << 3) | tmp_ind;
+instruction[4] = diff;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+/* PSRLDQ xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+/* instruction[2] = 0x73; */
+instruction[3] = 0xc0 | (3 << 3) | data2_ind;
+instruction[4] = 16 - diff;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+/* POR xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xeb;
+instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+jump[1] = JUMP(SLJIT_JUMP);
+
+JUMPHERE(jump[0]);
+
+/* MOVDQA xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x6f;
+instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PSLLDQ xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x73;
+instruction[3] = 0xc0 | (7 << 3) | data2_ind;
+instruction[4] = diff;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+JUMPHERE(jump[1]);
+
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
+
+fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind);
+fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind);
+
+/* PAND xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xdb;
+instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* Ignore matches before the first STR_PTR. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+/* BSF r32, r/m32 */
+instruction[0] = 0x0f;
+instruction[1] = 0xbc;
+instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
+sljit_emit_op_custom(compiler, instruction, 3);
+sljit_set_current_flags(compiler, SLJIT_SET_Z);
+
+jump[0] = JUMP(SLJIT_NOT_ZERO);
+
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+/* Main loop. */
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+
+start = LABEL();
+
+load_from_mem_sse2(compiler, data2_ind, str_ptr_ind);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+load_from_mem_sse2(compiler, data1_ind, str_ptr_ind);
+
+/* PSRLDQ xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x73;
+instruction[3] = 0xc0 | (3 << 3) | data2_ind;
+instruction[4] = 16 - diff;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+/* MOVDQA xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x6f;
+instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PSLLDQ xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x73;
+instruction[3] = 0xc0 | (7 << 3) | tmp_ind;
+instruction[4] = diff;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+/* POR xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xeb;
+instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind);
+fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind);
+
+/* PAND xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xdb;
+instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* BSF r32, r/m32 */
+instruction[0] = 0x0f;
+instruction[1] = 0xbc;
+instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
+sljit_emit_op_custom(compiler, instruction, 3);
+sljit_set_current_flags(compiler, SLJIT_SET_Z);
+
+JUMPTO(SLJIT_ZERO, start);
+
+JUMPHERE(jump[0]);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+if (common->match_end_ptr != 0)
+  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf)
+  {
+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));
+
+  jump[0] = jump_if_utf_char_start(compiler, TMP1);
+
+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+  CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);
+
+  add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));
+
+  JUMPHERE(jump[0]);
+  }
+#endif
+
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
+
+if (common->match_end_ptr != 0)
+  OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+}
+
+static BOOL check_fast_forward_char_pair_sse2(compiler_common *common, fast_forward_char_data *chars, int max)
+{
+sljit_s32 i, j, priority, count;
+sljit_u32 priorities;
+PCRE2_UCHAR a1, a2, b1, b2;
+
+priorities = 0;
+
+count = 0;
+for (i = 0; i < max; i++)
+  {
+  if (chars[i].last_count > 2)
+    {
+    SLJIT_ASSERT(chars[i].last_count <= 7);
+
+    priorities |= (1 << chars[i].last_count);
+    count++;
+    }
+  }
+
+if (count < 2)
+  return FALSE;
+
+for (priority = 7; priority > 2; priority--)
+  {
+  if ((priorities & (1 << priority)) == 0)
+    continue;
+
+  for (i = max - 1; i >= 1; i--)
+    if (chars[i].last_count >= priority)
+      {
+      SLJIT_ASSERT(chars[i].count <= 2 && chars[i].count >= 1);
+
+      a1 = chars[i].chars[0];
+      a2 = chars[i].chars[1];
+
+      j = i - max_fast_forward_char_pair_sse2_offset();
+      if (j < 0)
+        j = 0;
+
+      while (j < i)
+        {
+        if (chars[j].last_count >= priority)
+          {
+          b1 = chars[j].chars[0];
+          b2 = chars[j].chars[1];
+
+          if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2)
+            {
+            fast_forward_char_pair_sse2(common, i, a1, a2, j, b1, b2);
+            return TRUE;
+            }
+          }
+        j++;
+        }
+      }
+  }
+
+return FALSE;
+}
+
+#endif
+
 #undef SSE2_COMPARE_TYPE_INDEX
 
 #endif
@@ -4161,15 +4977,16 @@
 {
 DEFINE_COMPILER;
 struct sljit_label *start;
-struct sljit_jump *quit;
-struct sljit_jump *found;
+struct sljit_jump *match;
+struct sljit_jump *partial_quit;
 PCRE2_UCHAR mask;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *utf_start = NULL;
-struct sljit_jump *utf_quit = NULL;
-#endif
 BOOL has_match_end = (common->match_end_ptr != 0);
 
+SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0);
+
+if (has_match_end)
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+
 if (offset > 0)
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
 
@@ -4177,76 +4994,21 @@
   {
   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
 
-  OP2(SLJIT_ADD, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, SLJIT_IMM, IN_UCHARS(offset + 1));
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-  if (sljit_x86_is_cmov_available())
-    {
-    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_END, 0, TMP3, 0);
-    sljit_x86_emit_cmov(compiler, SLJIT_GREATER, STR_END, TMP3, 0);
-    }
-#endif
-    {
-    quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP3, 0);
-    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-    JUMPHERE(quit);
-    }
+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1));
+  OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
+  CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
   }
 
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && offset > 0)
-  utf_start = LABEL();
-#endif
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND)
 
 /* SSE2 accelerated first character search. */
 
-if (sljit_x86_is_sse2_available())
+if (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
   {
-  fast_forward_first_char2_sse2(common, char1, char2);
+  fast_forward_first_char2_sse2(common, char1, char2, offset);
 
-  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0);
-  if (common->mode == PCRE2_JIT_COMPLETE)
-    {
-    /* In complete mode, we don't need to run a match when STR_PTR == STR_END. */
-    SLJIT_ASSERT(common->forced_quit_label == NULL);
-    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
-    add_jump(compiler, &common->forced_quit, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-    if (common->utf && offset > 0)
-      {
-      SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
-
-      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
-      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if PCRE2_CODE_UNIT_WIDTH == 8
-      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
-      CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
-      CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
-#else
-#error "Unknown code width"
-#endif
-      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-      }
-#endif
-
-    if (offset > 0)
-      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
-    }
-  else if (sljit_x86_is_cmov_available())
-    {
-    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
-    sljit_x86_emit_cmov(compiler, SLJIT_GREATER_EQUAL, STR_PTR, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0);
-    }
-  else
-    {
-    quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
-    OP1(SLJIT_MOV, STR_PTR, 0, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0);
-    JUMPHERE(quit);
-    }
+  if (offset > 0)
+    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
 
   if (has_match_end)
     OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
@@ -4255,85 +5017,56 @@
 
 #endif
 
-quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-
 start = LABEL();
+
+partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+  add_jump(compiler, &common->failed_match, partial_quit);
+
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 
 if (char1 == char2)
-  found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);
+  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1, start);
 else
   {
   mask = char1 ^ char2;
   if (is_powerof2(mask))
     {
     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
-    found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask);
+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask, start);
     }
   else
     {
-    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char1);
-    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
-    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char2);
-    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-    found = JUMP(SLJIT_NOT_ZERO);
+    match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);
+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char2, start);
+    JUMPHERE(match);
     }
   }
 
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, start);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && offset > 0)
-  utf_quit = JUMP(SLJIT_JUMP);
-#endif
-
-JUMPHERE(found);
-
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
 if (common->utf && offset > 0)
   {
-  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
-  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if PCRE2_CODE_UNIT_WIDTH == 8
-  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
-  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
-  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
-#else
-#error "Unknown code width"
-#endif
-  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-  JUMPHERE(utf_quit);
+  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-(offset + 1)));
+  jumpto_if_not_utf_char_start(compiler, TMP1, start);
   }
 #endif
 
-JUMPHERE(quit);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset + 1));
+
+if (common->mode != PCRE2_JIT_COMPLETE)
+  JUMPHERE(partial_quit);
 
 if (has_match_end)
-  {
-  quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
-  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
-  if (offset > 0)
-    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
-  JUMPHERE(quit);
   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-  }
-
-if (offset > 0)
-  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
 }
 
 static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)
 {
 DEFINE_COMPILER;
 struct sljit_label *start;
-struct sljit_jump *quit;
 struct sljit_jump *match;
-/* bytes[0] represent the number of characters between 0
-and MAX_N_BYTES - 1, 255 represents any character. */
-PCRE2_UCHAR chars[MAX_N_CHARS * MAX_DIFF_CHARS];
+fast_forward_char_data chars[MAX_N_CHARS];
 sljit_s32 offset;
 PCRE2_UCHAR mask;
 PCRE2_UCHAR *char_set, *char_set_end;
@@ -4344,7 +5077,10 @@
 sljit_u32 rec_count;
 
 for (i = 0; i < MAX_N_CHARS; i++)
-  chars[i * MAX_DIFF_CHARS] = 0;
+  {
+  chars[i].count = 0;
+  chars[i].last_count = 0;
+  }
 
 rec_count = 10000;
 max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count);
@@ -4352,21 +5088,50 @@
 if (max < 1)
   return FALSE;
 
+/* Convert last_count to priority. */
+for (i = 0; i < max; i++)
+  {
+  SLJIT_ASSERT(chars[i].count > 0 && chars[i].last_count <= chars[i].count);
+
+  if (chars[i].count == 1)
+    {
+    chars[i].last_count = (chars[i].last_count == 1) ? 7 : 5;
+    /* Simplifies algorithms later. */
+    chars[i].chars[1] = chars[i].chars[0];
+    }
+  else if (chars[i].count == 2)
+    {
+    SLJIT_ASSERT(chars[i].chars[0] != chars[i].chars[1]);
+
+    if (is_powerof2(chars[i].chars[0] ^ chars[i].chars[1]))
+      chars[i].last_count = (chars[i].last_count == 2) ? 6 : 4;
+    else
+      chars[i].last_count = (chars[i].last_count == 2) ? 3 : 2;
+    }
+  else
+    chars[i].last_count = (chars[i].count == 255) ? 0 : 1;
+  }
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) && !(defined _WIN64)
+if (check_fast_forward_char_pair_sse2(common, chars, max))
+  return TRUE;
+#endif
+
 in_range = FALSE;
 /* Prevent compiler "uninitialized" warning */
 from = 0;
 range_len = 4 /* minimum length */ - 1;
 for (i = 0; i <= max; i++)
   {
-  if (in_range && (i - from) > range_len && (chars[(i - 1) * MAX_DIFF_CHARS] < 255))
+  if (in_range && (i - from) > range_len && (chars[i - 1].count < 255))
     {
     range_len = i - from;
     range_right = i - 1;
     }
 
-  if (i < max && chars[i * MAX_DIFF_CHARS] < 255)
+  if (i < max && chars[i].count < 255)
     {
-    SLJIT_ASSERT(chars[i * MAX_DIFF_CHARS] > 0);
+    SLJIT_ASSERT(chars[i].count > 0);
     if (!in_range)
       {
       in_range = TRUE;
@@ -4386,16 +5151,17 @@
 
   for (i = 0; i < range_len; i++)
     {
-    char_set = chars + ((range_right - i) * MAX_DIFF_CHARS);
-    SLJIT_ASSERT(char_set[0] > 0 && char_set[0] < 255);
-    char_set_end = char_set + char_set[0];
-    char_set++;
-    while (char_set <= char_set_end)
+    SLJIT_ASSERT(chars[range_right - i].count > 0 && chars[range_right - i].count < 255);
+
+    char_set = chars[range_right - i].chars;
+    char_set_end = char_set + chars[range_right - i].count;
+    do
       {
       if (update_table[(*char_set) & 0xff] > IN_UCHARS(i))
         update_table[(*char_set) & 0xff] = IN_UCHARS(i);
       char_set++;
       }
+    while (char_set < char_set_end);
     }
   }
 
@@ -4403,54 +5169,38 @@
 /* Scan forward. */
 for (i = 0; i < max; i++)
   {
+  if (range_right == i)
+    continue;
+
   if (offset == -1)
     {
-    if (chars[i * MAX_DIFF_CHARS] <= 2)
+    if (chars[i].last_count >= 2)
       offset = i;
     }
-  else if (chars[offset * MAX_DIFF_CHARS] == 2 && chars[i * MAX_DIFF_CHARS] <= 2)
-    {
-    if (chars[i * MAX_DIFF_CHARS] == 1)
-      offset = i;
-    else
-      {
-      mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2];
-      if (!is_powerof2(mask))
-        {
-        mask = chars[i * MAX_DIFF_CHARS + 1] ^ chars[i * MAX_DIFF_CHARS + 2];
-        if (is_powerof2(mask))
-          offset = i;
-        }
-      }
-    }
+  else if (chars[offset].last_count < chars[i].last_count)
+    offset = i;
   }
 
+SLJIT_ASSERT(offset == -1 || (chars[offset].count >= 1 && chars[offset].count <= 2));
+
 if (range_right < 0)
   {
   if (offset < 0)
     return FALSE;
-  SLJIT_ASSERT(chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2);
   /* Works regardless the value is 1 or 2. */
-  mask = chars[offset * MAX_DIFF_CHARS + chars[offset * MAX_DIFF_CHARS]];
-  fast_forward_first_char2(common, chars[offset * MAX_DIFF_CHARS + 1], mask, offset);
+  fast_forward_first_char2(common, chars[offset].chars[0], chars[offset].chars[1], offset);
   return TRUE;
   }
 
-if (range_right == offset)
-  offset = -1;
+SLJIT_ASSERT(range_right != offset);
 
-SLJIT_ASSERT(offset == -1 || (chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2));
-
-max -= 1;
-SLJIT_ASSERT(max > 0);
 if (common->match_end_ptr != 0)
   {
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
   OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
-  quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0);
-  OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
-  JUMPHERE(quit);
+  OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
+  CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
   }
 else
   OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
@@ -4462,7 +5212,7 @@
 #endif
 
 start = LABEL();
-quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
 
 #if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
@@ -4483,20 +5233,20 @@
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset));
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 
-  if (chars[offset * MAX_DIFF_CHARS] == 1)
-    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1], start);
+  if (chars[offset].count == 1)
+    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0], start);
   else
     {
-    mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2];
+    mask = chars[offset].chars[0] ^ chars[offset].chars[1];
     if (is_powerof2(mask))
       {
       OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
-      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1] | mask, start);
+      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0] | mask, start);
       }
     else
       {
-      match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1]);
-      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 2], start);
+      match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0]);
+      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[1], start);
       JUMPHERE(match);
       }
     }
@@ -4512,15 +5262,9 @@
     }
   else
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
-#if PCRE2_CODE_UNIT_WIDTH == 8
-  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
-  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, start);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
-  CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, start);
-#else
-#error "Unknown code width"
-#endif
+
+  jumpto_if_not_utf_char_start(compiler, TMP1, start);
+
   if (offset < 0)
     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
   }
@@ -4529,33 +5273,20 @@
 if (offset >= 0)
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 
-JUMPHERE(quit);
-
 if (common->match_end_ptr != 0)
-  {
-  if (range_right >= 0)
-    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-  if (range_right >= 0)
-    {
-    quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
-    OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
-    JUMPHERE(quit);
-    }
-  }
 else
   OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
 return TRUE;
 }
 
-#undef MAX_N_CHARS
-
-static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, PCRE2_UCHAR first_char, BOOL caseless)
+static SLJIT_INLINE void fast_forward_first_char(compiler_common *common)
 {
+PCRE2_UCHAR first_char = (PCRE2_UCHAR)(common->re->first_codeunit);
 PCRE2_UCHAR oc;
 
 oc = first_char;
-if (caseless)
+if ((common->re->flags & PCRE2_FIRSTCASELESS) != 0)
   {
   oc = TABLE_GET(first_char, common->fcc, first_char);
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
@@ -4593,8 +5324,8 @@
   firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
 
   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
-  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
-  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
 #endif
@@ -4638,8 +5369,8 @@
   JUMPHERE(foundcr);
   notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
-  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, 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
@@ -4654,79 +5385,75 @@
   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
 }
 
-static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
+static BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
 
-static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_u8 *start_bits)
+static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common)
 {
 DEFINE_COMPILER;
+const sljit_u8 *start_bits = common->re->start_bitmap;
 struct sljit_label *start;
-struct sljit_jump *quit;
-struct sljit_jump *found = NULL;
-jump_list *matches = NULL;
+struct sljit_jump *partial_quit;
 #if PCRE2_CODE_UNIT_WIDTH != 8
-struct sljit_jump *jump;
+struct sljit_jump *found = NULL;
 #endif
+jump_list *matches = NULL;
 
 if (common->match_end_ptr != 0)
   {
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
   OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
-  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+  OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
+  CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
   }
 
 start = LABEL();
-quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-#ifdef SUPPORT_UNICODE
-if (common->utf)
-  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-#endif
 
-if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))
+partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+  add_jump(compiler, &common->failed_match, partial_quit);
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+if (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0, FALSE, &matches))
   {
 #if PCRE2_CODE_UNIT_WIDTH != 8
-  jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255);
-  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
-  JUMPHERE(jump);
+  if ((start_bits[31] & 0x80) != 0)
+    found = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255);
+  else
+    CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255, start);
+#elif defined SUPPORT_UNICODE
+  if (common->utf && is_char7_bitset(start_bits, FALSE))
+    CMPTO(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 127, start);
 #endif
   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)start_bits);
-  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
-  found = JUMP(SLJIT_NOT_ZERO);
+  if (sljit_get_register_index(TMP3) >= 0)
+    {
+    OP2(SLJIT_SHL, TMP3, 0, SLJIT_IMM, 1, TMP2, 0);
+    OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP3, 0);
+    }
+  else
+    {
+    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+    OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+    }
+  JUMPTO(SLJIT_ZERO, start);
   }
+else
+  set_jumps(matches, start);
 
-#ifdef SUPPORT_UNICODE
-if (common->utf)
-  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-#endif
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-if (common->utf)
-  {
-  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
-  OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
-  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-  }
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-if (common->utf)
-  {
-  CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
-  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-  OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
-  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
-  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-  }
-#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
-#endif /* SUPPORT_UNICODE */
-JUMPTO(SLJIT_JUMP, start);
+#if PCRE2_CODE_UNIT_WIDTH != 8
 if (found != NULL)
   JUMPHERE(found);
-if (matches != NULL)
-  set_jumps(matches, LABEL());
-JUMPHERE(quit);
+#endif
+
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+if (common->mode != PCRE2_JIT_COMPLETE)
+  JUMPHERE(partial_quit);
 
 if (common->match_end_ptr != 0)
   OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
@@ -4802,31 +5529,50 @@
 struct sljit_label *mainloop;
 
 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
-GET_LOCAL_BASE(TMP3, 0, 0);
+GET_LOCAL_BASE(TMP1, 0, 0);
 
 /* Drop frames until we reach STACK_TOP. */
 mainloop = LABEL();
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
-OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
-jump = JUMP(SLJIT_SIG_LESS_EQUAL);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -sizeof(sljit_sw));
+jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0);
 
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
+if (sljit_get_register_index (TMP3) < 0)
+  {
+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(STACK_TOP), -(3 * sizeof(sljit_sw)));
+  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
+  }
+else
+  {
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
+  OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(3 * sizeof(sljit_sw)));
+  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
+  GET_LOCAL_BASE(TMP1, 0, 0);
+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP3, 0);
+  }
 JUMPTO(SLJIT_JUMP, mainloop);
 
 JUMPHERE(jump);
-jump = JUMP(SLJIT_SIG_LESS);
-/* End of dropping frames. */
+jump = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0);
+/* End of reverting values. */
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 
 JUMPHERE(jump);
 OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
-OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
+if (sljit_get_register_index (TMP3) < 0)
+  {
+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
+  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
+  }
+else
+  {
+  OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
+  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
+  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP3, 0);
+  }
 JUMPTO(SLJIT_JUMP, mainloop);
 }
 
@@ -4859,11 +5605,11 @@
   jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
-  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
-  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
-  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
   JUMPHERE(jump);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
   }
@@ -4903,11 +5649,11 @@
   jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
-  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
-  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
-  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
   JUMPHERE(jump);
   }
 else
@@ -4935,15 +5681,15 @@
   }
 set_jumps(skipread_list, LABEL());
 
-OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+OP2(SLJIT_XOR | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
 }
 
-static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
+static BOOL optimize_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
 {
 /* May destroy TMP1. */
 DEFINE_COMPILER;
-int ranges[MAX_RANGE_SIZE];
+int ranges[MAX_CLASS_RANGE_SIZE];
 sljit_u8 bit, cbit, all;
 int i, byte, length = 0;
 
@@ -4961,7 +5707,7 @@
     cbit = (bits[byte] >> (i & 0x7)) & 0x1;
     if (cbit != bit)
       {
-      if (length >= MAX_RANGE_SIZE)
+      if (length >= MAX_CLASS_RANGE_SIZE)
         return FALSE;
       ranges[length] = i;
       length++;
@@ -4974,7 +5720,7 @@
 
 if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
   {
-  if (length >= MAX_RANGE_SIZE)
+  if (length >= MAX_CLASS_RANGE_SIZE)
     return FALSE;
   ranges[length] = 256;
   length++;
@@ -5086,11 +5832,118 @@
   return TRUE;
 
   default:
-  SLJIT_ASSERT_STOP();
+  SLJIT_UNREACHABLE();
   return FALSE;
   }
 }
 
+static BOOL optimize_class_chars(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
+{
+/* May destroy TMP1. */
+DEFINE_COMPILER;
+uint16_t char_list[MAX_CLASS_CHARS_SIZE];
+uint8_t byte;
+sljit_s32 type;
+int i, j, k, len, c;
+
+if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV))
+  return FALSE;
+
+if (invert)
+  nclass = !nclass;
+
+len = 0;
+
+for (i = 0; i < 32; i++)
+  {
+  byte = bits[i];
+
+  if (nclass)
+    byte = ~byte;
+
+  j = 0;
+  while (byte != 0)
+    {
+    if (byte & 0x1)
+      {
+      c = i * 8 + j;
+
+      k = len;
+
+      if ((c & 0x20) != 0)
+        {
+        for (k = 0; k < len; k++)
+          if (char_list[k] == c - 0x20)
+            {
+            char_list[k] |= 0x120;
+            break;
+            }
+        }
+
+      if (k == len)
+        {
+        if (len >= MAX_CLASS_CHARS_SIZE)
+          return FALSE;
+
+        char_list[len++] = (uint16_t) c;
+        }
+      }
+
+    byte >>= 1;
+    j++;
+    }
+  }
+
+i = 0;
+j = 0;
+
+if (char_list[0] == 0)
+  {
+  i++;
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0);
+  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_ZERO);
+  }
+else
+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+
+while (i < len)
+  {
+  if ((char_list[i] & 0x100) != 0)
+    j++;
+  else
+    {
+    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_list[i]);
+    CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
+    }
+  i++;
+  }
+
+if (j != 0)
+  {
+  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);
+
+  for (i = 0; i < len; i++)
+    if ((char_list[i] & 0x100) != 0)
+      {
+      j--;
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff);
+      CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
+      }
+  }
+
+type = nclass ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
+add_jump(compiler, backtracks, CMP(type, TMP2, 0, SLJIT_IMM, 0));
+return TRUE;
+}
+
+static BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
+{
+/* May destroy TMP1. */
+if (optimize_class_ranges(common, bits, nclass, invert, backtracks))
+  return TRUE;
+return optimize_class_chars(common, bits, nclass, invert, backtracks);
+}
+
 static void check_anynewline(compiler_common *common)
 {
 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
@@ -5099,22 +5952,22 @@
 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
 
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
 #if PCRE2_CODE_UNIT_WIDTH == 8
 if (common->utf)
   {
 #endif
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
 #if PCRE2_CODE_UNIT_WIDTH == 8
   }
 #endif
 #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
-OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 }
 
@@ -5125,34 +5978,34 @@
 
 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
 
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
-OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
+OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
 #if PCRE2_CODE_UNIT_WIDTH == 8
 if (common->utf)
   {
 #endif
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
-  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
-  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
+  OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
 #if PCRE2_CODE_UNIT_WIDTH == 8
   }
 #endif
 #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
-OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
 
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 }
@@ -5165,113 +6018,210 @@
 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
 
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
-OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
-OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
 #if PCRE2_CODE_UNIT_WIDTH == 8
 if (common->utf)
   {
 #endif
-  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+  OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
 #if PCRE2_CODE_UNIT_WIDTH == 8
   }
 #endif
 #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
-OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
 
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 }
 
-#define CHAR1 STR_END
-#define CHAR2 STACK_TOP
-
 static void do_casefulcmp(compiler_common *common)
 {
 DEFINE_COMPILER;
 struct sljit_jump *jump;
 struct sljit_label *label;
+int char1_reg;
+int char2_reg;
 
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+if (sljit_get_register_index(TMP3) < 0)
+  {
+  char1_reg = STR_END;
+  char2_reg = STACK_TOP;
+  }
+else
+  {
+  char1_reg = TMP3;
+  char2_reg = RETURN_ADDR;
+  }
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 
-label = LABEL();
-OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
-OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
-OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-JUMPTO(SLJIT_NOT_ZERO, label);
+if (char1_reg == STR_END)
+  {
+  OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);
+  OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);
+  }
 
-JUMPHERE(jump);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
-OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+  {
+  label = LABEL();
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+  jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
+  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);
+  }
+else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+  {
+  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+  label = LABEL();
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+  jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
+  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);
+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+  }
+else
+  {
+  label = LABEL();
+  OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
+  OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+  jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
+  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);
+  }
+
+if (char1_reg == STR_END)
+  {
+  OP1(SLJIT_MOV, char1_reg, 0, TMP3, 0);
+  OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
+  }
+
+sljit_emit_fast_return(compiler, TMP1, 0);
 }
 
-#define LCC_TABLE STACK_LIMIT
-
 static void do_caselesscmp(compiler_common *common)
 {
 DEFINE_COMPILER;
 struct sljit_jump *jump;
 struct sljit_label *label;
+int char1_reg = STR_END;
+int char2_reg;
+int lcc_table;
+int opt_type = 0;
 
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+if (sljit_get_register_index(TMP3) < 0)
+  {
+  char2_reg = STACK_TOP;
+  lcc_table = STACK_LIMIT;
+  }
+else
+  {
+  char2_reg = RETURN_ADDR;
+  lcc_table = TMP3;
+  }
+
+if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+  opt_type = 1;
+else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
+  opt_type = 2;
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
 
-OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
-OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0);
 
-label = LABEL();
-OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
-OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+if (char2_reg == STACK_TOP)
+  {
+  OP1(SLJIT_MOV, TMP3, 0, char2_reg, 0);
+  OP1(SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);
+  }
+
+OP1(SLJIT_MOV, lcc_table, 0, SLJIT_IMM, common->lcc);
+
+if (opt_type == 1)
+  {
+  label = LABEL();
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+  }
+else if (opt_type == 2)
+  {
+  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+  label = LABEL();
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+  sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+  }
+else
+  {
+  label = LABEL();
+  OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
+  OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
+  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+  }
+
 #if PCRE2_CODE_UNIT_WIDTH != 8
-jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
+jump = CMP(SLJIT_GREATER, char1_reg, 0, SLJIT_IMM, 255);
 #endif
-OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
+OP1(SLJIT_MOV_U8, char1_reg, 0, SLJIT_MEM2(lcc_table, char1_reg), 0);
 #if PCRE2_CODE_UNIT_WIDTH != 8
 JUMPHERE(jump);
-jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
+jump = CMP(SLJIT_GREATER, char2_reg, 0, SLJIT_IMM, 255);
 #endif
-OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
+OP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);
 #if PCRE2_CODE_UNIT_WIDTH != 8
 JUMPHERE(jump);
 #endif
-jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
-OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+
+if (opt_type == 0)
+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
+OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
 JUMPTO(SLJIT_NOT_ZERO, label);
 
 JUMPHERE(jump);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
-OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
 
-#undef LCC_TABLE
-#undef CHAR1
-#undef CHAR2
+if (opt_type == 2)
+  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+if (char2_reg == STACK_TOP)
+  {
+  OP1(SLJIT_MOV, char2_reg, 0, TMP3, 0);
+  OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);
+  }
+
+OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+sljit_emit_fast_return(compiler, TMP1, 0);
+}
 
 #if defined SUPPORT_UNICODE
 
-static PCRE2_SPTR SLJIT_CALL do_utf_caselesscmp(PCRE2_SPTR src1, jit_arguments *args, PCRE2_SPTR end1)
+static PCRE2_SPTR SLJIT_FUNC do_utf_caselesscmp(PCRE2_SPTR src1, PCRE2_SPTR src2, PCRE2_SPTR end1, PCRE2_SPTR end2)
 {
 /* This function would be ineffective to do in JIT level. */
 sljit_u32 c1, c2;
-PCRE2_SPTR src2 = args->startchar_ptr;
-PCRE2_SPTR end2 = args->end;
 const ucd_record *ur;
 const sljit_u32 *pp;
 
@@ -5416,7 +6366,7 @@
 #endif
 
       default:
-      SLJIT_ASSERT_STOP();
+      SLJIT_UNREACHABLE();
       break;
       }
     context->ucharptr = 0;
@@ -5591,7 +6541,7 @@
       break;
 
       default:
-      SLJIT_ASSERT_STOP();
+      SLJIT_UNREACHABLE();
       break;
       }
     cc += 2;
@@ -5609,13 +6559,13 @@
   if ((cc[-1] & XCL_MAP) != 0)
     {
     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
-    if (!check_class_ranges(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found))
+    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);
-      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+      OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
       add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
       }
 
@@ -5636,7 +6586,7 @@
 #ifdef SUPPORT_UNICODE
   charsaved = TRUE;
 #endif
-  if (!check_class_ranges(common, (const sljit_u8 *)cc, FALSE, TRUE, list))
+  if (!optimize_class(common, (const sljit_u8 *)cc, FALSE, TRUE, list))
     {
 #if PCRE2_CODE_UNIT_WIDTH == 8
     jump = NULL;
@@ -5648,7 +6598,7 @@
     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);
-    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+    OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
     add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
 
 #if PCRE2_CODE_UNIT_WIDTH == 8
@@ -5667,6 +6617,15 @@
   if (needschar && !charsaved)
     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, INVALID_UTF_CHAR);
+    JUMPHERE(jump);
+    }
+#endif
+
   OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
   OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
@@ -5758,14 +6717,14 @@
 
     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
       {
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
-      OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, 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)
       {
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, 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;
       }
@@ -5784,14 +6743,14 @@
 
     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
       {
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
-      OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, 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)
       {
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, 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;
       }
@@ -5816,12 +6775,12 @@
       break;
 
       case PT_LAMP:
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
-      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
+      OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
       break;
 
@@ -5843,33 +6802,33 @@
       case PT_SPACE:
       case PT_PXSPACE:
       SET_CHAR_OFFSET(9);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
 
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
 
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
 
       SET_TYPE_OFFSET(ucp_Zl);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
+      OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
       break;
 
       case PT_WORD:
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
       /* Fall through. */
 
       case PT_ALNUM:
       SET_TYPE_OFFSET(ucp_Ll);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
-      OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+      OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
       SET_TYPE_OFFSET(ucp_Nd);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+      OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
       break;
 
@@ -5891,8 +6850,8 @@
           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]);
           }
-        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
-        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, 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]))
@@ -5904,63 +6863,63 @@
           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]);
           }
-        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
-        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
+        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
 
-        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
-        OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, 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
         {
-        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
-        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
+        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
         }
 
       while (*other_cases != NOTACHAR)
         {
-        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
-        OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, 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:
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
-      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
-      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
 
       SET_CHAR_OFFSET(0xa0);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
-      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
       SET_CHAR_OFFSET(0);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, 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:
       /* C and Z groups are the farthest two groups. */
       SET_TYPE_OFFSET(ucp_Ll);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
+      OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
 
       jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
 
       /* In case of ucp_Cf, we overwrite the result. */
       SET_CHAR_OFFSET(0x2066);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
 
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
-      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
 
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
-      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
 
       JUMPHERE(jump);
       jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
@@ -5969,21 +6928,21 @@
       case PT_PXPRINT:
       /* C and Z groups are the farthest two groups. */
       SET_TYPE_OFFSET(ucp_Ll);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
+      OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
 
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
-      OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
+      OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_NOT_EQUAL);
 
       jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
 
       /* In case of ucp_Cf, we overwrite the result. */
       SET_CHAR_OFFSET(0x2066);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
 
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
-      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
+      OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
 
       JUMPHERE(jump);
       jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
@@ -5991,21 +6950,21 @@
 
       case PT_PXPUNCT:
       SET_TYPE_OFFSET(ucp_Sc);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
 
       SET_CHAR_OFFSET(0);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
-      OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
+      OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL);
 
       SET_TYPE_OFFSET(ucp_Pc);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
+      OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
       break;
 
       default:
-      SLJIT_ASSERT_STOP();
+      SLJIT_UNREACHABLE();
       break;
       }
     cc += 2;
@@ -6051,6 +7010,7 @@
   case OP_NOT_WORD_BOUNDARY:
   case OP_WORD_BOUNDARY:
   add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
+  sljit_set_current_flags(compiler, SLJIT_SET_Z);
   add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
   return cc;
 
@@ -6066,10 +7026,10 @@
     else
       {
       jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
-      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
-      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS);
-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
-      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
+      OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);
+      OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, 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));
@@ -6091,9 +7051,9 @@
     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));
-    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+    OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
     jump[2] = JUMP(SLJIT_GREATER);
-    add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
+    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);
@@ -6112,6 +7072,7 @@
       read_char_range(common, common->nlmin, common->nlmax, TRUE);
       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, SLJIT_MEM1(SLJIT_SP), LOCALS1);
       }
@@ -6129,8 +7090,8 @@
 
   case OP_DOLL:
   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
-  OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
-  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+  OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
 
   if (!common->endonly)
     compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);
@@ -6144,8 +7105,8 @@
   case OP_DOLLM:
   jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
-  OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
-  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+  OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
   check_partial(common, FALSE);
   jump[0] = JUMP(SLJIT_JUMP);
   JUMPHERE(jump[1]);
@@ -6182,16 +7143,16 @@
   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));
-  OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
-  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+  OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
   return cc;
 
   case OP_CIRCM:
   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
   jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0);
-  OP2(SLJIT_AND32 | SLJIT_SET_E, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
-  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
+  OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+  add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
   jump[0] = JUMP(SLJIT_JUMP);
   JUMPHERE(jump[1]);
 
@@ -6229,7 +7190,7 @@
     label = LABEL();
     add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
     skip_char_back(common);
-    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
     JUMPTO(SLJIT_NOT_ZERO, label);
     }
   else
@@ -6242,10 +7203,126 @@
   check_start_used_ptr(common);
   return cc + LINK_SIZE;
   }
-SLJIT_ASSERT_STOP();
+SLJIT_UNREACHABLE();
 return cc;
 }
 
+#ifdef SUPPORT_UNICODE
+
+#if PCRE2_CODE_UNIT_WIDTH != 32
+
+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, len, ricount;
+PCRE2_SPTR prevcc, bptr;
+uint32_t c;
+
+prevcc = cc;
+GETCHARINC(c, cc);
+lgb = UCD_GRAPHBREAK(c);
+
+while (cc < end_subject)
+  {
+  len = 1;
+  GETCHARLEN(c, cc, len);
+  rgb = UCD_GRAPHBREAK(c);
+
+  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+
+  /* Not breaking between Regional Indicators is allowed only if there
+  are an even number of preceding RIs. */
+
+  if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator)
+    {
+    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_gbRegionalIndicator) break;
+
+      ricount++;
+      }
+
+    if ((ricount & 1) != 0) break;  /* Grapheme break required */
+    }
+
+  /* If Extend follows E_Base[_GAZ] do not update lgb; this allows
+  any number of Extend before a following E_Modifier. */
+
+  if (rgb != ucp_gbExtend || (lgb != ucp_gbE_Base && lgb != ucp_gbE_Base_GAZ))
+    lgb = rgb;
+
+  prevcc = cc;
+  cc += len;
+  }
+
+return cc;
+}
+
+#endif
+
+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;
+
+GETCHARINC(c, cc);
+lgb = UCD_GRAPHBREAK(c);
+
+while (cc < end_subject)
+  {
+  c = *cc;
+  rgb = UCD_GRAPHBREAK(c);
+
+  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+
+  /* Not breaking between Regional Indicators is allowed only if there
+  are an even number of preceding RIs. */
+
+  if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator)
+    {
+    ricount = 0;
+    bptr = cc - 1;
+
+    /* bptr is pointing to the left-hand character */
+    while (bptr > start_subject)
+      {
+      bptr--;
+      c = *bptr;
+
+      if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break;
+
+      ricount++;
+      }
+
+    if ((ricount & 1) != 0) break;  /* Grapheme break required */
+    }
+
+  /* If Extend follows E_Base[_GAZ] do not update lgb; this allows
+  any number of Extend before a following E_Modifier. */
+
+  if (rgb != ucp_gbExtend || (lgb != ucp_gbE_Base && lgb != ucp_gbE_Base_GAZ))
+    lgb = rgb;
+
+  cc++;
+  }
+
+return cc;
+}
+
+#endif
+
 static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr)
 {
 DEFINE_COMPILER;
@@ -6255,7 +7332,6 @@
 struct sljit_jump *jump[3];
 jump_list *end_list;
 #ifdef SUPPORT_UNICODE
-struct sljit_label *label;
 PCRE2_UCHAR propdata[5];
 #endif /* SUPPORT_UNICODE */
 
@@ -6273,7 +7349,7 @@
 #endif
     read_char8_type(common, type == OP_NOT_DIGIT);
     /* Flip the starting bit in the negative case. */
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
+  OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
   add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
   return cc;
 
@@ -6287,7 +7363,7 @@
   else
 #endif
     read_char8_type(common, type == OP_NOT_WHITESPACE);
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
+  OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
   add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
   return cc;
 
@@ -6301,7 +7377,7 @@
   else
 #endif
     read_char8_type(common, type == OP_NOT_WORDCHAR);
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
+  OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
   add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
   return cc;
 
@@ -6343,8 +7419,8 @@
 #elif PCRE2_CODE_UNIT_WIDTH == 16
     jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
-    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
-    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
 #endif
@@ -6404,6 +7480,7 @@
     detect_partial_match(common, backtracks);
   read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
   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;
 
@@ -6413,6 +7490,7 @@
     detect_partial_match(common, backtracks);
   read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
   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;
 
@@ -6420,35 +7498,22 @@
   case OP_EXTUNI:
   if (check_str_ptr)
     detect_partial_match(common, backtracks);
-  read_char(common);
-  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
-  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
-  /* Optimize register allocation: use a real register. */
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
-  OP1(SLJIT_MOV_U8, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
 
-  label = LABEL();
-  jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-  OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
-  read_char(common);
-  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
-  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
-  OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+  SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
+  OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
 
-  OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
-  OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
-  OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
-  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
-  JUMPTO(SLJIT_NOT_ZERO, label);
+#if PCRE2_CODE_UNIT_WIDTH != 32
+  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
+      common->utf ? SLJIT_FUNC_OFFSET(do_extuni_utf) : SLJIT_FUNC_OFFSET(do_extuni_no_utf));
+#else
+  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_extuni_no_utf));
+#endif
 
-  OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
-  JUMPHERE(jump[0]);
-  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
 
   if (common->mode == PCRE2_JIT_PARTIAL_HARD)
     {
-    jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
+    jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0);
     /* Since we successfully read a char above, partial matching must occure. */
     check_partial(common, TRUE);
     JUMPHERE(jump[0]);
@@ -6582,7 +7647,7 @@
   read_char_range(common, 0, 255, type == OP_NCLASS);
 #endif
 
-  if (check_class_ranges(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks))
+  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
@@ -6609,7 +7674,7 @@
   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);
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+  OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
   add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
 
 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
@@ -6626,7 +7691,7 @@
   return cc + GET(cc, 0) - 1;
 #endif
   }
-SLJIT_ASSERT_STOP();
+SLJIT_UNREACHABLE();
 return cc;
 }
 
@@ -6781,40 +7846,42 @@
 #if defined SUPPORT_UNICODE
 if (common->utf && *cc == OP_REFI)
   {
-  SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
+  SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
   if (ref)
-    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
   else
-    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
 
   if (withchecks)
-    jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
+    jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0);
+  /* No free saved registers so save data on stack. */
 
-  /* Needed to save important temporary registers. */
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
-  OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), STR_PTR, 0);
-  sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
-  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+  OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0);
+  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
+  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+
   if (common->mode == PCRE2_JIT_COMPLETE)
     add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
   else
     {
-    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
-    nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+    OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+
+    add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
+
+    nopartial = JUMP(SLJIT_NOT_EQUAL);
+    OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
     check_partial(common, FALSE);
     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
     JUMPHERE(nopartial);
     }
-  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
   }
 else
 #endif /* SUPPORT_UNICODE */
   {
   if (ref)
-    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
   else
-    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
 
   if (withchecks)
     jump = JUMP(SLJIT_ZERO);
@@ -6905,7 +7972,7 @@
   cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
   break;
   default:
-  SLJIT_ASSERT_STOP();
+  SLJIT_UNREACHABLE();
   break;
   }
 
@@ -6919,7 +7986,7 @@
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
     /* Temporary release of STR_PTR. */
-    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
     /* Handles both invalid and empty cases. Since the minimum repeat,
     is zero the invalid case is basically the same as an empty case. */
     if (ref)
@@ -6932,7 +7999,7 @@
       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
       }
     /* Restore if not zero length. */
-    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
     }
   else
     {
@@ -7096,8 +8163,10 @@
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     return NULL;
   entry->next = NULL;
-  entry->entry = NULL;
-  entry->calls = NULL;
+  entry->entry_label = NULL;
+  entry->backtrack_label = NULL;
+  entry->entry_calls = NULL;
+  entry->backtrack_calls = NULL;
   entry->start = start;
 
   if (prev != NULL)
@@ -7106,71 +8175,74 @@
     common->entries = entry;
   }
 
-if (common->has_set_som && common->mark_ptr != 0)
-  {
-  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
-  allocate_stack(common, 2);
-  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
-  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
-  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
-  }
-else if (common->has_set_som || common->mark_ptr != 0)
-  {
-  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
-  allocate_stack(common, 1);
-  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
-  }
+BACKTRACK_AS(recurse_backtrack)->entry = entry;
 
-if (entry->entry == NULL)
-  add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
+if (entry->entry_label == NULL)
+  add_jump(compiler, &entry->entry_calls, JUMP(SLJIT_FAST_CALL));
 else
-  JUMPTO(SLJIT_FAST_CALL, entry->entry);
+  JUMPTO(SLJIT_FAST_CALL, entry->entry_label);
 /* Leave if the match is failed. */
 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
+BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL();
 return cc + 1 + LINK_SIZE;
 }
 
-static int SLJIT_CALL do_callout(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
+static sljit_s32 SLJIT_FUNC do_callout(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
 {
-PCRE2_SPTR begin = arguments->begin;
-PCRE2_SIZE *ovector = arguments->match_data->ovector;
-sljit_u32 oveccount = arguments->oveccount;
-sljit_u32 i;
+PCRE2_SPTR begin;
+PCRE2_SIZE *ovector;
+sljit_u32 oveccount, capture_top;
 
 if (arguments->callout == NULL)
   return 0;
 
-callout_block->version = 1;
+SLJIT_COMPILE_ASSERT(sizeof (PCRE2_SIZE) <= sizeof (sljit_sw), pcre2_size_must_be_lower_than_sljit_sw_size);
+
+begin = arguments->begin;
+ovector = (PCRE2_SIZE*)(callout_block + 1);
+oveccount = callout_block->capture_top;
+
+SLJIT_ASSERT(oveccount >= 1);
+
+callout_block->version = 2;
+callout_block->callout_flags = 0;
 
 /* Offsets in subject. */
 callout_block->subject_length = arguments->end - arguments->begin;
-callout_block->start_match = (PCRE2_SPTR)callout_block->subject - arguments->begin;
-callout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - arguments->begin;
+callout_block->start_match = jit_ovector[0] - begin;
+callout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - begin;
 callout_block->subject = begin;
 
 /* Convert and copy the JIT offset vector to the ovector array. */
-callout_block->capture_top = 0;
+callout_block->capture_top = 1;
 callout_block->offset_vector = ovector;
-for (i = 2; i < oveccount; i += 2)
-  {
-  ovector[i] = jit_ovector[i] - begin;
-  ovector[i + 1] = jit_ovector[i + 1] - begin;
-  if (jit_ovector[i] >= begin)
-    callout_block->capture_top = i;
-  }
 
-callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
 ovector[0] = PCRE2_UNSET;
 ovector[1] = PCRE2_UNSET;
+ovector += 2;
+jit_ovector += 2;
+capture_top = 1;
+
+/* Convert pointers to sizes. */
+while (--oveccount != 0)
+  {
+  capture_top++;
+
+  ovector[0] = (PCRE2_SIZE)(jit_ovector[0] - begin);
+  ovector[1] = (PCRE2_SIZE)(jit_ovector[1] - begin);
+
+  if (ovector[0] != PCRE2_UNSET)
+    callout_block->capture_top = capture_top;
+
+  ovector += 2;
+  jit_ovector += 2;
+  }
+
 return (arguments->callout)(callout_block, arguments->callout_data);
 }
 
-/* Aligning to 8 byte. */
-#define CALLOUT_ARG_SIZE \
-    (((int)sizeof(pcre2_callout_block) + 7) & ~7)
-
 #define CALLOUT_ARG_OFFSET(arg) \
-    (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(pcre2_callout_block, arg))
+    SLJIT_OFFSETOF(pcre2_callout_block, arg)
 
 static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
 {
@@ -7182,10 +8254,13 @@
 sljit_sw value1;
 sljit_sw value2;
 sljit_sw value3;
+sljit_uw callout_arg_size = (common->re->top_bracket + 1) * 2 * sizeof(sljit_sw);
 
 PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
 
-allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
+callout_arg_size = (sizeof(pcre2_callout_block) + callout_arg_size + sizeof(sljit_sw) - 1) / sizeof(sljit_sw);
+
+allocate_stack(common, callout_arg_size);
 
 SLJIT_ASSERT(common->capture_last_ptr != 0);
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
@@ -7193,11 +8268,10 @@
 value1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0;
 OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1);
 OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
+OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_top), SLJIT_IMM, common->re->top_bracket + 1);
 
 /* These pointer sized fields temporarly stores internal variables. */
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
 
 if (common->mark_ptr != 0)
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
@@ -7223,22 +8297,24 @@
 OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3);
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
 
+SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
+
 /* Needed to save important temporary registers. */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
-OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, 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_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
-OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
+sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+free_stack(common, callout_arg_size);
 
 /* Check return value. */
-OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
-if (common->forced_quit_label == NULL)
-  add_jump(compiler, &common->forced_quit, JUMP(SLJIT_SIG_LESS));
+OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER32));
+if (common->abort_label == NULL)
+  add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL32) /* SIG_LESS */);
 else
-  JUMPTO(SLJIT_SIG_LESS, common->forced_quit_label);
+  JUMPTO(SLJIT_NOT_EQUAL32 /* SIG_LESS */, common->abort_label);
 return cc + callout_length;
 }
 
@@ -7280,6 +8356,7 @@
 DEFINE_COMPILER;
 int framesize;
 int extrasize;
+BOOL local_quit_available = FALSE;
 BOOL needs_control_head;
 int private_data_ptr;
 backtrack_common altbacktrack;
@@ -7290,13 +8367,13 @@
 jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
 jump_list **found;
 /* Saving previous accept variables. */
-BOOL save_local_exit = common->local_exit;
-BOOL save_positive_assert = common->positive_assert;
+BOOL save_local_quit_available = common->local_quit_available;
+BOOL save_in_positive_assertion = common->in_positive_assertion;
 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;
 jump_list *save_quit = common->quit;
-jump_list *save_positive_assert_quit = common->positive_assert_quit;
+jump_list *save_positive_assertion_quit = common->positive_assertion_quit;
 jump_list *save_accept = common->accept;
 struct sljit_jump *jump;
 struct sljit_jump *brajump = NULL;
@@ -7363,7 +8440,7 @@
   allocate_stack(common, framesize + extrasize);
 
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-  OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
+  OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
   if (needs_control_head)
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
@@ -7378,21 +8455,21 @@
   else
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
 
-  init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
+  init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize);
   }
 
 memset(&altbacktrack, 0, sizeof(backtrack_common));
-if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT))
   {
-  /* Negative assert is stronger than positive assert. */
-  common->local_exit = TRUE;
+  /* Control verbs cannot escape from these asserts. */
+  local_quit_available = TRUE;
+  common->local_quit_available = TRUE;
   common->quit_label = NULL;
   common->quit = NULL;
-  common->positive_assert = FALSE;
   }
-else
-  common->positive_assert = TRUE;
-common->positive_assert_quit = NULL;
+
+common->in_positive_assertion = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK);
+common->positive_assertion_quit = NULL;
 
 while (1)
   {
@@ -7408,16 +8485,16 @@
   compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {
-    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+    if (local_quit_available)
       {
-      common->local_exit = save_local_exit;
+      common->local_quit_available = save_local_quit_available;
       common->quit_label = save_quit_label;
       common->quit = save_quit;
       }
-    common->positive_assert = save_positive_assert;
+    common->in_positive_assertion = save_in_positive_assertion;
     common->then_trap = save_then_trap;
     common->accept_label = save_accept_label;
-    common->positive_assert_quit = save_positive_assert_quit;
+    common->positive_assertion_quit = save_positive_assertion_quit;
     common->accept = save_accept;
     return NULL;
     }
@@ -7434,23 +8511,24 @@
       free_stack(common, extrasize);
 
     if (needs_control_head)
-      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
     }
   else
     {
     if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
       {
       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
-      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
       if (needs_control_head)
-        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
       }
     else
       {
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
       if (needs_control_head)
-        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
+        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 2));
       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));
       }
     }
 
@@ -7460,25 +8538,25 @@
     if (conditional)
       {
       if (extrasize > 0)
-        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
+        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? STACK(-2) : STACK(-1));
       }
     else if (bra == OP_BRAZERO)
       {
       if (framesize < 0)
-        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
+        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));
       else
         {
-        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
-        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
+        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));
+        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - extrasize));
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
         }
-      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
       }
     else if (framesize >= 0)
       {
       /* For OP_BRA and OP_BRAMINZERO. */
-      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));
       }
     }
   add_jump(compiler, found, JUMP(SLJIT_JUMP));
@@ -7486,16 +8564,16 @@
   compile_backtrackingpath(common, altbacktrack.top);
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {
-    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+    if (local_quit_available)
       {
-      common->local_exit = save_local_exit;
+      common->local_quit_available = save_local_quit_available;
       common->quit_label = save_quit_label;
       common->quit = save_quit;
       }
-    common->positive_assert = save_positive_assert;
+    common->in_positive_assertion = save_in_positive_assertion;
     common->then_trap = save_then_trap;
     common->accept_label = save_accept_label;
-    common->positive_assert_quit = save_positive_assert_quit;
+    common->positive_assertion_quit = save_positive_assertion_quit;
     common->accept = save_accept;
     return NULL;
     }
@@ -7508,26 +8586,26 @@
   cc += GET(cc, 1);
   }
 
-if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+if (local_quit_available)
   {
-  SLJIT_ASSERT(common->positive_assert_quit == NULL);
+  SLJIT_ASSERT(common->positive_assertion_quit == NULL);
   /* Makes the check less complicated below. */
-  common->positive_assert_quit = common->quit;
+  common->positive_assertion_quit = common->quit;
   }
 
 /* None of them matched. */
-if (common->positive_assert_quit != NULL)
+if (common->positive_assertion_quit != NULL)
   {
   jump = JUMP(SLJIT_JUMP);
-  set_jumps(common->positive_assert_quit, LABEL());
+  set_jumps(common->positive_assertion_quit, LABEL());
   SLJIT_ASSERT(framesize != no_stack);
   if (framesize < 0)
-    OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
+    OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
   else
     {
     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 + extrasize) * sizeof(sljit_sw));
+    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (extrasize + 1) * sizeof(sljit_sw));
     }
   JUMPHERE(jump);
   }
@@ -7576,18 +8654,18 @@
     {
     /* We know that STR_PTR was stored on the top of the stack. */
     if (extrasize > 0)
-      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));
 
     /* Keep the STR_PTR on the top of the stack. */
     if (bra == OP_BRAZERO)
       {
-      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
       if (extrasize == 2)
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
       }
     else if (bra == OP_BRAMINZERO)
       {
-      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
       }
     }
@@ -7596,13 +8674,13 @@
     if (bra == OP_BRA)
       {
       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
-      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
-      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 1));
       }
     else
       {
       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
-      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
       if (extrasize == 2)
         {
         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
@@ -7630,7 +8708,9 @@
       {
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
-      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
+      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));
+      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
       }
     set_jumps(backtrack->common.topbacktracks, LABEL());
     }
@@ -7683,16 +8763,16 @@
     }
   }
 
-if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+if (local_quit_available)
   {
-  common->local_exit = save_local_exit;
+  common->local_quit_available = save_local_quit_available;
   common->quit_label = save_quit_label;
   common->quit = save_quit;
   }
-common->positive_assert = save_positive_assert;
+common->in_positive_assertion = save_in_positive_assertion;
 common->then_trap = save_then_trap;
 common->accept_label = save_accept_label;
-common->positive_assert_quit = save_positive_assert_quit;
+common->positive_assertion_quit = save_positive_assertion_quit;
 common->accept = save_accept;
 return cc + 1 + LINK_SIZE;
 }
@@ -7717,23 +8797,23 @@
     }
 
   if (needs_control_head)
-    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? STACK(-2) : STACK(-1));
 
   /* TMP2 which is set here used by OP_KETRMAX below. */
   if (ket == OP_KETRMAX)
-    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
   else if (ket == OP_KETRMIN)
     {
     /* Move the STR_PTR to the private_data_ptr. */
-    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
     }
   }
 else
   {
   stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
-  OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
+  OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
   if (needs_control_head)
-    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
+    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
 
   if (ket == OP_KETRMAX)
     {
@@ -7820,7 +8900,6 @@
   (|)     OP_*BRA    | OP_ALT ...         M A
   (?()|)  OP_*COND   | OP_ALT             M A
   (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
-  (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
                                           Or nothing, if trace is unnecessary
 */
 
@@ -7888,8 +8967,6 @@
 
 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
   opcode = OP_SCOND;
-if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
-  opcode = OP_ONCE;
 
 if (opcode == OP_CBRA || opcode == OP_SCBRA)
   {
@@ -7966,7 +9043,7 @@
         {
         /* Except when the whole stack frame must be saved. */
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-        braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
+        braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-BACKTRACK_AS(bracket_backtrack)->u.framesize - 2));
         }
       JUMPHERE(skip);
       }
@@ -8039,7 +9116,7 @@
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
       if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
-        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
+        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
       }
     else if (ket == OP_KETRMAX || has_alternatives)
@@ -8057,7 +9134,7 @@
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
 
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
+    OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
 
     stacksize = needs_control_head ? 1 : 0;
     if (ket != OP_KET || has_alternatives)
@@ -8072,7 +9149,7 @@
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
       }
-    init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
+    init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1);
     }
   }
 else if (opcode == OP_CBRA || opcode == OP_SCBRA)
@@ -8129,13 +9206,13 @@
     slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
     OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
-    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
     slot += common->name_entry_size;
     i--;
     while (i-- > 0)
       {
       OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
-      OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
+      OP2(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, STR_PTR, 0);
       slot += common->name_entry_size;
       }
     OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
@@ -8288,7 +9365,7 @@
     {
     if (has_alternatives)
       BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
-    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
     JUMPTO(SLJIT_NOT_ZERO, rmax_label);
     /* Drop STR_PTR for greedy plus quantifier. */
     if (opcode != OP_ONCE)
@@ -8318,7 +9395,7 @@
 if (repeat_type == OP_EXACT)
   {
   count_match(common);
-  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
   JUMPTO(SLJIT_NOT_ZERO, rmax_label);
   }
 else if (repeat_type == OP_UPTO)
@@ -8346,6 +9423,7 @@
       {
       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));
       }
     else if (ket == OP_KETRMIN && opcode != OP_ONCE)
       free_stack(common, 1);
@@ -8418,7 +9496,7 @@
   break;
 
   default:
-  SLJIT_ASSERT_STOP();
+  SLJIT_UNREACHABLE();
   break;
   }
 
@@ -8496,7 +9574,7 @@
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
   if (needs_control_head)
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
-  OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
+  OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
 
   stack = 0;
   if (!zero)
@@ -8515,7 +9593,7 @@
     stack++;
     }
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
-  init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
+  init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize);
   stack -= 1 + (offset == 0);
   }
 
@@ -8568,7 +9646,7 @@
     {
     if (offset != 0)
       {
-      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
@@ -8579,10 +9657,10 @@
     else
       {
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-      OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
+      OP2(SLJIT_SUB, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
       if (opcode == OP_SBRAPOS)
-        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
-      OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
+        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));
+      OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(-framesize - 2), STR_PTR, 0);
       }
 
     /* Even if the match is empty, we need to reset the control head. */
@@ -8628,7 +9706,7 @@
     else
       {
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
+      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));
       }
     }
 
@@ -8645,7 +9723,7 @@
   if (framesize < 0)
     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
   else /* TMP2 is set to [private_data_ptr] above. */
-    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0));
+    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0));
   }
 
 /* None of them matched. */
@@ -8868,7 +9946,7 @@
     OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
     label = LABEL();
     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
-    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
     JUMPTO(SLJIT_NOT_ZERO, label);
     }
   else
@@ -8876,7 +9954,7 @@
     OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
     label = LABEL();
     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
-    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
     JUMPTO(SLJIT_NOT_ZERO, label);
     }
   }
@@ -8906,7 +9984,7 @@
     if (opcode == OP_UPTO)
       {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
-      OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+      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);
       }
@@ -8968,7 +10046,7 @@
       label = LABEL();
       if (opcode == OP_UPTO)
         {
-        OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
         add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
         }
       compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
@@ -8988,7 +10066,7 @@
       OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
       if (opcode == OP_UPTO)
         {
-        OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+        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));
         }
 
@@ -9015,7 +10093,7 @@
 
       if (opcode == OP_UPTO)
         {
-        OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
         JUMPTO(SLJIT_NOT_ZERO, label);
         }
       else
@@ -9044,7 +10122,7 @@
 
       if (opcode == OP_UPTO)
         {
-        OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
         JUMPTO(SLJIT_NOT_ZERO, label);
         }
       else
@@ -9070,7 +10148,7 @@
       compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
       if (opcode == OP_UPTO)
         {
-        OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+        OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
         JUMPTO(SLJIT_NOT_ZERO, label);
         OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
         }
@@ -9157,7 +10235,7 @@
     label = LABEL();
     compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
-    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+    OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
     JUMPTO(SLJIT_NOT_ZERO, label);
     set_jumps(no_match, LABEL());
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
@@ -9168,7 +10246,7 @@
   label = LABEL();
   detect_partial_match(common, &no_match);
   compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
-  OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+  OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
   JUMPTO(SLJIT_NOT_ZERO, label);
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
   set_jumps(no_char1_match, LABEL());
@@ -9186,7 +10264,7 @@
   break;
 
   default:
-  SLJIT_ASSERT_STOP();
+  SLJIT_UNREACHABLE();
   break;
   }
 
@@ -9207,6 +10285,9 @@
   return cc + 1;
   }
 
+if (*cc == OP_ACCEPT && common->currententry == NULL && (common->re->overall_options & PCRE2_ENDANCHORED) != 0)
+  add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+
 if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
   {
   /* No need to check notempty conditions. */
@@ -9223,9 +10304,9 @@
   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);
 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
 OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO));
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
+OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
 if (common->accept_label == NULL)
   add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO));
 else
@@ -9309,7 +10390,7 @@
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
 allocate_stack(common, size);
 if (size > 3)
-  OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
+  OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
 else
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
@@ -9318,7 +10399,7 @@
 
 size = BACKTRACK_AS(then_trap_backtrack)->framesize;
 if (size >= 0)
-  init_frame(common, cc, ccend, size - 1, 0, FALSE);
+  init_frame(common, cc, ccend, size - 1, 0);
 }
 
 static void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)
@@ -9540,7 +10621,6 @@
     break;
 
     case OP_ONCE:
-    case OP_ONCE_NC:
     case OP_BRA:
     case OP_CBRA:
     case OP_COND:
@@ -9615,7 +10695,7 @@
     break;
 
     default:
-    SLJIT_ASSERT_STOP();
+    SLJIT_UNREACHABLE();
     return;
     }
   if (cc == NULL)
@@ -9723,7 +10803,7 @@
   case OP_MINUPTO:
   OP1(SLJIT_MOV, TMP1, 0, base, offset1);
   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
-  OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+  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);
@@ -9769,7 +10849,7 @@
   break;
 
   default:
-  SLJIT_ASSERT_STOP();
+  SLJIT_UNREACHABLE();
   break;
   }
 
@@ -9804,27 +10884,21 @@
 static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
 {
 DEFINE_COMPILER;
+recurse_entry *entry;
 
-if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
+if (!CURRENT_AS(recurse_backtrack)->inlined_pattern)
+  {
+  entry = CURRENT_AS(recurse_backtrack)->entry;
+  if (entry->backtrack_label == NULL)
+    add_jump(compiler, &entry->backtrack_calls, JUMP(SLJIT_FAST_CALL));
+  else
+    JUMPTO(SLJIT_FAST_CALL, entry->backtrack_label);
+  CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(recurse_backtrack)->matchingpath);
+  }
+else
   compile_backtrackingpath(common, current->top);
-set_jumps(current->topbacktracks, LABEL());
-if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
-  return;
 
-if (common->has_set_som && common->mark_ptr != 0)
-  {
-  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
-  free_stack(common, 2);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP2, 0);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
-  }
-else if (common->has_set_som || common->mark_ptr != 0)
-  {
-  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
-  free_stack(common, 1);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
-  }
+set_jumps(current->topbacktracks, LABEL());
 }
 
 static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
@@ -9877,7 +10951,9 @@
   {
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr);
   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw));
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
+  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(assert_backtrack)->framesize - 1) * sizeof(sljit_sw));
+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, TMP1, 0);
 
   set_jumps(current->topbacktracks, LABEL());
   }
@@ -9887,7 +10963,7 @@
 if (bra == OP_BRAZERO)
   {
   /* We know there is enough place on the stack. */
-  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
   JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
   JUMPHERE(brajump);
@@ -9947,8 +11023,6 @@
   offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
   opcode = OP_SCOND;
-if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
-  opcode = OP_ONCE;
 
 alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
 
@@ -10000,7 +11074,7 @@
       else
         {
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
-        CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
+        CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 2), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
         }
       /* Drop STR_PTR for non-greedy plus quantifier. */
       if (opcode != OP_ONCE)
@@ -10054,6 +11128,7 @@
     {
     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));
     }
   once = JUMP(SLJIT_JUMP);
   }
@@ -10106,7 +11181,9 @@
       {
       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, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
+      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);
       }
     cond = JUMP(SLJIT_JUMP);
     set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
@@ -10247,7 +11324,9 @@
       {
       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, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
+      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);
     }
@@ -10302,7 +11381,7 @@
   JUMPHERE(once);
   /* Restore previous private_data_ptr */
   if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
-    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw));
+    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 1));
   else if (ket == OP_KETRMIN)
     {
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
@@ -10383,6 +11462,7 @@
 
 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->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(bracketpos_backtrack)->framesize - 1) * sizeof(sljit_sw));
 
 if (current->topbacktracks)
   {
@@ -10392,7 +11472,7 @@
   free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
   JUMPHERE(jump);
   }
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracketpos_backtrack)->framesize - 1));
 }
 
 static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
@@ -10438,22 +11518,23 @@
     jump = JUMP(SLJIT_JUMP);
 
     loop = LABEL();
-    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
+    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
     JUMPHERE(jump);
-    CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
-    CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
+    CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, loop);
+    CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0, loop);
     add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
     return;
     }
-  else if (common->positive_assert)
+  else if (!common->local_quit_available && common->in_positive_assertion)
     {
-    add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
+    add_jump(compiler, &common->positive_assertion_quit, JUMP(SLJIT_JUMP));
     return;
     }
   }
 
-if (common->local_exit)
+if (common->local_quit_available)
   {
+  /* Abort match with a fail. */
   if (common->quit_label == NULL)
     add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
   else
@@ -10463,15 +11544,13 @@
 
 if (opcode == OP_SKIP_ARG)
   {
-  SLJIT_ASSERT(common->control_head_ptr != 0);
+  SLJIT_ASSERT(common->control_head_ptr != 0 && TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
-  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
-  sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
-  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+  OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
+  sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
 
-  OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
-  add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
+  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;
   }
 
@@ -10504,7 +11583,10 @@
 set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
 /* STACK_TOP is set by THEN. */
 if (CURRENT_AS(then_trap_backtrack)->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));
+  }
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
 free_stack(common, 3);
 
@@ -10621,7 +11703,6 @@
     break;
 
     case OP_ONCE:
-    case OP_ONCE_NC:
     case OP_BRA:
     case OP_CBRA:
     case OP_COND:
@@ -10670,7 +11751,7 @@
     break;
 
     case OP_COMMIT:
-    if (!common->local_exit)
+    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));
@@ -10692,7 +11773,7 @@
     break;
 
     default:
-    SLJIT_ASSERT_STOP();
+    SLJIT_UNREACHABLE();
     break;
     }
   current = current->prev;
@@ -10707,38 +11788,52 @@
 PCRE2_SPTR ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
 PCRE2_SPTR ccend = bracketend(cc) - (1 + LINK_SIZE);
 BOOL needs_control_head;
-int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
-int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
-int alternativesize;
-BOOL needs_frame;
+BOOL has_quit;
+BOOL has_accept;
+int private_data_size = get_recurse_data_length(common, ccbegin, ccend, &needs_control_head, &has_quit, &has_accept);
+int alt_count, alt_max, local_size;
 backtrack_common altbacktrack;
-struct sljit_jump *jump;
+jump_list *match = NULL;
+sljit_uw *next_update_addr = NULL;
+struct sljit_jump *alt1 = NULL;
+struct sljit_jump *alt2 = NULL;
+struct sljit_jump *accept_exit = NULL;
+struct sljit_label *quit;
 
 /* Recurse captures then. */
 common->then_trap = NULL;
 
 SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
-needs_frame = framesize >= 0;
-if (!needs_frame)
-  framesize = 0;
-alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
 
-SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
-common->currententry->entry = LABEL();
-set_jumps(common->currententry->calls, common->currententry->entry);
+alt_max = no_alternatives(cc);
+alt_count = 0;
+
+/* Matching path. */
+SLJIT_ASSERT(common->currententry->entry_label == NULL && common->recursive_head_ptr != 0);
+common->currententry->entry_label = LABEL();
+set_jumps(common->currententry->entry_calls, common->currententry->entry_label);
 
 sljit_emit_fast_enter(compiler, TMP2, 0);
 count_match(common);
-allocate_stack(common, private_data_size + framesize + alternativesize);
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
-copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
+
+local_size = (alt_max > 1) ? 2 : 1;
+
+/* (Reversed) stack layout:
+   [private data][return address][optional: str ptr] ... [optional: alternative index][recursive_head_ptr] */
+
+allocate_stack(common, private_data_size + local_size);
+/* Save return address. */
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP2, 0);
+
+copy_recurse_data(common, ccbegin, ccend, recurse_copy_from_global, local_size, private_data_size + local_size, has_quit);
+
+/* This variable is saved and restored all time when we enter or exit from a recursive context. */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);
+
 if (needs_control_head)
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);
-if (needs_frame)
-  init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
 
-if (alternativesize > 0)
+if (alt_max > 1)
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
 
 memset(&altbacktrack, 0, sizeof(backtrack_common));
@@ -10760,7 +11855,75 @@
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     return;
 
-  add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+  allocate_stack(common, (alt_max > 1 || has_accept) ? 2 : 1);
+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
+
+  if (alt_max > 1 || has_accept)
+    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
+
+  add_jump(compiler, &match, JUMP(SLJIT_JUMP));
+
+  if (alt_count == 0)
+    {
+    /* Backtracking path entry. */
+    SLJIT_ASSERT(common->currententry->backtrack_label == NULL);
+    common->currententry->backtrack_label = LABEL();
+    set_jumps(common->currententry->backtrack_calls, common->currententry->backtrack_label);
+
+    sljit_emit_fast_enter(compiler, TMP1, 0);
+
+    if (has_accept)
+      accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_max * sizeof (sljit_sw));
+
+    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+    /* Save return address. */
+    OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(local_size - 1), TMP1, 0);
+
+    copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, has_quit);
+
+    if (alt_max > 1)
+      {
+      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+      free_stack(common, 2);
+
+      if (alt_max > 4)
+        {
+          /* Table jump if alt_max is greater than 4. */
+          next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
+          if (SLJIT_UNLIKELY(next_update_addr == NULL))
+            return;
+          sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
+          add_label_addr(common, next_update_addr++);
+        }
+      else
+        {
+        if (alt_max == 4)
+          alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
+        alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
+        }
+      }
+    else
+      free_stack(common, has_accept ? 2 : 1);
+    }
+  else if (alt_max > 4)
+    add_label_addr(common, next_update_addr++);
+  else
+    {
+    if (alt_count != 2 * sizeof(sljit_uw))
+      {
+      JUMPHERE(alt1);
+      if (alt_max == 3 && alt_count == sizeof(sljit_uw))
+        alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
+      }
+    else
+      {
+      JUMPHERE(alt2);
+      if (alt_max == 4)
+        alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
+      }
+    }
+
+  alt_count += sizeof(sljit_uw);
 
   compile_backtrackingpath(common, altbacktrack.top);
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
@@ -10774,55 +11937,65 @@
   cc += GET(cc, 1);
   }
 
-/* None of them matched. */
-OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
-jump = JUMP(SLJIT_JUMP);
+/* No alternative is matched. */
+
+quit = LABEL();
+
+copy_recurse_data(common, ccbegin, ccend, recurse_copy_private_to_global, local_size, private_data_size + local_size, has_quit);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
+free_stack(common, private_data_size + local_size);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, TMP2, 0);
 
 if (common->quit != NULL)
   {
+  SLJIT_ASSERT(has_quit);
+
   set_jumps(common->quit, LABEL());
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
-  if (needs_frame)
-    {
-    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
-    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
-    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
-    }
-  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
-  common->quit = NULL;
-  add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
+  copy_recurse_data(common, ccbegin, ccend, recurse_copy_shared_to_global, local_size, private_data_size + local_size, has_quit);
+  JUMPTO(SLJIT_JUMP, quit);
   }
 
-set_jumps(common->accept, LABEL());
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
-if (needs_frame)
+if (has_accept)
   {
-  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
-  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
-  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
-  }
-OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
+  JUMPHERE(accept_exit);
+  free_stack(common, 2);
 
-JUMPHERE(jump);
-if (common->quit != NULL)
-  set_jumps(common->quit, LABEL());
-copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
-free_stack(common, private_data_size + framesize + alternativesize);
-if (needs_control_head)
-  {
-  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
-  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP1, 0);
-  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
+  /* Save return address. */
+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP1, 0);
+
+  copy_recurse_data(common, ccbegin, ccend, recurse_copy_kept_shared_to_global, local_size, private_data_size + local_size, has_quit);
+
+  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
+  free_stack(common, private_data_size + local_size);
+  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+  sljit_emit_fast_return(compiler, TMP2, 0);
   }
-else
+
+if (common->accept != NULL)
   {
-  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
-  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP2, 0);
+  SLJIT_ASSERT(has_accept);
+
+  set_jumps(common->accept, LABEL());
+
+  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
+  OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0);
+
+  allocate_stack(common, 2);
+  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
   }
-sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
+
+set_jumps(match, LABEL());
+
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+
+copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, has_quit);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), STACK(local_size - 1));
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
+sljit_emit_fast_return(compiler, TMP2, 0);
 }
 
 #undef COMPILE_BACKTRACKINGPATH
@@ -10854,11 +12027,13 @@
 struct sljit_jump *minlength_check_failed = NULL;
 struct sljit_jump *reqbyte_notfound = NULL;
 struct sljit_jump *empty_match = NULL;
+struct sljit_jump *end_anchor_failed = NULL;
 
 SLJIT_ASSERT(tables);
 
 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;
 
@@ -11045,7 +12220,7 @@
 common->compiler = compiler;
 
 /* Main pcre_jit_exec entry. */
-sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size);
+sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
 
 /* Register init. */
 reset_ovector(common, (re->top_bracket + 1) * 2);
@@ -11058,8 +12233,8 @@
 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
 OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
 
@@ -11076,7 +12251,7 @@
 /* Main part of the matching */
 if ((re->overall_options & PCRE2_ANCHORED) == 0)
   {
-  mainloop_label = mainloop_entry(common, (re->flags & PCRE2_HASCRORLF) != 0, re->overall_options);
+  mainloop_label = mainloop_entry(common);
   continue_match_label = LABEL();
   /* Forward search if possible. */
   if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
@@ -11084,11 +12259,11 @@
     if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common))
       ;
     else if ((re->flags & PCRE2_FIRSTSET) != 0)
-      fast_forward_first_char(common, (PCRE2_UCHAR)(re->first_codeunit), (re->flags & PCRE2_FIRSTCASELESS) != 0);
+      fast_forward_first_char(common);
     else if ((re->flags & PCRE2_STARTLINE) != 0)
       fast_forward_newline(common);
     else if ((re->flags & PCRE2_FIRSTMAPSET) != 0)
-      fast_forward_start_bits(common, re->start_bitmap);
+      fast_forward_start_bits(common);
     }
   }
 else
@@ -11135,6 +12310,9 @@
   return PCRE2_ERROR_NOMEMORY;
   }
 
+if ((re->overall_options & PCRE2_ENDANCHORED) != 0)
+  end_anchor_failed = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0);
+
 if (common->might_be_empty)
   {
   empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
@@ -11147,15 +12325,26 @@
 
 /* This means we have a match. Update the ovector. */
 copy_ovector(common, re->top_bracket + 1);
-common->quit_label = common->forced_quit_label = LABEL();
+common->quit_label = common->abort_label = LABEL();
 if (common->quit != NULL)
   set_jumps(common->quit, common->quit_label);
-if (common->forced_quit != NULL)
-  set_jumps(common->forced_quit, common->forced_quit_label);
+if (common->abort != NULL)
+  set_jumps(common->abort, common->abort_label);
 if (minlength_check_failed != NULL)
-  SET_LABEL(minlength_check_failed, common->forced_quit_label);
+  SET_LABEL(minlength_check_failed, common->abort_label);
 sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
 
+if (common->failed_match != NULL)
+  {
+  SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
+  set_jumps(common->failed_match, LABEL());
+  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
+  JUMPTO(SLJIT_JUMP, common->abort_label);
+  }
+
+if ((re->overall_options & PCRE2_ENDANCHORED) != 0)
+  JUMPHERE(end_anchor_failed);
+
 if (mode != PCRE2_JIT_COMPLETE)
   {
   common->partialmatchlabel = LABEL();
@@ -11236,9 +12425,9 @@
   JUMPHERE(empty_match);
   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
   OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
+  OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
   JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label);
-  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
+  OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
   JUMPTO(SLJIT_ZERO, empty_match_found_label);
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
@@ -11249,7 +12438,7 @@
 common->fast_fail_start_ptr = 0;
 common->fast_fail_end_ptr = 0;
 common->currententry = common->entries;
-common->local_exit = TRUE;
+common->local_quit_available = TRUE;
 quit_label = common->quit_label;
 while (common->currententry != NULL)
   {
@@ -11266,7 +12455,7 @@
   flush_stubs(common);
   common->currententry = common->currententry->next;
   }
-common->local_exit = FALSE;
+common->local_quit_available = FALSE;
 common->quit_label = quit_label;
 
 /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
@@ -11274,20 +12463,23 @@
 set_jumps(common->stackalloc, LABEL());
 /* RETURN_ADDR is not a saved register. */
 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
-OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
 
-sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
-jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
-OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
+
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, 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));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
+
+sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
+
+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);
+sljit_emit_fast_return(compiler, TMP1, 0);
 
 /* Allocation failed. */
 JUMPHERE(jump);
diff --git a/dist2/src/pcre2_jit_match.c b/dist2/src/pcre2_jit_match.c
index a323971..5a66545 100644
--- a/dist2/src/pcre2_jit_match.c
+++ b/dist2/src/pcre2_jit_match.c
@@ -49,10 +49,10 @@
 sljit_u8 local_space[MACHINE_STACK_SIZE];
 struct sljit_stack local_stack;
 
-local_stack.top = (sljit_sw)&local_space;
-local_stack.base = local_stack.top;
-local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
-local_stack.max_limit = local_stack.limit;
+local_stack.min_start = local_space;
+local_stack.start = local_space;
+local_stack.end = local_space + MACHINE_STACK_SIZE;
+local_stack.top = local_space + MACHINE_STACK_SIZE;
 arguments->stack = &local_stack;
 return executable_func(arguments);
 }
@@ -118,7 +118,7 @@
 else if ((options & PCRE2_PARTIAL_SOFT) != 0)
   index = 1;
 
-if (functions->executable_funcs[index] == NULL)
+if (functions == NULL || functions->executable_funcs[index] == NULL)
   return PCRE2_ERROR_JIT_BADOPTION;
 
 /* Sanity checks should be handled by pcre_exec. */
diff --git a/dist2/src/pcre2_jit_test.c b/dist2/src/pcre2_jit_test.c
index 705ba18..d9916b7 100644
--- a/dist2/src/pcre2_jit_test.c
+++ b/dist2/src/pcre2_jit_test.c
@@ -179,10 +179,12 @@
 	{ PCRE2_CASELESS, 0, 0, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" },
 	{ PCRE2_CASELESS, 0, 0, 0, "\xfe", "\xff\xfc#\xfe\xfe" },
 	{ PCRE2_CASELESS, 0, 0, 0, "a1", "Aa1" },
+#ifndef NEVER_BACKSLASH_C
 	{ M, A, 0, 0, "\\Ca", "cda" },
 	{ CM, A, 0, 0, "\\Ca", "CDA" },
 	{ M, A, 0, 0 | F_NOMATCH, "\\Cx", "cda" },
 	{ CM, A, 0, 0 | F_NOMATCH, "\\Cx", "CDA" },
+#endif
 	{ CMUP, A, 0, 0, "\xf0\x90\x90\x80\xf0\x90\x90\xa8", "\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
 	{ CMUP, A, 0, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
 	{ CMUP, A, 0, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
@@ -258,6 +260,8 @@
 	{ MU, A, 0, 0, "=\xc7\x82|#\xc6\x82", "\xf1\x83\x82\x82=\xc7\x82\xc7\x83" },
 	{ MU, A, 0, 0, "\xc7\x82\xc7\x83|\xc6\x82\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" },
 	{ MU, A, 0, 0, "\xc6\x82\xc6\x82|\xc7\x83\xc7\x83|\xc8\x84\xc8\x84", "\xf1\x83\x82\x82\xc8\x84\xc8\x84" },
+	{ U, A, 0, 0, "\xe1\x81\x80|\xe2\x82\x80|\xe4\x84\x80", "\xdf\xbf\xc2\x80\xe4\x84\x80" },
+	{ U, A, 0, 0, "(?:\xe1\x81\x80|\xe2\x82\x80|\xe4\x84\x80)#", "\xdf\xbf\xc2\x80#\xe4\x84\x80#" },
 
 	/* Greedy and non-greedy ? operators. */
 	{ MU, A, 0, 0, "(?:a)?a", "laab" },
@@ -707,7 +711,7 @@
 	{ MU, A, 0, 0, "(?1)(((a(*ACCEPT)))b)", "axaa" },
 	{ MU, A, 0, 0, "(?1)(?(DEFINE) (((ac(*ACCEPT)))b) )", "akaac" },
 	{ MU, A, 0, 0, "(a+)b(?1)b\\1", "abaaabaaaaa" },
-	{ MU, A, 0, 0 | F_NOMATCH, "(?(DEFINE)(aa|a))(?1)ab", "aab" },
+	{ MU, A, 0, 0, "(?(DEFINE)(aa|a))(?1)ab", "aab" },
 	{ MU, A, 0, 0, "(?(DEFINE)(a\\Kb))(?1)+ababc", "abababxabababc" },
 	{ MU, A, 0, 0, "(a\\Kb)(?1)+ababc", "abababxababababc" },
 	{ MU, A, 0, 0 | F_NOMATCH, "(a\\Kb)(?1)+ababc", "abababxababababxc" },
@@ -724,6 +728,8 @@
 	{ MU, A, 0, 0, "((?:(?(R)a|(?1))){3})", "XaaaaaaaaaX" },
 	{ MU, A, 0, 0, "((?(R)a|(?1)){1,3})aaaaaa", "aaaaaaaaXaaaaaaaaa" },
 	{ MU, A, 0, 0, "((?(R)a|(?1)){1,3}?)M", "aaaM" },
+	{ MU, A, 0, 0, "((.)(?:.|\\2(?1))){0}#(?1)#", "#aabbccdde# #aabbccddee#" },
+	{ MU, A, 0, 0, "((.)(?:\\2|\\2{4}b)){0}#(?:(?1))+#", "#aaaab# #aaaaab#" },
 
 	/* 16 bit specific tests. */
 	{ CM, A, 0, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" },
@@ -842,13 +848,23 @@
 	{ MU, A, 0, 0 | F_NOMATCH, "(?(?=a)a(*THEN)b|ad)", "ad" },
 	{ MU, A, 0, 0, "(?!(?(?=a)ab|b(*THEN)d))bn|bnn", "bnn" },
 
+	/* Recurse and control verbs. */
+	{ MU, A, 0, 0, "(a(*ACCEPT)b){0}a(?1)b", "aacaabb" },
+	{ MU, A, 0, 0, "((a)\\2(*ACCEPT)b){0}a(?1)b", "aaacaaabb" },
+	{ MU, A, 0, 0, "((ab|a(*ACCEPT)x)+|ababababax){0}_(?1)_", "_ababababax_ _ababababa_" },
+	{ MU, A, 0, 0, "((.)(?:A(*ACCEPT)|(?1)\\2)){0}_(?1)_", "_bcdaAdcb_bcdaAdcb_" },
+	{ MU, A, 0, 0, "((*MARK:m)(?:a|a(*COMMIT)b|aa)){0}_(?1)_", "_ab_" },
+	{ MU, A, 0, 0, "((*MARK:m)(?:a|a(*COMMIT)b|aa)){0}_(?1)_|(_aa_)", "_aa_" },
+	{ MU, A, 0, 0, "(a(*COMMIT)(?:b|bb)|c(*ACCEPT)d|dd){0}_(?1)+_", "_ax_ _cd_ _abbb_ _abcd_ _abbcdd_" },
+	{ MU, A, 0, 0, "((.)(?:.|(*COMMIT)\\2{3}(*ACCEPT).*|.*)){0}_(?1){0,4}_", "_aaaabbbbccccddd_ _aaaabbbbccccdddd_" },
+
 	/* Deep recursion. */
 	{ MU, A, 0, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " },
 	{ MU, A, 0, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " },
 	{ MU, A, 0, 0, "((a?)+)+b", "aaaaaaaaaaaa b" },
 
 	/* Deep recursion: Stack limit reached. */
-	{ M, A, 0, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" },
+	{ M, A, 0, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" },
 	{ M, A, 0, 0 | F_NOMATCH, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
 	{ M, A, 0, 0 | F_NOMATCH, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
 	{ M, A, 0, 0 | F_NOMATCH, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
@@ -1309,9 +1325,9 @@
 		} else {
 			ovector8_1 = pcre2_get_ovector_pointer_8(mdata8_1);
 			ovector8_2 = pcre2_get_ovector_pointer_8(mdata8_2);
-			for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)
 				ovector8_1[i] = -2;
-			for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)
 				ovector8_2[i] = -2;
 		}
 		if (re8) {
@@ -1348,9 +1364,9 @@
 		} else {
 			ovector16_1 = pcre2_get_ovector_pointer_16(mdata16_1);
 			ovector16_2 = pcre2_get_ovector_pointer_16(mdata16_2);
-			for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)
 				ovector16_1[i] = -2;
-			for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)
 				ovector16_2[i] = -2;
 		}
 		if (re16) {
@@ -1392,9 +1408,9 @@
 		} else {
 			ovector32_1 = pcre2_get_ovector_pointer_32(mdata32_1);
 			ovector32_2 = pcre2_get_ovector_pointer_32(mdata32_2);
-			for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)
 				ovector32_1[i] = -2;
-			for (i = 0; i < OVECTOR_SIZE * 3; ++i)
+			for (i = 0; i < OVECTOR_SIZE * 2; ++i)
 				ovector32_2[i] = -2;
 		}
 		if (re32) {
diff --git a/dist2/src/pcre2_match.c b/dist2/src/pcre2_match.c
index 0763a23..79cc93f 100644
--- a/dist2/src/pcre2_match.c
+++ b/dist2/src/pcre2_match.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2015-2018 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -43,17 +43,31 @@
 #include "config.h"
 #endif
 
-#define NLBLOCK mb             /* Block containing newline information */
-#define PSSTART start_subject  /* Field containing processed string start */
-#define PSEND   end_subject    /* Field containing processed string end */
+/* These defines enables debugging code */
+
+//#define DEBUG_FRAMES_DISPLAY
+//#define DEBUG_SHOW_OPS
+//#define DEBUG_SHOW_RMATCH
+
+#ifdef DEBUG_FRAME_DISPLAY
+#include <stdarg.h>
+#endif
+
+/* These defines identify the name of the block containing "static"
+information, and fields within it. */
+
+#define NLBLOCK mb              /* Block containing newline information */
+#define PSSTART start_subject   /* Field containing processed string start */
+#define PSEND   end_subject     /* Field containing processed string end */
 
 #include "pcre2_internal.h"
 
-/* Masks for identifying the public options that are permitted at match time.
-*/
+#define RECURSE_UNSET 0xffffffffu  /* Bigger than max group number */
+
+/* Masks for identifying the public options that are permitted at match time. */
 
 #define PUBLIC_MATCH_OPTIONS \
-  (PCRE2_ANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
+  (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
    PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
    PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT)
 
@@ -61,60 +75,255 @@
    (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\
     PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD)
 
-/* The mb->capture_last field uses the lower 16 bits for the last captured
-substring (which can never be greater than 65535) and a bit in the top half
-to mean "capture vector overflowed". This odd way of doing things was
-implemented when it was realized that preserving and restoring the overflow bit
-whenever the last capture number was saved/restored made for a neater
-interface, and doing it this way saved on (a) another variable, which would
-have increased the stack frame size (a big NO-NO in PCRE) and (b) another
-separate set of save/restore instructions. The following defines are used in
-implementing this. */
-
-#define CAPLMASK    0x0000ffff    /* The bits used for last_capture */
-#define OVFLMASK    0xffff0000    /* The bits used for the overflow flag */
-#define OVFLBIT     0x00010000    /* The bit that is set for overflow */
-
-/* Bits for setting in mb->match_function_type to indicate two special types
-of call to match(). We do it this way to save on using another stack variable,
-as stack usage is to be discouraged. */
-
-#define MATCH_CONDASSERT     1  /* Called to check a condition assertion */
-#define MATCH_CBEGROUP       2  /* Could-be-empty unlimited repeat group */
-
-/* Non-error returns from the match() function. Error returns are externally
-defined PCRE2_ERROR_xxx codes, which are all negative. */
+/* Non-error returns from and within the match() function. Error returns are
+externally defined PCRE2_ERROR_xxx codes, which are all negative. */
 
 #define MATCH_MATCH        1
 #define MATCH_NOMATCH      0
 
-/* Special internal returns from the match() function. Make them sufficiently
-negative to avoid the external error codes. */
+/* Special internal returns used in the match() function. Make them
+sufficiently negative to avoid the external error codes. */
 
 #define MATCH_ACCEPT       (-999)
 #define MATCH_KETRPOS      (-998)
-#define MATCH_ONCE         (-997)
 /* The next 5 must be kept together and in sequence so that a test that checks
 for any one of them can use a range. */
-#define MATCH_COMMIT       (-996)
-#define MATCH_PRUNE        (-995)
-#define MATCH_SKIP         (-994)
-#define MATCH_SKIP_ARG     (-993)
-#define MATCH_THEN         (-992)
+#define MATCH_COMMIT       (-997)
+#define MATCH_PRUNE        (-996)
+#define MATCH_SKIP         (-995)
+#define MATCH_SKIP_ARG     (-994)
+#define MATCH_THEN         (-993)
 #define MATCH_BACKTRACK_MAX MATCH_THEN
 #define MATCH_BACKTRACK_MIN MATCH_COMMIT
 
-/* Min and max values for the common repeats; for the maxima, 0 => infinity */
+/* Group frame type values. Zero means the frame is not a group frame. The
+lower 16 bits are used for data (e.g. the capture number). Group frames are
+used for most groups so that information about the start is easily available at
+the end without having to scan back through intermediate frames (backtrack
+points). */
 
-static const char rep_min[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, };
-static const char rep_max[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, };
+#define GF_CAPTURE     0x00010000u
+#define GF_NOCAPTURE   0x00020000u
+#define GF_CONDASSERT  0x00030000u
+#define GF_RECURSE     0x00040000u
 
-/* Maximum number of ovector elements that can be saved on the system stack
-when processing OP_RECURSE in non-HEAP_MATCH_RECURSE mode. If the ovector is
-bigger, malloc() is used. This value should be a multiple of 3, because the
-ovector length is always a multiple of 3. */
+/* Masks for the identity and data parts of the group frame type. */
 
-#define OP_RECURSE_STACK_SAVE_MAX 45
+#define GF_IDMASK(a)   ((a) & 0xffff0000u)
+#define GF_DATAMASK(a) ((a) & 0x0000ffffu)
+
+/* Repetition types */
+
+enum { REPTYPE_MIN, REPTYPE_MAX, REPTYPE_POS };
+
+/* Min and max values for the common repeats; a maximum of UINT32_MAX =>
+infinity. */
+
+static const uint32_t rep_min[] = {
+  0, 0,       /* * and *? */
+  1, 1,       /* + and +? */
+  0, 0,       /* ? and ?? */
+  0, 0,       /* dummy placefillers for OP_CR[MIN]RANGE */
+  0, 1, 0 };  /* OP_CRPOS{STAR, PLUS, QUERY} */
+
+static const uint32_t rep_max[] = {
+  UINT32_MAX, UINT32_MAX,      /* * and *? */
+  UINT32_MAX, UINT32_MAX,      /* + and +? */
+  1, 1,                        /* ? and ?? */
+  0, 0,                        /* dummy placefillers for OP_CR[MIN]RANGE */
+  UINT32_MAX, UINT32_MAX, 1 }; /* OP_CRPOS{STAR, PLUS, QUERY} */
+
+/* Repetition types - must include OP_CRPOSRANGE (not needed above) */
+
+static const uint32_t rep_typ[] = {
+  REPTYPE_MAX, REPTYPE_MIN,    /* * and *? */
+  REPTYPE_MAX, REPTYPE_MIN,    /* + and +? */
+  REPTYPE_MAX, REPTYPE_MIN,    /* ? and ?? */
+  REPTYPE_MAX, REPTYPE_MIN,    /* OP_CRRANGE and OP_CRMINRANGE */
+  REPTYPE_POS, REPTYPE_POS,    /* OP_CRPOSSTAR, OP_CRPOSPLUS */
+  REPTYPE_POS, REPTYPE_POS };  /* OP_CRPOSQUERY, OP_CRPOSRANGE */
+
+/* Numbers for RMATCH calls at backtracking points. When these lists are
+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 };
+
+#ifdef SUPPORT_WIDE_CHARS
+enum { RM100=100, RM101 };
+#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 };
+#endif
+
+/* Define short names for general fields in the current backtrack frame, which
+is always pointed to by the F variable. Occasional references to fields in
+other frames are written out explicitly. There are also some fields in the
+current frame whose names start with "temp" that are used for short-term,
+localised backtracking memory. These are #defined with Lxxx names at the point
+of use and undefined afterwards. */
+
+#define Fback_frame        F->back_frame
+#define Fcapture_last      F->capture_last
+#define Fcurrent_recurse   F->current_recurse
+#define Fecode             F->ecode
+#define Feptr              F->eptr
+#define Fgroup_frame_type  F->group_frame_type
+#define Flast_group_offset F->last_group_offset
+#define Flength            F->length
+#define Fmark              F->mark
+#define Frdepth            F->rdepth
+#define Fstart_match       F->start_match
+#define Foffset_top        F->offset_top
+#define Foccu              F->occu
+#define Fop                F->op
+#define Fovector           F->ovector
+#define Freturn_id         F->return_id
+
+
+#ifdef DEBUG_FRAMES_DISPLAY
+/*************************************************
+*      Display current frames and contents       *
+*************************************************/
+
+/* This debugging function displays the current set of frames and their
+contents. It is not called automatically from anywhere, the intention being
+that calls can be inserted where necessary when debugging frame-related
+problems.
+
+Arguments:
+  f           the file to write to
+  F           the current top frame
+  P           a previous frame of interest
+  frame_size  the frame size
+  mb          points to the match block
+  s           identification text
+
+Returns:    nothing
+*/
+
+static void
+display_frames(FILE *f, heapframe *F, heapframe *P, PCRE2_SIZE frame_size,
+  match_block *mb, const char *s, ...)
+{
+uint32_t i;
+heapframe *Q;
+va_list ap;
+va_start(ap, s);
+
+fprintf(f, "FRAMES ");
+vfprintf(f, s, ap);
+va_end(ap);
+
+if (P != NULL) fprintf(f, " P=%lu",
+  ((char *)P - (char *)(mb->match_frames))/frame_size);
+fprintf(f, "\n");
+
+for (i = 0, Q = mb->match_frames;
+     Q <= F;
+     i++, Q = (heapframe *)((char *)Q + frame_size))
+  {
+  fprintf(f, "Frame %d type=%x subj=%lu code=%d back=%lu id=%d",
+    i, Q->group_frame_type, Q->eptr - mb->start_subject, *(Q->ecode),
+    Q->back_frame, Q->return_id);
+
+  if (Q->last_group_offset == PCRE2_UNSET)
+    fprintf(f, " lgoffset=unset\n");
+  else
+    fprintf(f, " lgoffset=%lu\n",  Q->last_group_offset/frame_size);
+  }
+}
+
+#endif
+
+
+
+/*************************************************
+*                Process a callout               *
+*************************************************/
+
+/* This function is called for all callouts, whether "standalone" or at the
+start of a conditional group. Feptr will be pointing to either OP_CALLOUT or
+OP_CALLOUT_STR. A callout block is allocated in pcre2_match() and initialized
+with fixed values.
+
+Arguments:
+  F          points to the current backtracking frame
+  mb         points to the match block
+  lengthptr  where to return the length of the callout item
+
+Returns:     the return from the callout
+             or 0 if no callout function exists
+*/
+
+static int
+do_callout(heapframe *F, match_block *mb, PCRE2_SIZE *lengthptr)
+{
+int rc;
+PCRE2_SIZE save0, save1;
+PCRE2_SIZE *callout_ovector;
+pcre2_callout_block *cb;
+
+*lengthptr = (*Fecode == OP_CALLOUT)?
+  PRIV(OP_lengths)[OP_CALLOUT] : GET(Fecode, 1 + 2*LINK_SIZE);
+
+if (mb->callout == NULL) return 0;   /* No callout function provided */
+
+/* The original matching code (pre 10.30) worked directly with the ovector
+passed by the user, and this was passed to callouts. Now that the working
+ovector is in the backtracking frame, it no longer needs to reserve space for
+the overall match offsets (which would waste space in the frame). For backward
+compatibility, however, we pass capture_top and offset_vector to the callout as
+if for the extended ovector, and we ensure that the first two slots are unset
+by preserving and restoring their current contents. Picky compilers complain if
+references such as Fovector[-2] are use directly, so we set up a separate
+pointer. */
+
+callout_ovector = (PCRE2_SIZE *)(Fovector) - 2;
+
+/* The cb->version, cb->subject, cb->subject_length, and cb->start_match fields
+are set externally. The first 3 never change; the last is updated for each
+bumpalong. */
+
+cb = mb->cb;
+cb->capture_top      = (uint32_t)Foffset_top/2 + 1;
+cb->capture_last     = Fcapture_last;
+cb->offset_vector    = callout_ovector;
+cb->mark             = mb->nomatch_mark;
+cb->current_position = (PCRE2_SIZE)(Feptr - mb->start_subject);
+cb->pattern_position = GET(Fecode, 1);
+cb->next_item_length = GET(Fecode, 1 + LINK_SIZE);
+
+if (*Fecode == OP_CALLOUT)  /* Numerical callout */
+  {
+  cb->callout_number = Fecode[1 + 2*LINK_SIZE];
+  cb->callout_string_offset = 0;
+  cb->callout_string = NULL;
+  cb->callout_string_length = 0;
+  }
+else  /* String callout */
+  {
+  cb->callout_number = 0;
+  cb->callout_string_offset = GET(Fecode, 1 + 3*LINK_SIZE);
+  cb->callout_string = Fecode + (1 + 4*LINK_SIZE) + 1;
+  cb->callout_string_length =
+    *lengthptr - (1 + 4*LINK_SIZE) - 2;
+  }
+
+save0 = callout_ovector[0];
+save1 = callout_ovector[1];
+callout_ovector[0] = callout_ovector[1] = PCRE2_UNSET;
+rc = mb->callout(cb, mb->callout_data);
+callout_ovector[0] = save0;
+callout_ovector[1] = save1;
+cb->callout_flags = 0;
+return rc;
+}
 
 
 
@@ -130,10 +339,9 @@
 
 Arguments:
   offset      index into the offset vector
-  offset_top  top of the used offset vector
-  eptr        pointer into the subject
-  mb          points to match block
   caseless    TRUE if caseless
+  F           the current backtracking frame pointer
+  mb          points to match block
   lengthptr   pointer for returning the length matched
 
 Returns:      = 0 sucessful match; number of code units matched is set
@@ -142,21 +350,18 @@
 */
 
 static int
-match_ref(PCRE2_SIZE offset, PCRE2_SIZE offset_top, register PCRE2_SPTR eptr,
-  match_block *mb, BOOL caseless, PCRE2_SIZE *lengthptr)
+match_ref(PCRE2_SIZE offset, BOOL caseless, heapframe *F, match_block *mb,
+  PCRE2_SIZE *lengthptr)
 {
-#if defined SUPPORT_UNICODE
-BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
-#endif
-
-register PCRE2_SPTR p;
+PCRE2_SPTR p;
 PCRE2_SIZE length;
-PCRE2_SPTR eptr_start = eptr;
+PCRE2_SPTR eptr;
+PCRE2_SPTR eptr_start;
 
 /* Deal with an unset group. The default is no match, but there is an option to
 match an empty string. */
 
-if (offset >= offset_top || mb->ovector[offset] == PCRE2_UNSET)
+if (offset >= Foffset_top || Fovector[offset] == PCRE2_UNSET)
   {
   if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
     {
@@ -168,19 +373,20 @@
 
 /* Separate the caseless and UTF cases for speed. */
 
-p = mb->start_subject + mb->ovector[offset];
-length = mb->ovector[offset+1] - mb->ovector[offset];
+eptr = eptr_start = Feptr;
+p = mb->start_subject + Fovector[offset];
+length = Fovector[offset+1] - Fovector[offset];
 
 if (caseless)
   {
 #if defined SUPPORT_UNICODE
-  if (utf)
+  if ((mb->poptions & PCRE2_UTF) != 0)
     {
     /* Match characters up to the end of the reference. NOTE: the number of
     code units matched may differ, because in UTF-8 there are some characters
-    whose upper and lower case versions code have different numbers of bytes.
-    For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65
-    (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
+    whose upper and lower case codes have different numbers of bytes. For
+    example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 (3
+    bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
     sequence of two of the latter. It is important, therefore, to check the
     length along the reference, not along the subject (earlier code did this
     wrong). */
@@ -226,14 +432,26 @@
   }
 
 /* In the caseful case, we can just compare the code units, whether or not we
-are in UTF mode. */
+are in UTF mode. When partial matching, we have to do this unit-by-unit. */
 
 else
   {
-  for (; length > 0; length--)
+  if (mb->partial != 0)
     {
-    if (eptr >= mb->end_subject) return 1;   /* Partial match */
-    if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1;  /*No match */
+    for (; length > 0; length--)
+      {
+      if (eptr >= mb->end_subject) return 1;   /* Partial match */
+      if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1;  /* No match */
+      }
+    }
+
+  /* Not partial matching */
+
+  else
+    {
+    if ((PCRE2_SIZE)(mb->end_subject - eptr) < length) return 1; /* Partial */
+    if (memcmp(p, eptr, CU2BYTES(length)) != 0) return -1;  /* No match */
+    eptr += length;
     }
   }
 
@@ -243,2304 +461,1787 @@
 
 
 
-/***************************************************************************
-****************************************************************************
-                   RECURSION IN THE match() FUNCTION
+/******************************************************************************
+*******************************************************************************
+                   "Recursion" in the match() function
 
-The match() function is highly recursive, though not every recursive call
-increases the recursion depth. Nevertheless, some regular expressions can cause
-it to recurse to a great depth. I was writing for Unix, so I just let it call
-itself recursively. This uses the stack for saving everything that has to be
-saved for a recursive call. On Unix, the stack can be large, and this works
-fine.
+The original match() function was highly recursive, but this proved to be the
+source of a number of problems over the years, mostly because of the relatively
+small system stacks that are commonly found. As new features were added to
+patterns, various kludges were invented to reduce the amount of stack used,
+making the code hard to understand in places.
 
-It turns out that on some non-Unix-like systems there are problems with
-programs that use a lot of stack. (This despite the fact that every last chip
-has oodles of memory these days, and techniques for extending the stack have
-been known for decades.) So....
+A version did exist that used individual frames on the heap instead of calling
+match() recursively, but this ran substantially slower. The current version is
+a refactoring that uses a vector of frames to remember backtracking points.
+This runs no slower, and possibly even a bit faster than the original recursive
+implementation. An initial vector of size START_FRAMES_SIZE (enough for maybe
+50 frames) is allocated on the system stack. If this is not big enough, the
+heap is used for a larger vector.
 
-There is a fudge, triggered by defining HEAP_MATCH_RECURSE, which avoids
-recursive calls by keeping local variables that need to be preserved in blocks
-of memory on the heap instead instead of on the stack. Macros are used to
-achieve this so that the actual code doesn't look very different to what it
-always used to.
+*******************************************************************************
+******************************************************************************/
 
-The original heap-recursive code used longjmp(). However, it seems that this
-can be very slow on some operating systems. Following a suggestion from Stan
-Switzer, the use of longjmp() has been abolished, at the cost of having to
-provide a unique number for each call to RMATCH. There is no way of generating
-a sequence of numbers at compile time in C. I have given them names, to make
-them stand out more clearly.
 
-Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
-FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
-tests. Furthermore, not using longjmp() means that local dynamic variables
-don't have indeterminate values; this has meant that the frame size can be
-reduced because the result can be "passed back" by straight setting of the
-variable instead of being passed in the frame.
-****************************************************************************
-***************************************************************************/
 
-/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
-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, RM38, RM39, RM40,
-       RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
-       RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
-       RM61,  RM62, RM63, RM64, RM65, RM66, RM67, RM68 };
+/*************************************************
+*       Macros for the match() function          *
+*************************************************/
 
-/* These versions of the macros use the stack, as normal. Note that the "rw"
-argument of RMATCH isn't actually used in this definition. */
+/* These macros pack up tests that are used for partial matching several times
+in the code. We set the "hit end" flag if the pointer is at the end of the
+subject and also past the earliest inspected character (i.e. something has been
+matched, even if not part of the actual matched string). For hard partial
+matching, we then return immediately. The second one is used when we already
+know we are past the end of the subject. */
 
-#ifndef HEAP_MATCH_RECURSE
-#define REGISTER register
-#define RMATCH(ra,rb,rc,rd,re,rw) \
-  rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
-#define RRETURN(ra) return ra
-#else
+#define CHECK_PARTIAL()\
+  if (mb->partial != 0 && Feptr >= mb->end_subject && \
+      Feptr > mb->start_used_ptr) \
+    { \
+    mb->hitend = TRUE; \
+    if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \
+    }
 
-/* These versions of the macros manage a private stack on the heap. Note that
-the "rd" argument of RMATCH isn't actually used in this definition. It's the mb
-argument of match(), which never changes. */
+#define SCHECK_PARTIAL()\
+  if (mb->partial != 0 && Feptr > mb->start_used_ptr) \
+    { \
+    mb->hitend = TRUE; \
+    if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \
+    }
 
-#define REGISTER
+/* 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,rc,rd,re,rw)\
+#define RMATCH(ra,rb)\
   {\
-  heapframe *newframe = frame->Xnextframe;\
-  if (newframe == NULL)\
-    {\
-    newframe = (heapframe *)(mb->stack_memctl.malloc)\
-      (sizeof(heapframe), mb->stack_memctl.memory_data);\
-    if (newframe == NULL) RRETURN(PCRE2_ERROR_NOMEMORY);\
-    newframe->Xnextframe = NULL;\
-    frame->Xnextframe = newframe;\
-    }\
-  frame->Xwhere = rw;\
-  newframe->Xeptr = ra;\
-  newframe->Xecode = rb;\
-  newframe->Xmstart = mstart;\
-  newframe->Xoffset_top = rc;\
-  newframe->Xeptrb = re;\
-  newframe->Xrdepth = frame->Xrdepth + 1;\
-  newframe->Xprevframe = frame;\
-  frame = newframe;\
-  goto HEAP_RECURSE;\
-  L_##rw:;\
+  start_ecode = ra;\
+  Freturn_id = rb;\
+  goto MATCH_RECURSE;\
+  L_##rb:;\
   }
 
 #define RRETURN(ra)\
   {\
-  heapframe *oldframe = frame;\
-  frame = oldframe->Xprevframe;\
-  if (frame != NULL)\
-    {\
-    rrc = ra;\
-    goto HEAP_RETURN;\
-    }\
-  return ra;\
+  rrc = ra;\
+  goto RETURN_SWITCH;\
   }
 
 
-/* Structure for remembering the local variables in a private frame. Arrange it
-so as to minimize the number of holes. */
-
-typedef struct heapframe {
-  struct heapframe *Xprevframe;
-  struct heapframe *Xnextframe;
-
-#ifdef SUPPORT_UNICODE
-  PCRE2_SPTR Xcharptr;
-#endif
-  PCRE2_SPTR Xeptr;
-  PCRE2_SPTR Xecode;
-  PCRE2_SPTR Xmstart;
-  PCRE2_SPTR Xcallpat;
-  PCRE2_SPTR Xdata;
-  PCRE2_SPTR Xnext_ecode;
-  PCRE2_SPTR Xpp;
-  PCRE2_SPTR Xprev;
-  PCRE2_SPTR Xsaved_eptr;
-
-  eptrblock *Xeptrb;
-
-  PCRE2_SIZE Xlength;
-  PCRE2_SIZE Xoffset;
-  PCRE2_SIZE Xoffset_top;
-  PCRE2_SIZE Xsave_offset1, Xsave_offset2, Xsave_offset3;
-
-  uint32_t Xfc;
-  uint32_t Xnumber;
-  uint32_t Xrdepth;
-  uint32_t Xop;
-  uint32_t Xsave_capture_last;
-
-#ifdef SUPPORT_UNICODE
-  uint32_t Xprop_value;
-  int Xprop_type;
-  int Xprop_fail_result;
-  int Xoclength;
-#endif
-
-  int Xcodelink;
-  int Xctype;
-  int Xfi;
-  int Xmax;
-  int Xmin;
-  int Xwhere;    /* Where to jump back to */
-
-  BOOL Xcondition;
-  BOOL Xcur_is_word;
-  BOOL Xprev_is_word;
-
-  eptrblock Xnewptrb;
-  recursion_info Xnew_recursive;
-
-#ifdef SUPPORT_UNICODE
-  PCRE2_UCHAR Xocchars[6];
-#endif
-} heapframe;
-
-#endif
-
-
-/***************************************************************************
-***************************************************************************/
-
-
-/* When HEAP_MATCH_RECURSE is not defined, the match() function implements
-backtrack points by calling itself recursively in all but one case. The one
-special case is when processing OP_RECURSE, which specifies recursion in the
-pattern. The entire ovector must be saved and restored while processing
-OP_RECURSE. If the ovector is small enough, instead of calling match()
-directly, op_recurse_ovecsave() is called. This function uses the system stack
-to save the ovector while calling match() to process the pattern recursion. */
-
-#ifndef HEAP_MATCH_RECURSE
-
-/* We need a prototype for match() because it is mutually recursive with
-op_recurse_ovecsave(). */
-
-static int
-match(REGISTER PCRE2_SPTR eptr, REGISTER PCRE2_SPTR ecode, PCRE2_SPTR mstart,
-  PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth);
-
-
-/*************************************************
-*      Process OP_RECURSE, stacking ovector      *
-*************************************************/
-
-/* When this function is called, mb->recursive has already been updated to
-point to a new recursion data block, and all its fields other than ovec_save
-have been set.
-
-This function exists so that the local vector variable ovecsave is no longer
-defined in the match() function, as it was in PCRE1. It is used only when there
-is recursion in the pattern, so it wastes a lot of stack to have it defined for
-every call of match(). We now use this function as an indirect way of calling
-match() only in the case when ovecsave is needed. (David Wheeler used to say
-"All problems in computer science can be solved by another level of
-indirection.")
-
-HOWEVER: when this file is compiled by gcc in an optimizing mode, because this
-function is called only once, and only from within match(), gcc will "inline"
-it - that is, move it inside match() - and this completely negates its reason
-for existence. Therefore, we mark it as non-inline when gcc is in use.
-
-Arguments:
-  eptr        pointer to current character in subject
-  callpat     the recursion point in the pattern
-  mstart      pointer to the current match start position (can be modified
-                by encountering \K)
-  offset_top  current top pointer (highest ovector offset used + 1)
-  mb          pointer to "static" info block for the match
-  eptrb       pointer to chain of blocks containing eptr at start of
-                brackets - for testing for empty matches
-  rdepth      the recursion depth
-
-Returns:      a match() return code
-*/
-
-static int
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
-__attribute__ ((noinline))
-#endif
-op_recurse_ovecsave(REGISTER PCRE2_SPTR eptr, PCRE2_SPTR callpat,
-  PCRE2_SPTR mstart, PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb,
-  uint32_t rdepth)
-{
-register int rrc;
-BOOL cbegroup = *callpat >= OP_SBRA;
-recursion_info *new_recursive = mb->recursive;
-PCRE2_SIZE ovecsave[OP_RECURSE_STACK_SAVE_MAX];
-
-/* Save the ovector */
-
-new_recursive->ovec_save = ovecsave;
-memcpy(ovecsave, mb->ovector, mb->offset_end * sizeof(PCRE2_SIZE));
-
-/* Do the recursion. After processing each alternative, restore the ovector
-data and the last captured value. */
-
-do
-  {
-  if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP;
-  rrc = match(eptr, callpat + PRIV(OP_lengths)[*callpat], mstart, offset_top,
-    mb, eptrb, rdepth + 1);
-  memcpy(mb->ovector, new_recursive->ovec_save,
-      mb->offset_end * sizeof(PCRE2_SIZE));
-  mb->capture_last = new_recursive->saved_capture_last;
-  if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) return rrc;
-
-  /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
-  recursion; they cause a NOMATCH for the entire recursion. These codes
-  are defined in a range that can be tested for. */
-
-  if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
-    return MATCH_NOMATCH;
-
-  /* Any return code other than NOMATCH is an error. Otherwise, advance to the
-  next alternative or to the end of the recursing subpattern. If there were
-  nested recursions, mb->recursive might be changed, so reset it before
-  looping. */
-
-  if (rrc != MATCH_NOMATCH) return rrc;
-  mb->recursive = new_recursive;
-  callpat += GET(callpat, 1);
-  }
-while (*callpat == OP_ALT);  /* Loop for the alternatives */
-
-/* None of the alternatives matched. */
-
-return MATCH_NOMATCH;
-}
-#endif  /* HEAP_MATCH_RECURSE */
-
-
 
 /*************************************************
 *         Match from current position            *
 *************************************************/
 
-/* This function is called recursively in many circumstances. Whenever it
-returns a negative (error) response, the outer incarnation must also return the
-same response. */
+/* This function is called to run one match attempt at a single starting point
+in the subject.
 
-/* These macros pack up tests that are used for partial matching, and which
-appear several times in the code. We set the "hit end" flag if the pointer is
-at the end of the subject and also past the earliest inspected character (i.e.
-something has been matched, even if not part of the actual matched string). For
-hard partial matching, we then return immediately. The second one is used when
-we already know we are past the end of the subject. */
-
-#define CHECK_PARTIAL()\
-  if (mb->partial != 0 && eptr >= mb->end_subject && \
-      eptr > mb->start_used_ptr) \
-    { \
-    mb->hitend = TRUE; \
-    if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \
-    }
-
-#define SCHECK_PARTIAL()\
-  if (mb->partial != 0 && eptr > mb->start_used_ptr) \
-    { \
-    mb->hitend = TRUE; \
-    if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL); \
-    }
-
-
-/* Performance note: It might be tempting to extract commonly used fields from
-the mb structure (e.g. utf, end_subject) into individual variables to improve
+Performance note: It might be tempting to extract commonly used fields from the
+mb structure (e.g. end_subject) into individual variables to improve
 performance. Tests using gcc on a SPARC disproved this; in the first case, it
 made performance worse.
 
 Arguments:
-   eptr        pointer to current character in subject
-   ecode       pointer to current position in compiled code
-   mstart      pointer to the current match start position (can be modified
-                 by encountering \K)
-   offset_top  current top pointer (highest ovector offset used + 1)
-   mb          pointer to "static" info block for the match
-   eptrb       pointer to chain of blocks containing eptr at start of
-                 brackets - for testing for empty matches
-   rdepth      the recursion depth
+   start_eptr   starting character in subject
+   start_ecode  starting position in compiled code
+   ovector      pointer to the final output vector
+   oveccount    number of pairs in ovector
+   top_bracket  number of capturing parentheses in the pattern
+   frame_size   size of each backtracking frame
+   mb           pointer to "static" variables block
 
-Returns:       MATCH_MATCH if matched            )  these values are >= 0
-               MATCH_NOMATCH if failed to match  )
-               a negative MATCH_xxx value for PRUNE, SKIP, etc
-               a negative PCRE2_ERROR_xxx value if aborted by an error condition
-                 (e.g. stopped by repeated call or recursion limit)
+Returns:        MATCH_MATCH if matched            )  these values are >= 0
+                MATCH_NOMATCH if failed to match  )
+                negative MATCH_xxx value for PRUNE, SKIP, etc
+                negative PCRE2_ERROR_xxx value if aborted by an error condition
+                (e.g. stopped by repeated call or depth limit)
 */
 
 static int
-match(REGISTER PCRE2_SPTR eptr, REGISTER PCRE2_SPTR ecode, PCRE2_SPTR mstart,
-  PCRE2_SIZE offset_top, match_block *mb, eptrblock *eptrb, uint32_t rdepth)
+match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, PCRE2_SIZE *ovector,
+  uint16_t oveccount, uint16_t top_bracket, PCRE2_SIZE frame_size,
+  match_block *mb)
 {
-/* These variables do not need to be preserved over recursion in this function,
-so they can be ordinary variables in all cases. Mark some of them with
-"register" because they are used a lot in loops. */
+/* Frame-handling variables */
 
-register int  rrc;         /* Returns from recursive calls */
-register int  i;           /* Used for loops not involving calls to RMATCH() */
-register uint32_t c;       /* Character values not kept over RMATCH() calls */
-register BOOL utf;         /* Local copy of UTF flag for speed */
+heapframe *F;           /* Current frame pointer */
+heapframe *N = NULL;    /* Temporary frame pointers */
+heapframe *P = NULL;
+heapframe *assert_accept_frame;  /* For passing back the frame with captures */
+PCRE2_SIZE frame_copy_size;      /* Amount to copy when creating a new frame */
 
-BOOL minimize, possessive; /* Quantifier options */
-BOOL caseless;
-int condcode;
+/* Local variables that do not need to be preserved over calls to RRMATCH(). */
 
-/* When recursion is not being used, all "local" variables that have to be
-preserved over calls to RMATCH() are part of a "frame". We set up the top-level
-frame on the stack here; subsequent instantiations are obtained from the heap
-whenever RMATCH() does a "recursion". See the macro definitions above. Putting
-the top-level on the stack rather than malloc-ing them all gives a performance
-boost in many cases where there is not much "recursion". */
+PCRE2_SPTR bracode;     /* Temp pointer to start of group */
+PCRE2_SIZE offset;      /* Used for group offsets */
+PCRE2_SIZE length;      /* Used for various length calculations */
 
-#ifdef HEAP_MATCH_RECURSE
-heapframe *frame = (heapframe *)mb->match_frames_base;
-
-/* Copy in the original argument variables */
-
-frame->Xeptr = eptr;
-frame->Xecode = ecode;
-frame->Xmstart = mstart;
-frame->Xoffset_top = offset_top;
-frame->Xeptrb = eptrb;
-frame->Xrdepth = rdepth;
-
-/* This is where control jumps back to to effect "recursion" */
-
-HEAP_RECURSE:
-
-/* Macros make the argument variables come from the current frame */
-
-#define eptr               frame->Xeptr
-#define ecode              frame->Xecode
-#define mstart             frame->Xmstart
-#define offset_top         frame->Xoffset_top
-#define eptrb              frame->Xeptrb
-#define rdepth             frame->Xrdepth
-
-/* Ditto for the local variables */
-
+int rrc;                /* Return from functions & backtracking "recursions" */
 #ifdef SUPPORT_UNICODE
-#define charptr            frame->Xcharptr
-#define prop_value         frame->Xprop_value
-#define prop_type          frame->Xprop_type
-#define prop_fail_result   frame->Xprop_fail_result
-#define oclength           frame->Xoclength
-#define occhars            frame->Xocchars
+int proptype;           /* Type of character property */
 #endif
 
+uint32_t i;             /* Used for local loops */
+uint32_t fc;            /* Character values */
+uint32_t number;        /* Used for group and other numbers */
+uint32_t reptype = 0;   /* Type of repetition (0 to avoid compiler warning) */
+uint32_t group_frame_type;  /* Specifies type for new group frames */
 
-#define callpat            frame->Xcallpat
-#define codelink           frame->Xcodelink
-#define data               frame->Xdata
-#define next_ecode         frame->Xnext_ecode
-#define pp                 frame->Xpp
-#define prev               frame->Xprev
-#define saved_eptr         frame->Xsaved_eptr
+BOOL condition;         /* Used in conditional groups */
+BOOL cur_is_word;       /* Used in "word" tests */
+BOOL prev_is_word;      /* Used in "word" tests */
 
-#define new_recursive      frame->Xnew_recursive
-
-#define ctype              frame->Xctype
-#define fc                 frame->Xfc
-#define fi                 frame->Xfi
-#define length             frame->Xlength
-#define max                frame->Xmax
-#define min                frame->Xmin
-#define number             frame->Xnumber
-#define offset             frame->Xoffset
-#define op                 frame->Xop
-#define save_capture_last  frame->Xsave_capture_last
-#define save_offset1       frame->Xsave_offset1
-#define save_offset2       frame->Xsave_offset2
-#define save_offset3       frame->Xsave_offset3
-
-#define condition          frame->Xcondition
-#define cur_is_word        frame->Xcur_is_word
-#define prev_is_word       frame->Xprev_is_word
-
-#define newptrb            frame->Xnewptrb
-
-/* When normal stack-based recursion is being used for match(), local variables
-are allocated on the stack and get preserved during recursion in the usual way.
-In this environment, fi and i, and fc and c, can be the same variables. */
-
-#else         /* HEAP_MATCH_RECURSE not defined */
-#define fi i
-#define fc c
-
-/* Many of the following variables are used only in small blocks of the code.
-My normal style of coding would have declared them within each of those blocks.
-However, in order to accommodate the version of this code that uses an external
-"stack" implemented on the heap, it is easier to declare them all here, so the
-declarations can be cut out in a block. The only declarations within blocks
-below are for variables that do not have to be preserved over a recursive call
-to RMATCH(). */
+/* UTF flag */
 
 #ifdef SUPPORT_UNICODE
-PCRE2_SPTR charptr;
-#endif
-PCRE2_SPTR callpat;
-PCRE2_SPTR data;
-PCRE2_SPTR next_ecode;
-PCRE2_SPTR pp;
-PCRE2_SPTR prev;
-PCRE2_SPTR saved_eptr;
-
-PCRE2_SIZE length;
-PCRE2_SIZE offset;
-PCRE2_SIZE save_offset1, save_offset2, save_offset3;
-
-uint32_t number;
-uint32_t op;
-uint32_t save_capture_last;
-
-#ifdef SUPPORT_UNICODE
-uint32_t prop_value;
-int prop_type;
-int prop_fail_result;
-int oclength;
-PCRE2_UCHAR occhars[6];
-#endif
-
-int codelink;
-int ctype;
-int max;
-int min;
-
-BOOL condition;
-BOOL cur_is_word;
-BOOL prev_is_word;
-
-eptrblock newptrb;
-recursion_info new_recursive;
-#endif  /* HEAP_MATCH_RECURSE not defined */
-
-/* To save space on the stack and in the heap frame, I have doubled up on some
-of the local variables that are used only in localised parts of the code, but
-still need to be preserved over recursive calls of match(). These macros define
-the alternative names that are used. */
-
-#define allow_zero      cur_is_word
-#define cbegroup        condition
-#define code_offset     codelink
-#define condassert      condition
-#define foc             number
-#define matched_once    prev_is_word
-#define save_mark       data
-
-/* These statements are here to stop the compiler complaining about unitialized
-variables. */
-
-#ifdef SUPPORT_UNICODE
-prop_value = 0;
-prop_fail_result = 0;
-#endif
-
-
-/* This label is used for tail recursion, which is used in a few cases even
-when HEAP_MATCH_RECURSE is not defined, in order to reduce the amount of stack
-that is used. Thanks to Ian Taylor for noticing this possibility and sending
-the original patch. */
-
-TAIL_RECURSE:
-
-/* OK, now we can get on with the real code of the function. Recursive calls
-are specified by the macro RMATCH and RRETURN is used to return. When
-HEAP_MATCH_RECURSE is *not* defined, these just turn into a recursive call to
-match() and a "return", respectively. However, RMATCH isn't like a function
-call because it's quite a complicated macro. It has to be used in one
-particular way. This shouldn't, however, impact performance when true recursion
-is being used. */
-
-#ifdef SUPPORT_UNICODE
-utf = (mb->poptions & PCRE2_UTF) != 0;
+BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
 #else
-utf = FALSE;
+BOOL utf = FALSE;
 #endif
 
-/* First check that we haven't called match() too many times, or that we
-haven't exceeded the recursive call limit. */
+/* This is the length of the last part of a backtracking frame that must be
+copied when a new frame is created. */
 
-if (mb->match_call_count++ >= mb->match_limit) RRETURN(PCRE2_ERROR_MATCHLIMIT);
-if (rdepth >= mb->match_limit_recursion) RRETURN(PCRE2_ERROR_RECURSIONLIMIT);
+frame_copy_size = frame_size - offsetof(heapframe, eptr);
 
-/* At the start of a group with an unlimited repeat that may match an empty
-string, the variable mb->match_function_type contains the MATCH_CBEGROUP bit.
-It is done this way to save having to use another function argument, which
-would take up space on the stack. See also MATCH_CONDASSERT below.
+/* Set up the first current frame at the start of the vector, and initialize
+fields that are not reset for new frames. */
 
-When MATCH_CBEGROUP is set, add the current subject pointer to the chain of
-such remembered pointers, to be checked when we hit the closing ket, in order
-to break infinite loops that match no characters. When match() is called in
-other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must
-NOT be used with tail recursion, because the memory block that is used is on
-the stack, so a new one may be required for each match(). */
+F = mb->match_frames;
+Frdepth = 0;                        /* "Recursion" depth */
+Fcapture_last = 0;                  /* Number of most recent capture */
+Fcurrent_recurse = RECURSE_UNSET;   /* Not pattern recursing. */
+Fstart_match = Feptr = start_eptr;  /* Current data pointer and start match */
+Fmark = NULL;                       /* Most recent mark */
+Foffset_top = 0;                    /* End of captures within the frame */
+Flast_group_offset = PCRE2_UNSET;   /* Saved frame of most recent group */
+group_frame_type = 0;               /* Not a start of group frame */
+goto NEW_FRAME;                     /* Start processing with this frame */
 
-if ((mb->match_function_type & MATCH_CBEGROUP) != 0)
+/* Come back here when we want to create a new frame for remembering a
+backtracking point. */
+
+MATCH_RECURSE:
+
+/* Set up a new backtracking frame. If the vector is full, get a new one
+on the heap, doubling the size, but constrained by the heap limit. */
+
+N = (heapframe *)((char *)F + frame_size);
+if (N >= mb->match_frames_top)
   {
-  newptrb.epb_saved_eptr = eptr;
-  newptrb.epb_prev = eptrb;
-  eptrb = &newptrb;
-  mb->match_function_type &= ~MATCH_CBEGROUP;
+  PCRE2_SIZE newsize = mb->frame_vector_size * 2;
+  heapframe *new;
+
+  if ((newsize / 1024) > mb->heap_limit)
+    {
+    PCRE2_SIZE maxsize = ((mb->heap_limit * 1024)/frame_size) * frame_size;
+    if (mb->frame_vector_size >= maxsize) return PCRE2_ERROR_HEAPLIMIT;
+    newsize = maxsize;
+    }
+
+  new = mb->memctl.malloc(newsize, mb->memctl.memory_data);
+  if (new == NULL) return PCRE2_ERROR_NOMEMORY;
+  memcpy(new, mb->match_frames, mb->frame_vector_size);
+
+  F = (heapframe *)((char *)new + ((char *)F - (char *)mb->match_frames));
+  N = (heapframe *)((char *)F + frame_size);
+
+  if (mb->match_frames != mb->stack_frames)
+    mb->memctl.free(mb->match_frames, mb->memctl.memory_data);
+  mb->match_frames = new;
+  mb->match_frames_top = (heapframe *)((char *)mb->match_frames + newsize);
+  mb->frame_vector_size = newsize;
   }
 
-/* Now, at last, we can start processing the opcodes. */
+#ifdef DEBUG_SHOW_RMATCH
+fprintf(stderr, "++ RMATCH %2d frame=%d", Freturn_id, Frdepth + 1);
+if (group_frame_type != 0)
+  {
+  fprintf(stderr, " type=%x ", group_frame_type);
+  switch (GF_IDMASK(group_frame_type))
+    {
+    case GF_CAPTURE:
+    fprintf(stderr, "capture=%d", GF_DATAMASK(group_frame_type));
+    break;
+
+    case GF_NOCAPTURE:
+    fprintf(stderr, "nocapture op=%d", GF_DATAMASK(group_frame_type));
+    break;
+
+    case GF_CONDASSERT:
+    fprintf(stderr, "condassert op=%d", GF_DATAMASK(group_frame_type));
+    break;
+
+    case GF_RECURSE:
+    fprintf(stderr, "recurse=%d", GF_DATAMASK(group_frame_type));
+    break;
+
+    default:
+    fprintf(stderr, "*** unknown ***");
+    break;
+    }
+  }
+fprintf(stderr, "\n");
+#endif
+
+/* Copy those fields that must be copied into the new frame, increase the
+"recursion" depth (i.e. the new frame's index) and then make the new frame
+current. */
+
+memcpy((char *)N + offsetof(heapframe, eptr),
+       (char *)F + offsetof(heapframe, eptr),
+       frame_copy_size);
+
+N->rdepth = Frdepth + 1;
+F = N;
+
+/* Carry on processing with a new frame. */
+
+NEW_FRAME:
+Fgroup_frame_type = group_frame_type;
+Fecode = start_ecode;      /* Starting code pointer */
+Fback_frame = frame_size;  /* Default is go back one frame */
+
+/* If this is a special type of group frame, remember its offset for quick
+access at the end of the group. If this is a recursion, set a new current
+recursion value. */
+
+if (group_frame_type != 0)
+  {
+  Flast_group_offset = (char *)F - (char *)mb->match_frames;
+  if (GF_IDMASK(group_frame_type) == GF_RECURSE)
+    Fcurrent_recurse = GF_DATAMASK(group_frame_type);
+  group_frame_type = 0;
+  }
+
+
+/* ========================================================================= */
+/* This is the main processing loop. First check that we haven't recorded too
+many backtracks (search tree is too large), or that we haven't exceeded the
+recursive depth limit (used too many backtracking frames). If not, process the
+opcodes. */
+
+if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
+if (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
 
 for (;;)
   {
-  minimize = possessive = FALSE;
-  op = *ecode;
+#ifdef DEBUG_SHOW_OPS
+fprintf(stderr, "++ op=%d\n", *Fecode);
+#endif
 
-  switch(op)
+  Fop = (uint8_t)(*Fecode);  /* Cast needed for 16-bit and 32-bit modes */
+  switch(Fop)
     {
-    case OP_MARK:
-    mb->nomatch_mark = ecode + 2;
-    mb->mark = NULL;    /* In case previously set by assertion */
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb,
-      eptrb, RM55);
-    if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
-         mb->mark == NULL) mb->mark = ecode + 2;
-
-    /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
-    argument, and we must check whether that argument matches this MARK's
-    argument. It is passed back in mb->start_match_ptr (an overloading of that
-    variable). If it does match, we reset that variable to the current subject
-    position and return MATCH_SKIP. Otherwise, pass back the return code
-    unaltered. */
-
-    else if (rrc == MATCH_SKIP_ARG &&
-        PRIV(strcmp)(ecode + 2, mb->start_match_ptr) == 0)
-      {
-      mb->start_match_ptr = eptr;
-      RRETURN(MATCH_SKIP);
-      }
-    RRETURN(rrc);
-
-    case OP_FAIL:
-    RRETURN(MATCH_NOMATCH);
-
-    case OP_COMMIT:
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
-      eptrb, RM52);
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    RRETURN(MATCH_COMMIT);
-
-    case OP_PRUNE:
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
-      eptrb, RM51);
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    RRETURN(MATCH_PRUNE);
-
-    case OP_PRUNE_ARG:
-    mb->nomatch_mark = ecode + 2;
-    mb->mark = NULL;    /* In case previously set by assertion */
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb,
-      eptrb, RM56);
-    if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
-         mb->mark == NULL) mb->mark = ecode + 2;
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    RRETURN(MATCH_PRUNE);
-
-    case OP_SKIP:
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
-      eptrb, RM53);
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    mb->start_match_ptr = eptr;   /* Pass back current position */
-    RRETURN(MATCH_SKIP);
-
-    /* Note that, for Perl compatibility, SKIP with an argument does NOT set
-    nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
-    not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
-    that failed and any that precede it (either they also failed, or were not
-    triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
-    SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg
-    set to the count of the one that failed. */
-
-    case OP_SKIP_ARG:
-    mb->skip_arg_count++;
-    if (mb->skip_arg_count <= mb->ignore_skip_arg)
-      {
-      ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
-      break;
-      }
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, mb,
-      eptrb, RM57);
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-
-    /* Pass back the current skip name by overloading mb->start_match_ptr and
-    returning the special MATCH_SKIP_ARG return code. This will either be
-    caught by a matching MARK, or get to the top, where it causes a rematch
-    with mb->ignore_skip_arg set to the value of mb->skip_arg_count. */
-
-    mb->start_match_ptr = ecode + 2;
-    RRETURN(MATCH_SKIP_ARG);
-
-    /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
-    the branch in which it occurs can be determined. Overload the start of
-    match pointer to do this. */
-
-    case OP_THEN:
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
-      eptrb, RM54);
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    mb->start_match_ptr = ecode;
-    RRETURN(MATCH_THEN);
-
-    case OP_THEN_ARG:
-    mb->nomatch_mark = ecode + 2;
-    mb->mark = NULL;    /* In case previously set by assertion */
-    RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
-      mb, eptrb, RM58);
-    if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
-         mb->mark == NULL) mb->mark = ecode + 2;
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    mb->start_match_ptr = ecode;
-    RRETURN(MATCH_THEN);
-
-    /* Handle an atomic group that does not contain any capturing parentheses.
-    This can be handled like an assertion. Prior to 8.13, all atomic groups
-    were handled this way. In 8.13, the code was changed as below for ONCE, so
-    that backups pass through the group and thereby reset captured values.
-    However, this uses a lot more stack, so in 8.20, atomic groups that do not
-    contain any captures generate OP_ONCE_NC, which can be handled in the old,
-    less stack intensive way.
-
-    Check the alternative branches in turn - the matching won't pass the KET
-    for this kind of subpattern. If any one branch matches, we carry on as at
-    the end of a normal bracket, leaving the subject pointer, but resetting
-    the start-of-match value in case it was changed by \K. */
-
-    case OP_ONCE_NC:
-    prev = ecode;
-    saved_eptr = eptr;
-    save_mark = mb->mark;
-    do
-      {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM64);
-      if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
-        {
-        mstart = mb->start_match_ptr;
-        break;
-        }
-      if (rrc == MATCH_THEN)
-        {
-        next_ecode = ecode + GET(ecode,1);
-        if (mb->start_match_ptr < next_ecode &&
-            (*ecode == OP_ALT || *next_ecode == OP_ALT))
-          rrc = MATCH_NOMATCH;
-        }
-
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      ecode += GET(ecode,1);
-      mb->mark = save_mark;
-      }
-    while (*ecode == OP_ALT);
-
-    /* If hit the end of the group (which could be repeated), fail */
-
-    if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
-
-    /* Continue as from after the group, updating the offsets high water
-    mark, since extracts may have been taken. */
-
-    do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
-
-    offset_top = mb->end_offset_top;
-    eptr = mb->end_match_ptr;
-
-    /* For a non-repeating ket, just continue at this level. This also
-    happens for a repeating ket if no characters were matched in the group.
-    This is the forcible breaking of infinite loops as implemented in Perl
-    5.005. */
-
-    if (*ecode == OP_KET || eptr == saved_eptr)
-      {
-      ecode += 1+LINK_SIZE;
-      break;
-      }
-
-    /* The repeating kets try the rest of the pattern or restart from the
-    preceding bracket, in the appropriate order. The second "call" of match()
-    uses tail recursion, to avoid using another stack frame. */
-
-    if (*ecode == OP_KETRMIN)
-      {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM65);
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      ecode = prev;
-      goto TAIL_RECURSE;
-      }
-    else  /* OP_KETRMAX */
-      {
-      RMATCH(eptr, prev, offset_top, mb, eptrb, RM66);
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      ecode += 1 + LINK_SIZE;
-      goto TAIL_RECURSE;
-      }
-    /* Control never gets here */
-
-    /* Handle a capturing bracket, other than those that are possessive with an
-    unlimited repeat. If there is space in the offset vector, save the current
-    subject position in the working slot at the top of the vector. We mustn't
-    change the current values of the data slot, because they may be set from a
-    previous iteration of this group, and be referred to by a reference inside
-    the group. A failure to match might occur after the group has succeeded,
-    if something later on doesn't match. For this reason, we need to restore
-    the working value and also the values of the final offsets, in case they
-    were set by a previous iteration of the same bracket.
-
-    If there isn't enough space in the offset vector, treat this as if it were
-    a non-capturing bracket. Don't worry about setting the flag for the error
-    case here; that is handled in the code for KET. */
-
-    case OP_CBRA:
-    case OP_SCBRA:
-    number = GET2(ecode, 1+LINK_SIZE);
-    offset = number << 1;
-
-    if (offset < mb->offset_max)
-      {
-      save_offset1 = mb->ovector[offset];
-      save_offset2 = mb->ovector[offset+1];
-      save_offset3 = mb->ovector[mb->offset_end - number];
-      save_capture_last = mb->capture_last;
-      save_mark = mb->mark;
-
-      mb->ovector[mb->offset_end - number] = eptr - mb->start_subject;
-
-      for (;;)
-        {
-        if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP;
-        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
-          eptrb, RM1);
-        if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
-
-        /* If we backed up to a THEN, check whether it is within the current
-        branch by comparing the address of the THEN that is passed back with
-        the end of the branch. If it is within the current branch, and the
-        branch is one of two or more alternatives (it either starts or ends
-        with OP_ALT), we have reached the limit of THEN's action, so convert
-        the return code to NOMATCH, which will cause normal backtracking to
-        happen from now on. Otherwise, THEN is passed back to an outer
-        alternative. This implements Perl's treatment of parenthesized groups,
-        where a group not containing | does not affect the current alternative,
-        that is, (X) is NOT the same as (X|(*F)). */
-
-        if (rrc == MATCH_THEN)
-          {
-          next_ecode = ecode + GET(ecode,1);
-          if (mb->start_match_ptr < next_ecode &&
-              (*ecode == OP_ALT || *next_ecode == OP_ALT))
-            rrc = MATCH_NOMATCH;
-          }
-
-        /* Anything other than NOMATCH is passed back. */
-
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        mb->capture_last = save_capture_last;
-        ecode += GET(ecode, 1);
-        mb->mark = save_mark;
-        if (*ecode != OP_ALT) break;
-        }
-
-      mb->ovector[offset] = save_offset1;
-      mb->ovector[offset+1] = save_offset2;
-      mb->ovector[mb->offset_end - number] = save_offset3;
-
-      /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
-
-      RRETURN(rrc);
-      }
-
-    /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
-    as a non-capturing bracket. */
-
-    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
-    /* Non-capturing or atomic group, except for possessive with unlimited
-    repeat and ONCE group with no captures. Loop for all the alternatives.
-
-    When we get to the final alternative within the brackets, we used to return
-    the result of a recursive call to match() whatever happened so it was
-    possible to reduce stack usage by turning this into a tail recursion,
-    except in the case of a possibly empty group. However, now that there is
-    the possiblity of (*THEN) occurring in the final alternative, this
-    optimization is no longer always possible.
-
-    We can optimize if we know there are no (*THEN)s in the pattern; at present
-    this is the best that can be done.
-
-    MATCH_ONCE is returned when the end of an atomic group is successfully
-    reached, but subsequent matching fails. It passes back up the tree (causing
-    captured values to be reset) until the original atomic group level is
-    reached. This is tested by comparing mb->once_target with the start of the
-    group. At this point, the return is converted into MATCH_NOMATCH so that
-    previous backup points can be taken. */
-
-    case OP_ONCE:
-    case OP_BRA:
-    case OP_SBRA:
-
-    for (;;)
-      {
-      if (op >= OP_SBRA || op == OP_ONCE)
-        mb->match_function_type |= MATCH_CBEGROUP;
-
-      /* If this is not a possibly empty group, and there are no (*THEN)s in
-      the pattern, and this is the final alternative, optimize as described
-      above. */
-
-      else if (!mb->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
-        {
-        ecode += PRIV(OP_lengths)[*ecode];
-        goto TAIL_RECURSE;
-        }
-
-      /* In all other cases, we have to make another call to match(). */
-
-      save_mark = mb->mark;
-      save_capture_last = mb->capture_last;
-      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb, eptrb,
-        RM2);
-
-      /* See comment in the code for capturing groups above about handling
-      THEN. */
-
-      if (rrc == MATCH_THEN)
-        {
-        next_ecode = ecode + GET(ecode,1);
-        if (mb->start_match_ptr < next_ecode &&
-            (*ecode == OP_ALT || *next_ecode == OP_ALT))
-          rrc = MATCH_NOMATCH;
-        }
-
-      if (rrc != MATCH_NOMATCH)
-        {
-        if (rrc == MATCH_ONCE)
-          {
-          PCRE2_SPTR scode = ecode;
-          if (*scode != OP_ONCE)           /* If not at start, find it */
-            {
-            while (*scode == OP_ALT) scode += GET(scode, 1);
-            scode -= GET(scode, 1);
-            }
-          if (mb->once_target == scode) rrc = MATCH_NOMATCH;
-          }
-        RRETURN(rrc);
-        }
-      ecode += GET(ecode, 1);
-      mb->mark = save_mark;
-      if (*ecode != OP_ALT) break;
-      mb->capture_last = save_capture_last;
-      }
-
-    RRETURN(MATCH_NOMATCH);
-
-    /* Handle possessive capturing brackets with an unlimited repeat. We come
-    here from BRAZERO with allow_zero set TRUE. The ovector values are
-    handled similarly to the normal case above. However, the matching is
-    different. The end of these brackets will always be OP_KETRPOS, which
-    returns MATCH_KETRPOS without going further in the pattern. By this means
-    we can handle the group by iteration rather than recursion, thereby
-    reducing the amount of stack needed. If the ovector is too small for
-    capturing, treat as non-capturing. */
-
-    case OP_CBRAPOS:
-    case OP_SCBRAPOS:
-    allow_zero = FALSE;
-
-    POSSESSIVE_CAPTURE:
-    number = GET2(ecode, 1+LINK_SIZE);
-    offset = number << 1;
-    if (offset >= mb->offset_max) goto POSSESSIVE_NON_CAPTURE;
-
-    matched_once = FALSE;
-    code_offset = (int)(ecode - mb->start_code);
-
-    save_offset1 = mb->ovector[offset];
-    save_offset2 = mb->ovector[offset+1];
-    save_offset3 = mb->ovector[mb->offset_end - number];
-    save_capture_last = mb->capture_last;
-
-    /* Each time round the loop, save the current subject position for use
-    when the group matches. For MATCH_MATCH, the group has matched, so we
-    restart it with a new subject starting position, remembering that we had
-    at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
-    usual. If we haven't matched any alternatives in any iteration, check to
-    see if a previous iteration matched. If so, the group has matched;
-    continue from afterwards. Otherwise it has failed; restore the previous
-    capture values before returning NOMATCH. */
-
-    for (;;)
-      {
-      mb->ovector[mb->offset_end - number] = eptr - mb->start_subject;
-      if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP;
-      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
-        eptrb, RM63);
-      if (rrc == MATCH_KETRPOS)
-        {
-        offset_top = mb->end_offset_top;
-        ecode = mb->start_code + code_offset;
-        save_capture_last = mb->capture_last;
-        matched_once = TRUE;
-        mstart = mb->start_match_ptr;    /* In case \K changed it */
-        if (eptr == mb->end_match_ptr)   /* Matched an empty string */
-          {
-          do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
-          break;
-          }
-        eptr = mb->end_match_ptr;
-        continue;
-        }
-
-      /* See comment in the code for capturing groups above about handling
-      THEN. */
-
-      if (rrc == MATCH_THEN)
-        {
-        next_ecode = ecode + GET(ecode,1);
-        if (mb->start_match_ptr < next_ecode &&
-            (*ecode == OP_ALT || *next_ecode == OP_ALT))
-          rrc = MATCH_NOMATCH;
-        }
-
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      mb->capture_last = save_capture_last;
-      ecode += GET(ecode, 1);
-      if (*ecode != OP_ALT) break;
-      }
-
-    if (!matched_once)
-      {
-      mb->ovector[offset] = save_offset1;
-      mb->ovector[offset+1] = save_offset2;
-      mb->ovector[mb->offset_end - number] = save_offset3;
-      }
-
-    if (allow_zero || matched_once)
-      {
-      ecode += 1 + LINK_SIZE;
-      break;
-      }
-    RRETURN(MATCH_NOMATCH);
-
-    /* Non-capturing possessive bracket with unlimited repeat. We come here
-    from BRAZERO with allow_zero = TRUE. The code is similar to the above,
-    without the capturing complication. It is written out separately for speed
-    and cleanliness. */
-
-    case OP_BRAPOS:
-    case OP_SBRAPOS:
-    allow_zero = FALSE;
-
-    POSSESSIVE_NON_CAPTURE:
-    matched_once = FALSE;
-    code_offset = (int)(ecode - mb->start_code);
-    save_capture_last = mb->capture_last;
-
-    for (;;)
-      {
-      if (op >= OP_SBRA) mb->match_function_type |= MATCH_CBEGROUP;
-      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, mb,
-        eptrb, RM48);
-      if (rrc == MATCH_KETRPOS)
-        {
-        offset_top = mb->end_offset_top;
-        ecode = mb->start_code + code_offset;
-        matched_once = TRUE;
-        mstart = mb->start_match_ptr;   /* In case \K reset it */
-        if (eptr == mb->end_match_ptr)  /* Matched an empty string */
-          {
-          do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
-          break;
-          }
-        eptr = mb->end_match_ptr;
-        continue;
-        }
-
-      /* See comment in the code for capturing groups above about handling
-      THEN. */
-
-      if (rrc == MATCH_THEN)
-        {
-        next_ecode = ecode + GET(ecode,1);
-        if (mb->start_match_ptr < next_ecode &&
-            (*ecode == OP_ALT || *next_ecode == OP_ALT))
-          rrc = MATCH_NOMATCH;
-        }
-
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      ecode += GET(ecode, 1);
-      if (*ecode != OP_ALT) break;
-      mb->capture_last = save_capture_last;
-      }
-
-    if (matched_once || allow_zero)
-      {
-      ecode += 1 + LINK_SIZE;
-      break;
-      }
-    RRETURN(MATCH_NOMATCH);
-
-    /* Control never reaches here. */
-
-    /* Conditional group: compilation checked that there are no more than two
-    branches. If the condition is false, skipping the first branch takes us
-    past the end of the item if there is only one branch, but that's exactly
-    what we want. */
-
-    case OP_COND:
-    case OP_SCOND:
-
-    /* The variable codelink will be added to ecode when the condition is
-    false, to get to the second branch. Setting it to the offset to the ALT
-    or KET, then incrementing ecode achieves this effect. We now have ecode
-    pointing to the condition or callout. */
-
-    codelink = GET(ecode, 1);   /* Offset to the second branch */
-    ecode += 1 + LINK_SIZE;     /* From this opcode */
-
-    /* Because of the way auto-callout works during compile, a callout item is
-    inserted between OP_COND and an assertion condition. */
-
-    if (*ecode == OP_CALLOUT || *ecode == OP_CALLOUT_STR)
-      {
-      unsigned int callout_length = (*ecode == OP_CALLOUT)
-          ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE);
-
-      if (mb->callout != NULL)
-        {
-        pcre2_callout_block cb;
-        cb.version          = 1;
-        cb.capture_top      = offset_top/2;
-        cb.capture_last     = mb->capture_last & CAPLMASK;
-        cb.offset_vector    = mb->ovector;
-        cb.mark             = mb->nomatch_mark;
-        cb.subject          = mb->start_subject;
-        cb.subject_length   = (PCRE2_SIZE)(mb->end_subject - mb->start_subject);
-        cb.start_match      = (PCRE2_SIZE)(mstart - mb->start_subject);
-        cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject);
-        cb.pattern_position = GET(ecode, 1);
-        cb.next_item_length = GET(ecode, 1 + LINK_SIZE);
-
-        if (*ecode == OP_CALLOUT)
-          {
-          cb.callout_number = ecode[1 + 2*LINK_SIZE];
-          cb.callout_string_offset = 0;
-          cb.callout_string = NULL;
-          cb.callout_string_length = 0;
-          }
-        else
-          {
-          cb.callout_number = 0;
-          cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE);
-          cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1;
-          cb.callout_string_length =
-            callout_length - (1 + 4*LINK_SIZE) - 2;
-          }
-
-        if ((rrc = mb->callout(&cb, mb->callout_data)) > 0)
-          RRETURN(MATCH_NOMATCH);
-        if (rrc < 0) RRETURN(rrc);
-        }
-
-      /* Advance ecode past the callout, so it now points to the condition. We
-      must adjust codelink so that the value of ecode+codelink is unchanged. */
-
-      ecode += callout_length;
-      codelink -= callout_length;
-      }
-
-    /* Test the various possible conditions */
-
-    condition = FALSE;
-    switch(condcode = *ecode)
-      {
-      case OP_RREF:                  /* Numbered group recursion test */
-      if (mb->recursive != NULL)     /* Not recursing => FALSE */
-        {
-        uint32_t recno = GET2(ecode, 1);   /* Recursion group number*/
-        condition = (recno == RREF_ANY || recno == mb->recursive->group_num);
-        }
-      break;
-
-      case OP_DNRREF:       /* Duplicate named group recursion test */
-      if (mb->recursive != NULL)
-        {
-        int count = GET2(ecode, 1 + IMM2_SIZE);
-        PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size;
-        while (count-- > 0)
-          {
-          uint32_t recno = GET2(slot, 0);
-          condition = recno == mb->recursive->group_num;
-          if (condition) break;
-          slot += mb->name_entry_size;
-          }
-        }
-      break;
-
-      case OP_CREF:                  /* Numbered group used test */
-      offset = GET2(ecode, 1) << 1;  /* Doubled ref number */
-      condition = offset < offset_top &&
-        mb->ovector[offset] != PCRE2_UNSET;
-      break;
-
-      case OP_DNCREF:      /* Duplicate named group used test */
-        {
-        int count = GET2(ecode, 1 + IMM2_SIZE);
-        PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size;
-        while (count-- > 0)
-          {
-          offset = GET2(slot, 0) << 1;
-          condition = offset < offset_top &&
-            mb->ovector[offset] != PCRE2_UNSET;
-          if (condition) break;
-          slot += mb->name_entry_size;
-          }
-        }
-      break;
-
-      case OP_FALSE:
-      case OP_FAIL:   /* The assertion (?!) becomes OP_FAIL */
-      break;
-
-      case OP_TRUE:
-      condition = TRUE;
-      break;
-
-      /* The condition is an assertion. Call match() to evaluate it - setting
-      the MATCH_CONDASSERT bit in mb->match_function_type causes it to stop at
-      the end of an assertion. */
-
-      default:
-      mb->match_function_type |= MATCH_CONDASSERT;
-      RMATCH(eptr, ecode, offset_top, mb, NULL, RM3);
-      if (rrc == MATCH_MATCH)
-        {
-        if (mb->end_offset_top > offset_top)
-          offset_top = mb->end_offset_top;  /* Captures may have happened */
-        condition = TRUE;
-
-        /* Advance ecode past the assertion to the start of the first branch,
-        but adjust it so that the general choosing code below works. If the
-        assertion has a quantifier that allows zero repeats we must skip over
-        the BRAZERO. This is a lunatic thing to do, but somebody did! */
-
-        if (*ecode == OP_BRAZERO) ecode++;
-        ecode += GET(ecode, 1);
-        while (*ecode == OP_ALT) ecode += GET(ecode, 1);
-        ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
-        }
-
-      /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
-      assertion; it is therefore treated as NOMATCH. Any other return is an
-      error. */
-
-      else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
-        {
-        RRETURN(rrc);         /* Need braces because of following else */
-        }
-      break;
-      }
-
-    /* Choose branch according to the condition */
-
-    ecode += condition? PRIV(OP_lengths)[condcode] : codelink;
-
-    /* We are now at the branch that is to be obeyed. As there is only one, we
-    can use tail recursion to avoid using another stack frame, except when
-    there is unlimited repeat of a possibly empty group. In the latter case, a
-    recursive call to match() is always required, unless the second alternative
-    doesn't exist, in which case we can just plough on. Note that, for
-    compatibility with Perl, the | in a conditional group is NOT treated as
-    creating two alternatives. If a THEN is encountered in the branch, it
-    propagates out to the enclosing alternative (unless nested in a deeper set
-    of alternatives, of course). */
-
-    if (condition || ecode[-(1+LINK_SIZE)] == OP_ALT)
-      {
-      if (op != OP_SCOND)
-        {
-        goto TAIL_RECURSE;
-        }
-
-      mb->match_function_type |= MATCH_CBEGROUP;
-      RMATCH(eptr, ecode, offset_top, mb, eptrb, RM49);
-      RRETURN(rrc);
-      }
-
-     /* Condition false & no alternative; continue after the group. */
-
-    else
-      {
-      }
-    break;
-
-
-    /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
-    to close any currently open capturing brackets. */
+    /* ===================================================================== */
+    /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, to close
+    any currently open capturing brackets. Unlike reaching the end of a group,
+    where we know the starting frame is at the top of the chained frames, in
+    this case we have to search back for the relevant frame in case other types
+    of group that use chained frames have intervened. Multiple OP_CLOSEs always
+    come innermost first, which matches the chain order. We can ignore this in
+    a recursion, because captures are not passed out of recursions. */
 
     case OP_CLOSE:
-    number = GET2(ecode, 1);   /* Must be less than 65536 */
-    offset = number << 1;
-    mb->capture_last = (mb->capture_last & OVFLMASK) | number;
-    if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else
+    if (Fcurrent_recurse == RECURSE_UNSET)
       {
-      mb->ovector[offset] =
-        mb->ovector[mb->offset_end - number];
-      mb->ovector[offset+1] = eptr - mb->start_subject;
-
-      /* If this group is at or above the current highwater mark, ensure that
-      any groups between the current high water mark and this group are marked
-      unset and then update the high water mark. */
-
-      if (offset >= offset_top)
+      number = GET2(Fecode, 1);
+      offset = Flast_group_offset;
+      for(;;)
         {
-        register PCRE2_SIZE *iptr = mb->ovector + offset_top;
-        register PCRE2_SIZE *iend = mb->ovector + offset;
-        while (iptr < iend) *iptr++ = PCRE2_UNSET;
-        offset_top = offset + 2;
+        if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
+        N = (heapframe *)((char *)mb->match_frames + offset);
+        P = (heapframe *)((char *)N - frame_size);
+        if (N->group_frame_type == (GF_CAPTURE | number)) break;
+        offset = P->last_group_offset;
         }
+      offset = (number << 1) - 2;
+      Fcapture_last = number;
+      Fovector[offset] = P->eptr - mb->start_subject;
+      Fovector[offset+1] = Feptr - mb->start_subject;
+      if (offset >= Foffset_top) Foffset_top = offset + 2;
       }
-    ecode += 1 + IMM2_SIZE;
+    Fecode += PRIV(OP_lengths)[*Fecode];
     break;
 
 
-    /* End of the pattern, either real or forced. In an assertion ACCEPT,
-    update the last used pointer. */
+    /* ===================================================================== */
+    /* Real or forced end of the pattern, assertion, or recursion. In an
+    assertion ACCEPT, update the last used pointer and remember the current
+    frame so that the captures can be fished out of it. */
 
     case OP_ASSERT_ACCEPT:
-    if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
+    if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
+    assert_accept_frame = F;
+    RRETURN(MATCH_ACCEPT);
+
+    /* If recursing, we have to find the most recent recursion. */
 
     case OP_ACCEPT:
     case OP_END:
 
-    /* If we have matched an empty string, fail if not in an assertion and not
-    in a recursion if either PCRE2_NOTEMPTY is set, or if PCRE2_NOTEMPTY_ATSTART
-    is set and we have matched at the start of the subject. In both cases,
-    backtracking will then try other alternatives, if any. */
+    /* Handle end of a recursion. */
 
-    if (eptr == mstart && op != OP_ASSERT_ACCEPT &&
-         mb->recursive == NULL &&
+    if (Fcurrent_recurse != RECURSE_UNSET)
+      {
+      offset = Flast_group_offset;
+      for(;;)
+        {
+        if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
+        N = (heapframe *)((char *)mb->match_frames + offset);
+        P = (heapframe *)((char *)N - frame_size);
+        if (GF_IDMASK(N->group_frame_type) == GF_RECURSE) break;
+        offset = P->last_group_offset;
+        }
+
+      /* N is now the frame of the recursion; the previous frame is at the
+      OP_RECURSE position. Go back there, copying the current subject position
+      and mark, and move on past the OP_RECURSE. */
+
+      P->eptr = Feptr;
+      P->mark = Fmark;
+      F = P;
+      Fecode += 1 + LINK_SIZE;
+      continue;
+      }
+
+    /* Not a recursion. Fail for an empty string match if either PCRE2_NOTEMPTY
+    is set, or if PCRE2_NOTEMPTY_ATSTART is set and we have matched at the
+    start of the subject. In both cases, backtracking will then try other
+    alternatives, if any. */
+
+    if (Feptr == Fstart_match &&
          ((mb->moptions & PCRE2_NOTEMPTY) != 0 ||
            ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 &&
-             mstart == mb->start_subject + mb->start_offset)))
+             Fstart_match == mb->start_subject + mb->start_offset)))
       RRETURN(MATCH_NOMATCH);
 
-    /* Otherwise, we have a match. */
+    /* Also fail if PCRE2_ENDANCHORED is set and the end of the match is not
+    the end of the subject. After (*ACCEPT) we fail the entire match (at this
+    position) but backtrack on reaching the end of the pattern. */
 
-    mb->end_match_ptr = eptr;           /* Record where we ended */
-    mb->end_offset_top = offset_top;    /* and how many extracts were taken */
-    mb->start_match_ptr = mstart;       /* and the start (\K can modify) */
-
-    /* For some reason, the macros don't work properly if an expression is
-    given as the argument to RRETURN when the heap is in use. */
-
-    rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
-    RRETURN(rrc);
-
-    /* Assertion brackets. Check the alternative branches in turn - the
-    matching won't pass the KET for an assertion. If any one branch matches,
-    the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
-    start of each branch to move the current point backwards, so the code at
-    this level is identical to the lookahead case. When the assertion is part
-    of a condition, we want to return immediately afterwards. The caller of
-    this incarnation of the match() function will have set MATCH_CONDASSERT in
-    mb->match_function type, and one of these opcodes will be the first opcode
-    that is processed. We use a local variable that is preserved over calls to
-    match() to remember this case. */
-
-    case OP_ASSERT:
-    case OP_ASSERTBACK:
-    save_mark = mb->mark;
-    if ((mb->match_function_type & MATCH_CONDASSERT) != 0)
+    if (Feptr < mb->end_subject &&
+        ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)
       {
-      condassert = TRUE;
-      mb->match_function_type &= ~MATCH_CONDASSERT;
-      }
-    else condassert = FALSE;
-
-    /* Loop for each branch */
-
-    do
-      {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM4);
-
-      /* A match means that the assertion is true; break out of the loop
-      that matches its alternatives. */
-
-      if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
-        {
-        mstart = mb->start_match_ptr;   /* In case \K reset it */
-        break;
-        }
-
-      /* If not matched, restore the previous mark setting. */
-
-      mb->mark = save_mark;
-
-      /* See comment in the code for capturing groups above about handling
-      THEN. */
-
-      if (rrc == MATCH_THEN)
-        {
-        next_ecode = ecode + GET(ecode,1);
-        if (mb->start_match_ptr < next_ecode &&
-            (*ecode == OP_ALT || *next_ecode == OP_ALT))
-          rrc = MATCH_NOMATCH;
-        }
-
-      /* Anything other than NOMATCH causes the entire assertion to fail,
-      passing back the return code. This includes COMMIT, SKIP, PRUNE and an
-      uncaptured THEN, which means they take their normal effect. This
-      consistent approach does not always have exactly the same effect as in
-      Perl. */
-
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      ecode += GET(ecode, 1);
-      }
-    while (*ecode == OP_ALT);   /* Continue for next alternative */
-
-    /* If we have tried all the alternative branches, the assertion has
-    failed. If not, we broke out after a match. */
-
-    if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
-
-    /* If checking an assertion for a condition, return MATCH_MATCH. */
-
-    if (condassert) RRETURN(MATCH_MATCH);
-
-    /* Continue from after a successful assertion, updating the offsets high
-    water mark, since extracts may have been taken during the assertion. */
-
-    do ecode += GET(ecode,1); while (*ecode == OP_ALT);
-    ecode += 1 + LINK_SIZE;
-    offset_top = mb->end_offset_top;
-    continue;
-
-    /* Negative assertion: all branches must fail to match for the assertion to
-    succeed. */
-
-    case OP_ASSERT_NOT:
-    case OP_ASSERTBACK_NOT:
-    save_mark = mb->mark;
-    if ((mb->match_function_type & MATCH_CONDASSERT) != 0)
-      {
-      condassert = TRUE;
-      mb->match_function_type &= ~MATCH_CONDASSERT;
-      }
-    else condassert = FALSE;
-
-    /* Loop for each alternative branch. */
-
-    do
-      {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, NULL, RM5);
-      mb->mark = save_mark;   /* Always restore the mark setting */
-
-      switch(rrc)
-        {
-        case MATCH_MATCH:            /* A successful match means */
-        case MATCH_ACCEPT:           /* the assertion has failed. */
-        RRETURN(MATCH_NOMATCH);
-
-        case MATCH_NOMATCH:          /* Carry on with next branch */
-        break;
-
-        /* See comment in the code for capturing groups above about handling
-        THEN. */
-
-        case MATCH_THEN:
-        next_ecode = ecode + GET(ecode,1);
-        if (mb->start_match_ptr < next_ecode &&
-            (*ecode == OP_ALT || *next_ecode == OP_ALT))
-          {
-          rrc = MATCH_NOMATCH;
-          break;
-          }
-        /* Otherwise fall through. */
-
-        /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole
-        assertion to fail to match, without considering any more alternatives.
-        Failing to match means the assertion is true. This is a consistent
-        approach, but does not always have the same effect as in Perl. */
-
-        case MATCH_COMMIT:
-        case MATCH_SKIP:
-        case MATCH_SKIP_ARG:
-        case MATCH_PRUNE:
-        do ecode += GET(ecode,1); while (*ecode == OP_ALT);
-        goto NEG_ASSERT_TRUE;   /* Break out of alternation loop */
-
-        /* Anything else is an error */
-
-        default:
-        RRETURN(rrc);
-        }
-
-      /* Continue with next branch */
-
-      ecode += GET(ecode,1);
-      }
-    while (*ecode == OP_ALT);
-
-    /* All branches in the assertion failed to match. */
-
-    NEG_ASSERT_TRUE:
-    if (condassert) RRETURN(MATCH_MATCH);  /* Condition assertion */
-    ecode += 1 + LINK_SIZE;                /* Continue with current branch */
-    continue;
-
-    /* Move the subject pointer back. This occurs only at the start of
-    each branch of a lookbehind assertion. If we are too close to the start to
-    move back, this match function fails. When working with UTF-8 we move
-    back a number of characters, not bytes. */
-
-    case OP_REVERSE:
-    i = GET(ecode, 1);
-#ifdef SUPPORT_UNICODE
-    if (utf)
-      {
-      while (i-- > 0)
-        {
-        if (eptr <= mb->start_subject) RRETURN(MATCH_NOMATCH);
-        eptr--;
-        BACKCHAR(eptr);
-        }
-      }
-    else
-#endif
-
-    /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
-
-      {
-      if (i > eptr - mb->start_subject) RRETURN(MATCH_NOMATCH);
-      eptr -= i;
+      if (Fop == OP_END) RRETURN(MATCH_NOMATCH);
+      return MATCH_NOMATCH;
       }
 
-    /* Save the earliest consulted character, then skip to next op code */
+    /* We have a successful match of the whole pattern. Record the result and
+    then do a direct return from the function. If there is space in the offset
+    vector, set any pairs that follow the highest-numbered captured string but
+    are less than the number of capturing groups in the pattern to PCRE2_UNSET.
+    It is documented that this happens. "Gaps" are set to PCRE2_UNSET
+    dynamically. It is only those at the end that need setting here. */
 
-    if (eptr < mb->start_used_ptr) mb->start_used_ptr = eptr;
-    ecode += 1 + LINK_SIZE;
-    break;
+    mb->end_match_ptr = Feptr;           /* Record where we ended */
+    mb->end_offset_top = Foffset_top;    /* and how many extracts were taken */
+    mb->mark = Fmark;                    /* and the last success mark */
+    if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
 
-    /* The callout item calls an external function, if one is provided, passing
-    details of the match so far. This is mainly for debugging, though the
-    function is able to force a failure. */
+    ovector[0] = Fstart_match - mb->start_subject;
+    ovector[1] = Feptr - mb->start_subject;
 
-    case OP_CALLOUT:
-    case OP_CALLOUT_STR:
-      {
-      unsigned int callout_length = (*ecode == OP_CALLOUT)
-          ? PRIV(OP_lengths)[OP_CALLOUT] : GET(ecode, 1 + 2*LINK_SIZE);
+    /* Set i to the smaller of the sizes of the external and frame ovectors. */
 
-      if (mb->callout != NULL)
-        {
-        pcre2_callout_block cb;
-        cb.version          = 1;
-        cb.callout_number   = ecode[LINK_SIZE + 1];
-        cb.capture_top      = offset_top/2;
-        cb.capture_last     = mb->capture_last & CAPLMASK;
-        cb.offset_vector    = mb->ovector;
-        cb.mark             = mb->nomatch_mark;
-        cb.subject          = mb->start_subject;
-        cb.subject_length   = (PCRE2_SIZE)(mb->end_subject - mb->start_subject);
-        cb.start_match      = (PCRE2_SIZE)(mstart - mb->start_subject);
-        cb.current_position = (PCRE2_SIZE)(eptr - mb->start_subject);
-        cb.pattern_position = GET(ecode, 1);
-        cb.next_item_length = GET(ecode, 1 + LINK_SIZE);
+    i = 2 * ((top_bracket + 1 > oveccount)? oveccount : top_bracket + 1);
+    memcpy(ovector + 2, Fovector, (i - 2) * sizeof(PCRE2_SIZE));
+    while (--i >= Foffset_top + 2) ovector[i] = PCRE2_UNSET;
+    return MATCH_MATCH;  /* Note: NOT RRETURN */
 
-        if (*ecode == OP_CALLOUT)
-          {
-          cb.callout_number = ecode[1 + 2*LINK_SIZE];
-          cb.callout_string_offset = 0;
-          cb.callout_string = NULL;
-          cb.callout_string_length = 0;
-          }
-        else
-          {
-          cb.callout_number = 0;
-          cb.callout_string_offset = GET(ecode, 1 + 3*LINK_SIZE);
-          cb.callout_string = ecode + (1 + 4*LINK_SIZE) + 1;
-          cb.callout_string_length =
-            callout_length - (1 + 4*LINK_SIZE) - 2;
-          }
 
-        if ((rrc = mb->callout(&cb, mb->callout_data)) > 0)
-          RRETURN(MATCH_NOMATCH);
-        if (rrc < 0) RRETURN(rrc);
-        }
-      ecode += callout_length;
-      }
-    break;
-
-    /* Recursion either matches the current regex, or some subexpression. The
-    offset data is the offset to the starting bracket from the start of the
-    whole pattern. (This is so that it works from duplicated subpatterns.)
-
-    The state of the capturing groups is preserved over recursion, and
-    re-instated afterwards. We don't know how many are started and not yet
-    finished (offset_top records the completed total) so we just have to save
-    all the potential data. There may be up to 65535 such values, which is too
-    large to put on the stack, but using malloc for small numbers seems
-    expensive. As a compromise, the stack is used when there are no more than
-    OP_RECURSE_STACK_SAVE_MAX values to store; otherwise malloc is used.
-
-    There are also other values that have to be saved. We use a chained
-    sequence of blocks that actually live on the stack. Thanks to Robin Houston
-    for the original version of this logic. It has, however, been hacked around
-    a lot, so he is not to blame for the current way it works. */
-
-    case OP_RECURSE:
-      {
-      ovecsave_frame *fr;
-      recursion_info *ri;
-      uint32_t recno;
-
-      callpat = mb->start_code + GET(ecode, 1);
-      recno = (callpat == mb->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE);
-
-      /* Check for repeating a pattern recursion without advancing the subject
-      pointer. This should catch convoluted mutual recursions. (Some simple
-      cases are caught at compile time.) */
-
-      for (ri = mb->recursive; ri != NULL; ri = ri->prevrec)
-        if (recno == ri->group_num && eptr == ri->subject_position)
-          RRETURN(PCRE2_ERROR_RECURSELOOP);
-
-      /* Add to "recursing stack" */
-
-      new_recursive.group_num = recno;
-      new_recursive.saved_capture_last = mb->capture_last;
-      new_recursive.subject_position = eptr;
-      new_recursive.prevrec = mb->recursive;
-      mb->recursive = &new_recursive;
-
-      /* Where to continue from afterwards */
-
-      ecode += 1 + LINK_SIZE;
-
-      /* When we are using the system stack for match() recursion we can call a
-      function that uses the system stack for preserving the ovector while
-      processing the pattern recursion, but only if the ovector is small
-      enough. */
-
-#ifndef HEAP_MATCH_RECURSE
-      if (mb->offset_end <= OP_RECURSE_STACK_SAVE_MAX)
-        {
-        rrc = op_recurse_ovecsave(eptr, callpat, mstart, offset_top, mb,
-          eptrb, rdepth);
-        mb->recursive = new_recursive.prevrec;
-        if (rrc != MATCH_MATCH && rrc != MATCH_ACCEPT) RRETURN(rrc);
-
-        /* Set where we got to in the subject, and reset the start, in case
-        it was changed by \K. This *is* propagated back out of a recursion,
-        for Perl compatibility. */
-
-        eptr = mb->end_match_ptr;
-        mstart = mb->start_match_ptr;
-        break;   /* End of processing OP_RECURSE */
-        }
-#endif
-      /* If the ovector is too big, or if we are using the heap for match()
-      recursion, we have to use the heap for saving the ovector. Used ovecsave
-      frames are kept on a chain and re-used. This makes a small improvement in
-      execution time on Linux. */
-
-      if (mb->ovecsave_chain != NULL)
-        {
-        new_recursive.ovec_save = mb->ovecsave_chain->saved_ovec;
-        mb->ovecsave_chain = mb->ovecsave_chain->next;
-        }
-      else
-        {
-        fr = (ovecsave_frame *)(mb->memctl.malloc(sizeof(ovecsave_frame *) +
-          mb->offset_end * sizeof(PCRE2_SIZE), mb->memctl.memory_data));
-        if (fr == NULL) RRETURN(PCRE2_ERROR_NOMEMORY);
-        new_recursive.ovec_save = fr->saved_ovec;
-        }
-
-      memcpy(new_recursive.ovec_save, mb->ovector,
-        mb->offset_end * sizeof(PCRE2_SIZE));
-
-      /* Do the recursion. After processing each alternative, restore the
-      ovector data and the last captured value. This code has the same overall
-      logic as the code in the op_recurse_ovecsave() function, but is adapted
-      to use RMATCH/RRETURN and to release the heap block containing the saved
-      ovector. */
-
-      cbegroup = (*callpat >= OP_SBRA);
-      do
-        {
-        if (cbegroup) mb->match_function_type |= MATCH_CBEGROUP;
-        RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
-          mb, eptrb, RM6);
-        memcpy(mb->ovector, new_recursive.ovec_save,
-            mb->offset_end * sizeof(PCRE2_SIZE));
-        mb->capture_last = new_recursive.saved_capture_last;
-        mb->recursive = new_recursive.prevrec;
-
-        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
-          {
-          fr = (ovecsave_frame *)
-            ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *));
-          fr->next = mb->ovecsave_chain;
-          mb->ovecsave_chain = fr;
-
-          /* Set where we got to in the subject, and reset the start, in case
-          it was changed by \K. This *is* propagated back out of a recursion,
-          for Perl compatibility. */
-
-          eptr = mb->end_match_ptr;
-          mstart = mb->start_match_ptr;
-          goto RECURSION_MATCHED;        /* Exit loop; end processing */
-          }
-
-        /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
-        recursion; they cause a NOMATCH for the entire recursion. These codes
-        are defined in a range that can be tested for. */
-
-        if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
-          {
-          rrc = MATCH_NOMATCH;
-          goto RECURSION_RETURN;
-          }
-
-        /* Any return code other than NOMATCH is an error. */
-
-        if (rrc != MATCH_NOMATCH) goto RECURSION_RETURN;
-        mb->recursive = &new_recursive;
-        callpat += GET(callpat, 1);
-        }
-      while (*callpat == OP_ALT);
-
-      RECURSION_RETURN:
-      mb->recursive = new_recursive.prevrec;
-      fr = (ovecsave_frame *)
-        ((uint8_t *)new_recursive.ovec_save - sizeof(ovecsave_frame *));
-      fr->next = mb->ovecsave_chain;
-      mb->ovecsave_chain = fr;
-      RRETURN(rrc);
-      }
-
-    RECURSION_MATCHED:
-    break;
-
-    /* An alternation is the end of a branch; scan along to find the end of the
-    bracketed group and go to there. */
-
-    case OP_ALT:
-    do ecode += GET(ecode,1); while (*ecode == OP_ALT);
-    break;
-
-    /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
-    indicating that it may occur zero times. It may repeat infinitely, or not
-    at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
-    with fixed upper repeat limits are compiled as a number of copies, with the
-    optional ones preceded by BRAZERO or BRAMINZERO. */
-
-    case OP_BRAZERO:
-    next_ecode = ecode + 1;
-    RMATCH(eptr, next_ecode, offset_top, mb, eptrb, RM10);
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT);
-    ecode = next_ecode + 1 + LINK_SIZE;
-    break;
-
-    case OP_BRAMINZERO:
-    next_ecode = ecode + 1;
-    do next_ecode += GET(next_ecode, 1); while (*next_ecode == OP_ALT);
-    RMATCH(eptr, next_ecode + 1+LINK_SIZE, offset_top, mb, eptrb, RM11);
-    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-    ecode++;
-    break;
-
-    case OP_SKIPZERO:
-    next_ecode = ecode+1;
-    do next_ecode += GET(next_ecode,1); while (*next_ecode == OP_ALT);
-    ecode = next_ecode + 1 + LINK_SIZE;
-    break;
-
-    /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything
-    here; just jump to the group, with allow_zero set TRUE. */
-
-    case OP_BRAPOSZERO:
-    op = *(++ecode);
-    allow_zero = TRUE;
-    if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE;
-      goto POSSESSIVE_NON_CAPTURE;
-
-    /* End of a group, repeated or non-repeating. */
-
-    case OP_KET:
-    case OP_KETRMIN:
-    case OP_KETRMAX:
-    case OP_KETRPOS:
-    prev = ecode - GET(ecode, 1);
-
-    /* If this was a group that remembered the subject start, in order to break
-    infinite repeats of empty string matches, retrieve the subject start from
-    the chain. Otherwise, set it NULL. */
-
-    if (*prev >= OP_SBRA || *prev == OP_ONCE)
-      {
-      saved_eptr = eptrb->epb_saved_eptr;   /* Value at start of group */
-      eptrb = eptrb->epb_prev;              /* Backup to previous group */
-      }
-    else saved_eptr = NULL;
-
-    /* If we are at the end of an assertion group or a non-capturing atomic
-    group, stop matching and return MATCH_MATCH, but record the current high
-    water mark for use by positive assertions. We also need to record the match
-    start in case it was changed by \K. */
-
-    if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
-         *prev == OP_ONCE_NC)
-      {
-      mb->end_match_ptr = eptr;      /* For ONCE_NC */
-      mb->end_offset_top = offset_top;
-      mb->start_match_ptr = mstart;
-      if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
-      RRETURN(MATCH_MATCH);         /* Sets mb->mark */
-      }
-
-    /* For capturing groups we have to check the group number back at the start
-    and if necessary complete handling an extraction by setting the offsets and
-    bumping the high water mark. Whole-pattern recursion is coded as a recurse
-    into group 0, so it won't be picked up here. Instead, we catch it when the
-    OP_END is reached. Other recursion is handled here. We just have to record
-    the current subject position and start match pointer and give a MATCH
-    return. */
-
-    if (*prev == OP_CBRA || *prev == OP_SCBRA ||
-        *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS)
-      {
-      number = GET2(prev, 1+LINK_SIZE);
-      offset = number << 1;
-
-      /* Handle a recursively called group. */
-
-      if (mb->recursive != NULL && mb->recursive->group_num == number)
-        {
-        mb->end_match_ptr = eptr;
-        mb->start_match_ptr = mstart;
-        if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
-        RRETURN(MATCH_MATCH);
-        }
-
-      /* Deal with capturing */
-
-      mb->capture_last = (mb->capture_last & OVFLMASK) | number;
-      if (offset >= mb->offset_max) mb->capture_last |= OVFLBIT; else
-        {
-        /* If offset is greater than offset_top, it means that we are
-        "skipping" a capturing group, and that group's offsets must be marked
-        unset. In earlier versions of PCRE, all the offsets were unset at the
-        start of matching, but this doesn't work because atomic groups and
-        assertions can cause a value to be set that should later be unset.
-        Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as
-        part of the atomic group, but this is not on the final matching path,
-        so must be unset when 2 is set. (If there is no group 2, there is no
-        problem, because offset_top will then be 2, indicating no capture.) */
-
-        if (offset > offset_top)
-          {
-          register PCRE2_SIZE *iptr = mb->ovector + offset_top;
-          register PCRE2_SIZE *iend = mb->ovector + offset;
-          while (iptr < iend) *iptr++ = PCRE2_UNSET;
-          }
-
-        /* Now make the extraction */
-
-        mb->ovector[offset] = mb->ovector[mb->offset_end - number];
-        mb->ovector[offset+1] = eptr - mb->start_subject;
-        if (offset_top <= offset) offset_top = offset + 2;
-        }
-      }
-
-    /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
-    and return the MATCH_KETRPOS. This makes it possible to do the repeats one
-    at a time from the outer level, thus saving stack. This must precede the
-    empty string test - in this case that test is done at the outer level. */
-
-    if (*ecode == OP_KETRPOS)
-      {
-      mb->start_match_ptr = mstart;    /* In case \K reset it */
-      mb->end_match_ptr = eptr;
-      mb->end_offset_top = offset_top;
-      if (eptr > mb->last_used_ptr) mb->last_used_ptr = eptr;
-      RRETURN(MATCH_KETRPOS);
-      }
-
-    /* For an ordinary non-repeating ket, just continue at this level. This
-    also happens for a repeating ket if no characters were matched in the
-    group. This is the forcible breaking of infinite loops as implemented in
-    Perl 5.005. For a non-repeating atomic group that includes captures,
-    establish a backup point by processing the rest of the pattern at a lower
-    level. If this results in a NOMATCH return, pass MATCH_ONCE back to the
-    original OP_ONCE level, thereby bypassing intermediate backup points, but
-    resetting any captures that happened along the way. */
-
-    if (*ecode == OP_KET || eptr == saved_eptr)
-      {
-      if (*prev == OP_ONCE)
-        {
-        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM12);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        mb->once_target = prev;  /* Level at which to change to MATCH_NOMATCH */
-        RRETURN(MATCH_ONCE);
-        }
-      ecode += 1 + LINK_SIZE;    /* Carry on at this level */
-      break;
-      }
-
-    /* The normal repeating kets try the rest of the pattern or restart from
-    the preceding bracket, in the appropriate order. In the second case, we can
-    use tail recursion to avoid using another stack frame, unless we have an
-    an atomic group or an unlimited repeat of a group that can match an empty
-    string. */
-
-    if (*ecode == OP_KETRMIN)
-      {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM7);
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      if (*prev == OP_ONCE)
-        {
-        RMATCH(eptr, prev, offset_top, mb, eptrb, RM8);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        mb->once_target = prev;  /* Level at which to change to MATCH_NOMATCH */
-        RRETURN(MATCH_ONCE);
-        }
-      if (*prev >= OP_SBRA)    /* Could match an empty string */
-        {
-        RMATCH(eptr, prev, offset_top, mb, eptrb, RM50);
-        RRETURN(rrc);
-        }
-      ecode = prev;
-      goto TAIL_RECURSE;
-      }
-    else  /* OP_KETRMAX */
-      {
-      RMATCH(eptr, prev, offset_top, mb, eptrb, RM13);
-      if (rrc == MATCH_ONCE && mb->once_target == prev) rrc = MATCH_NOMATCH;
-      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-      if (*prev == OP_ONCE)
-        {
-        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, mb, eptrb, RM9);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        mb->once_target = prev;
-        RRETURN(MATCH_ONCE);
-        }
-      ecode += 1 + LINK_SIZE;
-      goto TAIL_RECURSE;
-      }
-    /* Control never gets here */
-
-    /* Not multiline mode: start of subject assertion, unless notbol. */
-
-    case OP_CIRC:
-    if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject)
-      RRETURN(MATCH_NOMATCH);
-
-    /* Start of subject assertion */
-
-    case OP_SOD:
-    if (eptr != mb->start_subject) RRETURN(MATCH_NOMATCH);
-    ecode++;
-    break;
-
-    /* Multiline mode: start of subject unless notbol, or after any newline
-    except for one at the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */
-
-    case OP_CIRCM:
-    if ((mb->moptions & PCRE2_NOTBOL) != 0 && eptr == mb->start_subject)
-      RRETURN(MATCH_NOMATCH);
-    if (eptr != mb->start_subject &&
-        ((eptr == mb->end_subject &&
-           (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) ||
-         !WAS_NEWLINE(eptr)))
-      RRETURN(MATCH_NOMATCH);
-    ecode++;
-    break;
-
-    /* Start of match assertion */
-
-    case OP_SOM:
-    if (eptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH);
-    ecode++;
-    break;
-
-    /* Reset the start of match point */
-
-    case OP_SET_SOM:
-    mstart = eptr;
-    ecode++;
-    break;
-
-    /* Multiline mode: assert before any newline, or before end of subject
-    unless noteol is set. */
-
-    case OP_DOLLM:
-    if (eptr < mb->end_subject)
-      {
-      if (!IS_NEWLINE(eptr))
-        {
-        if (mb->partial != 0 &&
-            eptr + 1 >= mb->end_subject &&
-            NLBLOCK->nltype == NLTYPE_FIXED &&
-            NLBLOCK->nllen == 2 &&
-            UCHAR21TEST(eptr) == NLBLOCK->nl[0])
-          {
-          mb->hitend = TRUE;
-          if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
-          }
-        RRETURN(MATCH_NOMATCH);
-        }
-      }
-    else
-      {
-      if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
-      SCHECK_PARTIAL();
-      }
-    ecode++;
-    break;
-
-    /* Not multiline mode: assert before a terminating newline or before end of
-    subject unless noteol is set. */
-
-    case OP_DOLL:
-    if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
-    if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;
-
-    /* ... else fall through for endonly */
-
-    /* End of subject assertion (\z) */
-
-    case OP_EOD:
-    if (eptr < mb->end_subject) RRETURN(MATCH_NOMATCH);
-    SCHECK_PARTIAL();
-    ecode++;
-    break;
-
-    /* End of subject or ending \n assertion (\Z) */
-
-    case OP_EODN:
-    ASSERT_NL_OR_EOS:
-    if (eptr < mb->end_subject &&
-        (!IS_NEWLINE(eptr) || eptr != mb->end_subject - mb->nllen))
-      {
-      if (mb->partial != 0 &&
-          eptr + 1 >= mb->end_subject &&
-          NLBLOCK->nltype == NLTYPE_FIXED &&
-          NLBLOCK->nllen == 2 &&
-          UCHAR21TEST(eptr) == NLBLOCK->nl[0])
-        {
-        mb->hitend = TRUE;
-        if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
-        }
-      RRETURN(MATCH_NOMATCH);
-      }
-
-    /* Either at end of string or \n before end. */
-
-    SCHECK_PARTIAL();
-    ecode++;
-    break;
-
-    /* Word boundary assertions */
-
-    case OP_NOT_WORD_BOUNDARY:
-    case OP_WORD_BOUNDARY:
-      {
-
-      /* Find out if the previous and current characters are "word" characters.
-      It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
-      be "non-word" characters. Remember the earliest consulted character for
-      partial matching. */
-
-#ifdef SUPPORT_UNICODE
-      if (utf)
-        {
-        /* Get status of previous character */
-
-        if (eptr == mb->start_subject) prev_is_word = FALSE; else
-          {
-          PCRE2_SPTR lastptr = eptr - 1;
-          BACKCHAR(lastptr);
-          if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr;
-          GETCHAR(c, lastptr);
-          if ((mb->poptions & PCRE2_UCP) != 0)
-            {
-            if (c == '_') prev_is_word = TRUE; else
-              {
-              int cat = UCD_CATEGORY(c);
-              prev_is_word = (cat == ucp_L || cat == ucp_N);
-              }
-            }
-          else
-          prev_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0;
-          }
-
-        /* Get status of next character */
-
-        if (eptr >= mb->end_subject)
-          {
-          SCHECK_PARTIAL();
-          cur_is_word = FALSE;
-          }
-        else
-          {
-          PCRE2_SPTR nextptr = eptr + 1;
-          FORWARDCHARTEST(nextptr, mb->end_subject);
-          if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr;
-          GETCHAR(c, eptr);
-          if ((mb->poptions & PCRE2_UCP) != 0)
-            {
-            if (c == '_') cur_is_word = TRUE; else
-              {
-              int cat = UCD_CATEGORY(c);
-              cur_is_word = (cat == ucp_L || cat == ucp_N);
-              }
-            }
-          else
-          cur_is_word = c < 256 && (mb->ctypes[c] & ctype_word) != 0;
-          }
-        }
-      else
-#endif  /* SUPPORT UTF */
-
-      /* Not in UTF-8 mode, but we may still have PCRE2_UCP set, and for
-      consistency with the behaviour of \w we do use it in this case. */
-
-        {
-        /* Get status of previous character */
-
-        if (eptr == mb->start_subject) prev_is_word = FALSE; else
-          {
-          if (eptr <= mb->start_used_ptr) mb->start_used_ptr = eptr - 1;
-#ifdef SUPPORT_UNICODE
-          if ((mb->poptions & PCRE2_UCP) != 0)
-            {
-            c = eptr[-1];
-            if (c == '_') prev_is_word = TRUE; else
-              {
-              int cat = UCD_CATEGORY(c);
-              prev_is_word = (cat == ucp_L || cat == ucp_N);
-              }
-            }
-          else
-#endif
-          prev_is_word = MAX_255(eptr[-1])
-            && ((mb->ctypes[eptr[-1]] & ctype_word) != 0);
-          }
-
-        /* Get status of next character */
-
-        if (eptr >= mb->end_subject)
-          {
-          SCHECK_PARTIAL();
-          cur_is_word = FALSE;
-          }
-        else
-          {
-          if (eptr >= mb->last_used_ptr) mb->last_used_ptr = eptr + 1;
-#ifdef SUPPORT_UNICODE
-          if ((mb->poptions & PCRE2_UCP) != 0)
-            {
-            c = *eptr;
-            if (c == '_') cur_is_word = TRUE; else
-              {
-              int cat = UCD_CATEGORY(c);
-              cur_is_word = (cat == ucp_L || cat == ucp_N);
-              }
-            }
-          else
-#endif
-          cur_is_word = MAX_255(*eptr)
-            && ((mb->ctypes[*eptr] & ctype_word) != 0);
-          }
-        }
-
-      /* Now see if the situation is what we want */
-
-      if ((*ecode++ == OP_WORD_BOUNDARY)?
-           cur_is_word == prev_is_word : cur_is_word != prev_is_word)
-        RRETURN(MATCH_NOMATCH);
-      }
-    break;
-
+    /*===================================================================== */
     /* Match any single character type except newline; have to take care with
     CRLF newlines and partial matching. */
 
     case OP_ANY:
-    if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+    if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
     if (mb->partial != 0 &&
-        eptr + 1 >= mb->end_subject &&
+        Feptr == mb->end_subject - 1 &&
         NLBLOCK->nltype == NLTYPE_FIXED &&
         NLBLOCK->nllen == 2 &&
-        UCHAR21TEST(eptr) == NLBLOCK->nl[0])
+        UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
       {
       mb->hitend = TRUE;
-      if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+      if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
       }
-
     /* Fall through */
 
     /* Match any single character whatsoever. */
 
     case OP_ALLANY:
-    if (eptr >= mb->end_subject)   /* DO NOT merge the eptr++ here; it must */
+    if (Feptr >= mb->end_subject)  /* DO NOT merge the Feptr++ here; it must */
       {                            /* not be updated before SCHECK_PARTIAL. */
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    eptr++;
+    Feptr++;
 #ifdef SUPPORT_UNICODE
-    if (utf) ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+    if (utf) ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
 #endif
-    ecode++;
+    Fecode++;
     break;
 
-    /* Match a single code unit, even in UTF-8 mode. This opcode really does
+
+    /* ===================================================================== */
+    /* Match a single code unit, even in UTF mode. This opcode really does
     match any code unit, even newline. (It really should be called ANYCODEUNIT,
     of course - the byte name is from pre-16 bit days.) */
 
     case OP_ANYBYTE:
-    if (eptr >= mb->end_subject)   /* DO NOT merge the eptr++ here; it must */
-      {                            /* not be updated before SCHECK_PARTIAL. */
+    if (Feptr >= mb->end_subject)   /* DO NOT merge the Feptr++ here; it must */
+      {                             /* not be updated before SCHECK_PARTIAL. */
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    eptr++;
-    ecode++;
+    Feptr++;
+    Fecode++;
     break;
 
-    case OP_NOT_DIGIT:
-    if (eptr >= mb->end_subject)
+
+    /* ===================================================================== */
+    /* Match a single character, casefully */
+
+    case OP_CHAR:
+#ifdef SUPPORT_UNICODE
+    if (utf)
+      {
+      Flength = 1;
+      Fecode++;
+      GETCHARLEN(fc, Fecode, Flength);
+      if (Flength > (PCRE2_SIZE)(mb->end_subject - Feptr))
+        {
+        CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
+        RRETURN(MATCH_NOMATCH);
+        }
+      for (; Flength > 0; Flength--)
+        {
+        if (*Fecode++ != UCHAR21INC(Feptr)) RRETURN(MATCH_NOMATCH);
+        }
+      }
+    else
+#endif
+    /* Not UTF mode */
+      {
+      if (mb->end_subject - Feptr < 1)
+        {
+        SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
+        RRETURN(MATCH_NOMATCH);
+        }
+      if (Fecode[1] != *Feptr++) RRETURN(MATCH_NOMATCH);
+      Fecode += 2;
+      }
+    break;
+
+
+    /* ===================================================================== */
+    /* Match a single character, caselessly. If we are at the end of the
+    subject, give up immediately. We get here only when the pattern character
+    has at most one other case. Characters with more than two cases are coded
+    as OP_PROP with the pseudo-property PT_CLIST. */
+
+    case OP_CHARI:
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    if (
-#ifdef SUPPORT_WIDE_CHARS
-       c < 256 &&
-#endif
-       (mb->ctypes[c] & ctype_digit) != 0
-       )
+
+#ifdef SUPPORT_UNICODE
+    if (utf)
+      {
+      Flength = 1;
+      Fecode++;
+      GETCHARLEN(fc, Fecode, Flength);
+
+      /* If the pattern character's value is < 128, we know that its other case
+      (if any) is also < 128 (and therefore only one code unit long in all
+      code-unit widths), so we can use the fast lookup table. We checked above
+      that there is at least one character left in the subject. */
+
+      if (fc < 128)
+        {
+        uint32_t cc = UCHAR21(Feptr);
+        if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
+        Fecode++;
+        Feptr++;
+        }
+
+      /* Otherwise we must pick up the subject character and use Unicode
+      property support to test its other case. Note that we cannot use the
+      value of "Flength" to check for sufficient bytes left, because the other
+      case of the character may have more or fewer code units. */
+
+      else
+        {
+        uint32_t dc;
+        GETCHARINC(dc, Feptr);
+        Fecode += Flength;
+        if (dc != fc && dc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
+        }
+      }
+    else
+#endif   /* SUPPORT_UNICODE */
+
+    /* Not UTF mode; use the table for characters < 256. */
+      {
+      if (TABLE_GET(Fecode[1], mb->lcc, Fecode[1])
+          != TABLE_GET(*Feptr, mb->lcc, *Feptr)) RRETURN(MATCH_NOMATCH);
+      Feptr++;
+      Fecode += 2;
+      }
+    break;
+
+
+    /* ===================================================================== */
+    /* Match not a single character. */
+
+    case OP_NOT:
+    case OP_NOTI:
+    if (Feptr >= mb->end_subject)
+      {
+      SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
-    ecode++;
+      }
+#ifdef SUPPORT_UNICODE
+    if (utf)
+      {
+      uint32_t ch;
+      Fecode++;
+      GETCHARINC(ch, Fecode);
+      GETCHARINC(fc, Feptr);
+      if (ch == fc)
+        {
+        RRETURN(MATCH_NOMATCH);  /* Caseful match */
+        }
+      else if (Fop == OP_NOTI)   /* If caseless */
+        {
+        if (ch > 127)
+          ch = UCD_OTHERCASE(ch);
+        else
+          ch = TABLE_GET(ch, mb->fcc, ch);
+        if (ch == fc) RRETURN(MATCH_NOMATCH);
+        }
+      }
+    else
+#endif  /* SUPPORT_UNICODE */
+      {
+      uint32_t ch = Fecode[1];
+      fc = *Feptr++;
+      if (ch == fc || (Fop == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == fc))
+        RRETURN(MATCH_NOMATCH);
+      Fecode += 2;
+      }
+    break;
+
+
+    /* ===================================================================== */
+    /* Match a single character repeatedly. */
+
+#define Loclength    F->temp_size
+#define Lstart_eptr  F->temp_sptr[0]
+#define Lcharptr     F->temp_sptr[1]
+#define Lmin         F->temp_32[0]
+#define Lmax         F->temp_32[1]
+#define Lc           F->temp_32[2]
+#define Loc          F->temp_32[3]
+
+    case OP_EXACT:
+    case OP_EXACTI:
+    Lmin = Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATCHAR;
+
+    case OP_POSUPTO:
+    case OP_POSUPTOI:
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATCHAR;
+
+    case OP_UPTO:
+    case OP_UPTOI:
+    reptype = REPTYPE_MAX;
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATCHAR;
+
+    case OP_MINUPTO:
+    case OP_MINUPTOI:
+    reptype = REPTYPE_MIN;
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATCHAR;
+
+    case OP_POSSTAR:
+    case OP_POSSTARI:
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = UINT32_MAX;
+    Fecode++;
+    goto REPEATCHAR;
+
+    case OP_POSPLUS:
+    case OP_POSPLUSI:
+    reptype = REPTYPE_POS;
+    Lmin = 1;
+    Lmax = UINT32_MAX;
+    Fecode++;
+    goto REPEATCHAR;
+
+    case OP_POSQUERY:
+    case OP_POSQUERYI:
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = 1;
+    Fecode++;
+    goto REPEATCHAR;
+
+    case OP_STAR:
+    case OP_STARI:
+    case OP_MINSTAR:
+    case OP_MINSTARI:
+    case OP_PLUS:
+    case OP_PLUSI:
+    case OP_MINPLUS:
+    case OP_MINPLUSI:
+    case OP_QUERY:
+    case OP_QUERYI:
+    case OP_MINQUERY:
+    case OP_MINQUERYI:
+    fc = *Fecode++ - ((Fop < OP_STARI)? OP_STAR : OP_STARI);
+    Lmin = rep_min[fc];
+    Lmax = rep_max[fc];
+    reptype = rep_typ[fc];
+
+    /* Common code for all repeated single-character matches. We first check
+    for the minimum number of characters. If the minimum equals the maximum, we
+    are done. Otherwise, if minimizing, check the rest of the pattern for a
+    match; if there isn't one, advance up to the maximum, one character at a
+    time.
+
+    If maximizing, advance up to the maximum number of matching characters,
+    until Feptr is past the end of the maximum run. If possessive, we are
+    then done (no backing up). Otherwise, match at this position; anything
+    other than no match is immediately returned. For nomatch, back up one
+    character, unless we are matching \R and the last thing matched was
+    \r\n, in which case, back up two code units until we reach the first
+    optional character position.
+
+    The various UTF/non-UTF and caseful/caseless cases are handled separately,
+    for speed. */
+
+    REPEATCHAR:
+#ifdef SUPPORT_UNICODE
+    if (utf)
+      {
+      Flength = 1;
+      Lcharptr = Fecode;
+      GETCHARLEN(fc, Fecode, Flength);
+      Fecode += Flength;
+
+      /* Handle multi-code-unit character matching, caseful and caseless. */
+
+      if (Flength > 1)
+        {
+        uint32_t othercase;
+
+        if (Fop >= OP_STARI &&     /* Caseless */
+            (othercase = UCD_OTHERCASE(fc)) != fc)
+          Loclength = PRIV(ord2utf)(othercase, Foccu);
+        else Loclength = 0;
+
+        for (i = 1; i <= Lmin; i++)
+          {
+          if (Feptr <= mb->end_subject - Flength &&
+            memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;
+          else if (Loclength > 0 &&
+                   Feptr <= mb->end_subject - Loclength &&
+                   memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
+            Feptr += Loclength;
+          else
+            {
+            CHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          }
+
+        if (Lmin == Lmax) continue;
+
+        if (reptype == REPTYPE_MIN)
+          {
+          for (;;)
+            {
+            RMATCH(Fecode, RM202);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr <= mb->end_subject - Flength &&
+              memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;
+            else if (Loclength > 0 &&
+                     Feptr <= mb->end_subject - Loclength &&
+                     memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
+              Feptr += Loclength;
+            else
+              {
+              CHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            }
+          /* Control never gets here */
+          }
+
+        else  /* Maximize */
+          {
+          Lstart_eptr = Feptr;
+          for (i = Lmin; i < Lmax; i++)
+            {
+            if (Feptr <= mb->end_subject - Flength &&
+                memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0)
+              Feptr += Flength;
+            else if (Loclength > 0 &&
+                     Feptr <= mb->end_subject - Loclength &&
+                     memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
+              Feptr += Loclength;
+            else
+              {
+              CHECK_PARTIAL();
+              break;
+              }
+            }
+
+          /* 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. */
+
+          if (reptype != REPTYPE_POS) for(;;)
+            {
+            if (Feptr <= Lstart_eptr) break;
+            RMATCH(Fecode, RM203);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            Feptr--;
+            BACKCHAR(Feptr);
+            }
+          }
+        break;   /* End of repeated wide character handling */
+        }
+
+      /* Length of UTF character is 1. Put it into the preserved variable and
+      fall through to the non-UTF code. */
+
+      Lc = fc;
+      }
+    else
+#endif  /* SUPPORT_UNICODE */
+
+    /* When not in UTF mode, load a single-code-unit character. Then proceed as
+    above. */
+
+    Lc = *Fecode++;
+
+    /* Caseless comparison */
+
+    if (Fop >= OP_STARI)
+      {
+#if PCRE2_CODE_UNIT_WIDTH == 8
+      /* Lc must be < 128 in UTF-8 mode. */
+      Loc = mb->fcc[Lc];
+#else /* 16-bit & 32-bit */
+#ifdef SUPPORT_UNICODE
+      if (utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);
+      else
+#endif  /* SUPPORT_UNICODE */
+      Loc = TABLE_GET(Lc, mb->fcc, Lc);
+#endif  /* PCRE2_CODE_UNIT_WIDTH == 8 */
+
+      for (i = 1; i <= Lmin; i++)
+        {
+        uint32_t cc;                 /* Faster than PCRE2_UCHAR */
+        if (Feptr >= mb->end_subject)
+          {
+          SCHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        cc = UCHAR21TEST(Feptr);
+        if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);
+        Feptr++;
+        }
+      if (Lmin == Lmax) continue;
+
+      if (reptype == REPTYPE_MIN)
+        {
+        for (;;)
+          {
+          uint32_t cc;               /* Faster than PCRE2_UCHAR */
+          RMATCH(Fecode, RM25);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          cc = UCHAR21TEST(Feptr);
+          if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);
+          Feptr++;
+          }
+        /* Control never gets here */
+        }
+
+      else  /* Maximize */
+        {
+        Lstart_eptr = Feptr;
+        for (i = Lmin; i < Lmax; i++)
+          {
+          uint32_t cc;               /* Faster than PCRE2_UCHAR */
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            break;
+            }
+          cc = UCHAR21TEST(Feptr);
+          if (Lc != cc && Loc != cc) break;
+          Feptr++;
+          }
+        if (reptype != REPTYPE_POS) for (;;)
+          {
+          if (Feptr == Lstart_eptr) break;
+          RMATCH(Fecode, RM26);
+          Feptr--;
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          }
+        }
+      }
+
+    /* Caseful comparisons (includes all multi-byte characters) */
+
+    else
+      {
+      for (i = 1; i <= Lmin; i++)
+        {
+        if (Feptr >= mb->end_subject)
+          {
+          SCHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);
+        }
+
+      if (Lmin == Lmax) continue;
+
+      if (reptype == REPTYPE_MIN)
+        {
+        for (;;)
+          {
+          RMATCH(Fecode, RM27);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);
+          }
+        /* Control never gets here */
+        }
+      else  /* Maximize */
+        {
+        Lstart_eptr = Feptr;
+        for (i = Lmin; i < Lmax; i++)
+          {
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            break;
+            }
+
+          if (Lc != UCHAR21TEST(Feptr)) break;
+          Feptr++;
+          }
+
+        if (reptype != REPTYPE_POS) for (;;)
+          {
+          if (Feptr <= Lstart_eptr) break;
+          RMATCH(Fecode, RM28);
+          Feptr--;
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          }
+        }
+      }
+    break;
+
+#undef Loclength
+#undef Lstart_eptr
+#undef Lcharptr
+#undef Lmin
+#undef Lmax
+#undef Lc
+#undef Loc
+
+
+    /* ===================================================================== */
+    /* Match a negated single one-byte character repeatedly. This is almost a
+    repeat of the code for a repeated single character, but I haven't found a
+    nice way of commoning these up that doesn't require a test of the
+    positive/negative option for each character match. Maybe that wouldn't add
+    very much to the time taken, but character matching *is* what this is all
+    about... */
+
+#define Lstart_eptr  F->temp_sptr[0]
+#define Lmin         F->temp_32[0]
+#define Lmax         F->temp_32[1]
+#define Lc           F->temp_32[2]
+#define Loc          F->temp_32[3]
+
+    case OP_NOTEXACT:
+    case OP_NOTEXACTI:
+    Lmin = Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTUPTO:
+    case OP_NOTUPTOI:
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    reptype = REPTYPE_MAX;
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTMINUPTO:
+    case OP_NOTMINUPTOI:
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    reptype = REPTYPE_MIN;
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSSTAR:
+    case OP_NOTPOSSTARI:
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = UINT32_MAX;
+    Fecode++;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSPLUS:
+    case OP_NOTPOSPLUSI:
+    reptype = REPTYPE_POS;
+    Lmin = 1;
+    Lmax = UINT32_MAX;
+    Fecode++;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSQUERY:
+    case OP_NOTPOSQUERYI:
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = 1;
+    Fecode++;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSUPTO:
+    case OP_NOTPOSUPTOI:
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTSTAR:
+    case OP_NOTSTARI:
+    case OP_NOTMINSTAR:
+    case OP_NOTMINSTARI:
+    case OP_NOTPLUS:
+    case OP_NOTPLUSI:
+    case OP_NOTMINPLUS:
+    case OP_NOTMINPLUSI:
+    case OP_NOTQUERY:
+    case OP_NOTQUERYI:
+    case OP_NOTMINQUERY:
+    case OP_NOTMINQUERYI:
+    fc = *Fecode++ - ((Fop >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
+    Lmin = rep_min[fc];
+    Lmax = rep_max[fc];
+    reptype = rep_typ[fc];
+
+    /* Common code for all repeated single-character non-matches. */
+
+    REPEATNOTCHAR:
+    GETCHARINCTEST(Lc, Fecode);
+
+    /* The code is duplicated for the caseless and caseful cases, for speed,
+    since matching characters is likely to be quite common. First, ensure the
+    minimum number of matches are present. If Lmin = Lmax, we are done.
+    Otherwise, if minimizing, keep trying the rest of the expression and
+    advancing one matching character if failing, up to the maximum.
+    Alternatively, if maximizing, find the maximum number of characters and
+    work backwards. */
+
+    if (Fop >= OP_NOTSTARI)     /* Caseless */
+      {
+#ifdef SUPPORT_UNICODE
+      if (utf && Lc > 127)
+        Loc = UCD_OTHERCASE(Lc);
+      else
+#endif /* SUPPORT_UNICODE */
+
+      Loc = TABLE_GET(Lc, mb->fcc, Lc);  /* Other case from table */
+
+#ifdef SUPPORT_UNICODE
+      if (utf)
+        {
+        uint32_t d;
+        for (i = 1; i <= Lmin; i++)
+          {
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(d, Feptr);
+          if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);
+          }
+        }
+      else
+#endif  /* SUPPORT_UNICODE */
+
+      /* Not UTF mode */
+        {
+        for (i = 1; i <= Lmin; i++)
+          {
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);
+          Feptr++;
+          }
+        }
+
+      if (Lmin == Lmax) continue;  /* Finished for exact count */
+
+      if (reptype == REPTYPE_MIN)
+        {
+#ifdef SUPPORT_UNICODE
+        if (utf)
+          {
+          uint32_t d;
+          for (;;)
+            {
+            RMATCH(Fecode, RM204);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(d, Feptr);
+            if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        else
+#endif  /*SUPPORT_UNICODE */
+
+        /* Not UTF mode */
+          {
+          for (;;)
+            {
+            RMATCH(Fecode, RM29);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);
+            Feptr++;
+            }
+          }
+        /* Control never gets here */
+        }
+
+      /* Maximize case */
+
+      else
+        {
+        Lstart_eptr = Feptr;
+
+#ifdef SUPPORT_UNICODE
+        if (utf)
+          {
+          uint32_t d;
+          for (i = Lmin; i < Lmax; i++)
+            {
+            int len = 1;
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(d, Feptr, len);
+            if (Lc == d || Loc == d) break;
+            Feptr += len;
+            }
+
+          /* 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. */
+
+          if (reptype != REPTYPE_POS) for(;;)
+            {
+            if (Feptr <= Lstart_eptr) break;
+            RMATCH(Fecode, RM205);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            Feptr--;
+            BACKCHAR(Feptr);
+            }
+          }
+        else
+#endif  /* SUPPORT_UNICODE */
+
+        /* Not UTF mode */
+          {
+          for (i = Lmin; i < Lmax; i++)
+            {
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if (Lc == *Feptr || Loc == *Feptr) break;
+            Feptr++;
+            }
+          if (reptype != REPTYPE_POS) for (;;)
+            {
+            if (Feptr == Lstart_eptr) break;
+            RMATCH(Fecode, RM30);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            Feptr--;
+            }
+          }
+        }
+      }
+
+    /* Caseful comparisons */
+
+    else
+      {
+#ifdef SUPPORT_UNICODE
+      if (utf)
+        {
+        uint32_t d;
+        for (i = 1; i <= Lmin; i++)
+          {
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(d, Feptr);
+          if (Lc == d) RRETURN(MATCH_NOMATCH);
+          }
+        }
+      else
+#endif
+      /* Not UTF mode */
+        {
+        for (i = 1; i <= Lmin; i++)
+          {
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);
+          }
+        }
+
+      if (Lmin == Lmax) continue;
+
+      if (reptype == REPTYPE_MIN)
+        {
+#ifdef SUPPORT_UNICODE
+        if (utf)
+          {
+          uint32_t d;
+          for (;;)
+            {
+            RMATCH(Fecode, RM206);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(d, Feptr);
+            if (Lc == d) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        else
+#endif
+        /* Not UTF mode */
+          {
+          for (;;)
+            {
+            RMATCH(Fecode, RM31);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        /* Control never gets here */
+        }
+
+      /* Maximize case */
+
+      else
+        {
+        Lstart_eptr = Feptr;
+
+#ifdef SUPPORT_UNICODE
+        if (utf)
+          {
+          uint32_t d;
+          for (i = Lmin; i < Lmax; i++)
+            {
+            int len = 1;
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(d, Feptr, len);
+            if (Lc == d) break;
+            Feptr += len;
+            }
+
+          /* 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. */
+
+          if (reptype != REPTYPE_POS) for(;;)
+            {
+            if (Feptr <= Lstart_eptr) break;
+            RMATCH(Fecode, RM207);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            Feptr--;
+            BACKCHAR(Feptr);
+            }
+          }
+        else
+#endif
+        /* Not UTF mode */
+          {
+          for (i = Lmin; i < Lmax; i++)
+            {
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if (Lc == *Feptr) break;
+            Feptr++;
+            }
+          if (reptype != REPTYPE_POS) for (;;)
+            {
+            if (Feptr == Lstart_eptr) break;
+            RMATCH(Fecode, RM32);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            Feptr--;
+            }
+          }
+        }
+      }
+    break;
+
+#undef Lstart_eptr
+#undef Lmin
+#undef Lmax
+#undef Lc
+#undef Loc
+
+
+    /* ===================================================================== */
+    /* Match a bit-mapped character class, possibly repeatedly. These op codes
+    are used when all the characters in the class have values in the range
+    0-255, and either the matching is caseful, or the characters are in the
+    range 0-127 when UTF processing is enabled. The only difference between
+    OP_CLASS and OP_NCLASS occurs when a data character outside the range is
+    encountered. */
+
+#define Lmin               F->temp_32[0]
+#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)
+
+    case OP_NCLASS:
+    case OP_CLASS:
+      {
+      Lbyte_map_address = Fecode + 1;           /* Save for matching */
+      Fecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */
+
+      /* Look past the end of the item to see if there is repeat information
+      following. Then obey similar code to character type repeats. */
+
+      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. */
+
+#ifdef SUPPORT_UNICODE
+      if (utf)
+        {
+        for (i = 1; i <= Lmin; i++)
+          {
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(fc, Feptr);
+          if (fc > 255)
+            {
+            if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
+            }
+          else
+            if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
+          }
+        }
+      else
+#endif
+      /* Not UTF mode */
+        {
+        for (i = 1; i <= Lmin; i++)
+          {
+          if (Feptr >= mb->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          fc = *Feptr++;
+#if PCRE2_CODE_UNIT_WIDTH != 8
+          if (fc > 255)
+            {
+            if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
+            }
+          else
+#endif
+          if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
+          }
+        }
+
+      /* If Lmax == Lmin we are done. Continue with 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)
+        {
+#ifdef SUPPORT_UNICODE
+        if (utf)
+          {
+          for (;;)
+            {
+            RMATCH(Fecode, RM200);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(fc, Feptr);
+            if (fc > 255)
+              {
+              if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
+              }
+            else
+              if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        else
+#endif
+        /* Not UTF mode */
+          {
+          for (;;)
+            {
+            RMATCH(Fecode, RM23);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            fc = *Feptr++;
+#if PCRE2_CODE_UNIT_WIDTH != 8
+            if (fc > 255)
+              {
+              if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
+              }
+            else
+#endif
+            if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        /* Control never gets here */
+        }
+
+      /* If maximizing, find the longest possible run, then work backwards. */
+
+      else
+        {
+        Lstart_eptr = Feptr;
+
+#ifdef SUPPORT_UNICODE
+        if (utf)
+          {
+          for (i = Lmin; i < Lmax; i++)
+            {
+            int len = 1;
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(fc, Feptr, len);
+            if (fc > 255)
+              {
+              if (Fop == OP_CLASS) break;
+              }
+            else
+              if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) break;
+            Feptr += len;
+            }
+
+          if (reptype == REPTYPE_POS) continue;    /* No backtracking */
+
+          for (;;)
+            {
+            RMATCH(Fecode, RM201);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (Feptr-- == Lstart_eptr) break;  /* Tried at original position */
+            BACKCHAR(Feptr);
+            }
+          }
+        else
+#endif
+          /* Not UTF mode */
+          {
+          for (i = Lmin; i < Lmax; i++)
+            {
+            if (Feptr >= mb->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            fc = *Feptr;
+#if PCRE2_CODE_UNIT_WIDTH != 8
+            if (fc > 255)
+              {
+              if (Fop == OP_CLASS) break;
+              }
+            else
+#endif
+            if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) break;
+            Feptr++;
+            }
+
+          if (reptype == REPTYPE_POS) continue;    /* No backtracking */
+
+          while (Feptr >= Lstart_eptr)
+            {
+            RMATCH(Fecode, RM24);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            Feptr--;
+            }
+          }
+
+        RRETURN(MATCH_NOMATCH);
+        }
+      }
+    /* Control never gets here */
+
+#undef Lbyte_map_address
+#undef Lbyte_map
+#undef Lstart_eptr
+#undef Lmin
+#undef Lmax
+
+
+    /* ===================================================================== */
+    /* Match an extended character class. In the 8-bit library, this opcode is
+    encountered only when UTF-8 mode mode is supported. In the 16-bit and
+    32-bit libraries, codepoints greater than 255 may be encountered even when
+    UTF is not supported. */
+
+#define Lstart_eptr  F->temp_sptr[0]
+#define Lxclass_data F->temp_sptr[1]
+#define Lmin         F->temp_32[0]
+#define Lmax         F->temp_32[1]
+
+#ifdef SUPPORT_WIDE_CHARS
+    case OP_XCLASS:
+      {
+      Lxclass_data = Fecode + 1 + LINK_SIZE;  /* Save for matching */
+      Fecode += GET(Fecode, 1);               /* Advance past the item */
+
+      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(xclass)(fc, Lxclass_data, 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, RM100);
+          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(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH);
+          }
+        /* Control never gets 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(xclass)(fc, Lxclass_data, utf)) break;
+          Feptr += len;
+          }
+
+        if (reptype == REPTYPE_POS) continue;    /* No backtracking */
+
+        for(;;)
+          {
+          RMATCH(Fecode, RM101);
+          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);
+        }
+
+      /* Control never gets here */
+      }
+#endif  /* SUPPORT_WIDE_CHARS: end of XCLASS */
+
+#undef Lstart_eptr
+#undef Lxclass_data
+#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
+    tests are compiled. */
+
+    case OP_NOT_DIGIT:
+    if (Feptr >= mb->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(fc, Feptr);
+    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)
+      RRETURN(MATCH_NOMATCH);
+    Fecode++;
     break;
 
     case OP_DIGIT:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    if (
-#ifdef SUPPORT_WIDE_CHARS
-       c > 255 ||
-#endif
-       (mb->ctypes[c] & ctype_digit) == 0
-       )
+    GETCHARINCTEST(fc, Feptr);
+    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)
       RRETURN(MATCH_NOMATCH);
-    ecode++;
+    Fecode++;
     break;
 
     case OP_NOT_WHITESPACE:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    if (
-#ifdef SUPPORT_WIDE_CHARS
-       c < 256 &&
-#endif
-       (mb->ctypes[c] & ctype_space) != 0
-       )
+    GETCHARINCTEST(fc, Feptr);
+    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)
       RRETURN(MATCH_NOMATCH);
-    ecode++;
+    Fecode++;
     break;
 
     case OP_WHITESPACE:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    if (
-#ifdef SUPPORT_WIDE_CHARS
-       c > 255 ||
-#endif
-       (mb->ctypes[c] & ctype_space) == 0
-       )
+    GETCHARINCTEST(fc, Feptr);
+    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)
       RRETURN(MATCH_NOMATCH);
-    ecode++;
+    Fecode++;
     break;
 
     case OP_NOT_WORDCHAR:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    if (
-#ifdef SUPPORT_WIDE_CHARS
-       c < 256 &&
-#endif
-       (mb->ctypes[c] & ctype_word) != 0
-       )
+    GETCHARINCTEST(fc, Feptr);
+    if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)
       RRETURN(MATCH_NOMATCH);
-    ecode++;
+    Fecode++;
     break;
 
     case OP_WORDCHAR:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    if (
-#ifdef SUPPORT_WIDE_CHARS
-       c > 255 ||
-#endif
-       (mb->ctypes[c] & ctype_word) == 0
-       )
+    GETCHARINCTEST(fc, Feptr);
+    if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)
       RRETURN(MATCH_NOMATCH);
-    ecode++;
+    Fecode++;
     break;
 
     case OP_ANYNL:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    switch(c)
+    GETCHARINCTEST(fc, Feptr);
+    switch(fc)
       {
       default: RRETURN(MATCH_NOMATCH);
 
       case CHAR_CR:
-      if (eptr >= mb->end_subject)
+      if (Feptr >= mb->end_subject)
         {
         SCHECK_PARTIAL();
         }
-      else if (UCHAR21TEST(eptr) == CHAR_LF) eptr++;
+      else if (UCHAR21TEST(Feptr) == CHAR_LF) Feptr++;
       break;
 
       case CHAR_LF:
@@ -2556,110 +2257,113 @@
       if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
       break;
       }
-    ecode++;
+    Fecode++;
     break;
 
     case OP_NOT_HSPACE:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    switch(c)
+    GETCHARINCTEST(fc, Feptr);
+    switch(fc)
       {
       HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */
       default: break;
       }
-    ecode++;
+    Fecode++;
     break;
 
     case OP_HSPACE:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    switch(c)
+    GETCHARINCTEST(fc, Feptr);
+    switch(fc)
       {
       HSPACE_CASES: break;  /* Byte and multibyte cases */
       default: RRETURN(MATCH_NOMATCH);
       }
-    ecode++;
+    Fecode++;
     break;
 
     case OP_NOT_VSPACE:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    switch(c)
+    GETCHARINCTEST(fc, Feptr);
+    switch(fc)
       {
       VSPACE_CASES: RRETURN(MATCH_NOMATCH);
       default: break;
       }
-    ecode++;
+    Fecode++;
     break;
 
     case OP_VSPACE:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
-    switch(c)
+    GETCHARINCTEST(fc, Feptr);
+    switch(fc)
       {
       VSPACE_CASES: break;
       default: RRETURN(MATCH_NOMATCH);
       }
-    ecode++;
+    Fecode++;
     break;
 
+
 #ifdef SUPPORT_UNICODE
+
+    /* ===================================================================== */
     /* Check the next character by Unicode property. We will get here only
     if the support is in the binary; otherwise a compile-time error occurs. */
 
     case OP_PROP:
     case OP_NOTPROP:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
-    GETCHARINCTEST(c, eptr);
+    GETCHARINCTEST(fc, Feptr);
       {
       const uint32_t *cp;
-      const ucd_record *prop = GET_UCD(c);
+      const ucd_record *prop = GET_UCD(fc);
 
-      switch(ecode[1])
+      switch(Fecode[1])
         {
         case PT_ANY:
-        if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+        if (Fop == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
         break;
 
         case PT_LAMP:
         if ((prop->chartype == ucp_Lu ||
              prop->chartype == ucp_Ll ||
-             prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
+             prop->chartype == ucp_Lt) == (Fop == OP_NOTPROP))
           RRETURN(MATCH_NOMATCH);
         break;
 
         case PT_GC:
-        if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
+        if ((Fecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (Fop == OP_PROP))
           RRETURN(MATCH_NOMATCH);
         break;
 
         case PT_PC:
-        if ((ecode[2] != prop->chartype) == (op == OP_PROP))
+        if ((Fecode[2] != prop->chartype) == (Fop == OP_PROP))
           RRETURN(MATCH_NOMATCH);
         break;
 
         case PT_SC:
-        if ((ecode[2] != prop->script) == (op == OP_PROP))
+        if ((Fecode[2] != prop->script) == (Fop == OP_PROP))
           RRETURN(MATCH_NOMATCH);
         break;
 
@@ -2667,7 +2371,7 @@
 
         case PT_ALNUM:
         if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
-             PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
+             PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (Fop == OP_NOTPROP))
           RRETURN(MATCH_NOMATCH);
         break;
 
@@ -2677,16 +2381,16 @@
 
         case PT_SPACE:    /* Perl space */
         case PT_PXSPACE:  /* POSIX space */
-        switch(c)
+        switch(fc)
           {
           HSPACE_CASES:
           VSPACE_CASES:
-          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+          if (Fop == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
           break;
 
           default:
           if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) ==
-            (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH);
+            (Fop == OP_NOTPROP)) RRETURN(MATCH_NOMATCH);
           break;
           }
         break;
@@ -2694,1520 +2398,112 @@
         case PT_WORD:
         if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
              PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
-             c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
+             fc == CHAR_UNDERSCORE) == (Fop == OP_NOTPROP))
           RRETURN(MATCH_NOMATCH);
         break;
 
         case PT_CLIST:
-        cp = PRIV(ucd_caseless_sets) + ecode[2];
+        cp = PRIV(ucd_caseless_sets) + Fecode[2];
         for (;;)
           {
-          if (c < *cp)
-            { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; }
-          if (c == *cp++)
-            { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } }
+          if (fc < *cp)
+            { if (Fop == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; }
+          if (fc == *cp++)
+            { if (Fop == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } }
           }
         break;
 
         case PT_UCNC:
-        if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
-             c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
-             c >= 0xe000) == (op == OP_NOTPROP))
+        if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
+             fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
+             fc >= 0xe000) == (Fop == OP_NOTPROP))
           RRETURN(MATCH_NOMATCH);
         break;
 
         /* This should never occur */
 
         default:
-        RRETURN(PCRE2_ERROR_INTERNAL);
+        return PCRE2_ERROR_INTERNAL;
         }
 
-      ecode += 3;
+      Fecode += 3;
       }
     break;
 
+
+    /* ===================================================================== */
     /* Match an extended Unicode sequence. We will get here only if the support
     is in the binary; otherwise a compile-time error occurs. */
 
     case OP_EXTUNI:
-    if (eptr >= mb->end_subject)
+    if (Feptr >= mb->end_subject)
       {
       SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);
       }
     else
       {
-      int lgb, rgb;
-      GETCHARINCTEST(c, eptr);
-      lgb = UCD_GRAPHBREAK(c);
-      while (eptr < mb->end_subject)
-        {
-        int len = 1;
-        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
-        rgb = UCD_GRAPHBREAK(c);
-        if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
-        lgb = rgb;
-        eptr += len;
-        }
+      GETCHARINCTEST(fc, Feptr);
+      Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject, utf,
+        NULL);
       }
     CHECK_PARTIAL();
-    ecode++;
-    break;
-#endif  /* SUPPORT_UNICODE */
-
-
-    /* Match a back reference, possibly repeatedly. Look past the end of the
-    item to see if there is repeat information following.
-
-    The OP_REF and OP_REFI opcodes are used for a reference to a numbered group
-    or to a non-duplicated named group. For a duplicated named group, OP_DNREF
-    and OP_DNREFI are used. In this case we must scan the list of groups to
-    which the name refers, and use the first one that is set. */
-
-    case OP_DNREF:
-    case OP_DNREFI:
-    caseless = op == OP_DNREFI;
-      {
-      int count = GET2(ecode, 1+IMM2_SIZE);
-      PCRE2_SPTR slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size;
-      ecode += 1 + 2*IMM2_SIZE;
-
-      /* Initializing 'offset' avoids a compiler warning in the REF_REPEAT
-      code. */
-
-      offset = 0;
-      while (count-- > 0)
-        {
-        offset = GET2(slot, 0) << 1;
-        if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET) break;
-        slot += mb->name_entry_size;
-        }
-      }
-    goto REF_REPEAT;
-
-    case OP_REF:
-    case OP_REFI:
-    caseless = op == OP_REFI;
-    offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
-    ecode += 1 + IMM2_SIZE;
-
-    /* Set up for repetition, or handle the non-repeated case */
-
-    REF_REPEAT:
-    switch (*ecode)
-      {
-      case OP_CRSTAR:
-      case OP_CRMINSTAR:
-      case OP_CRPLUS:
-      case OP_CRMINPLUS:
-      case OP_CRQUERY:
-      case OP_CRMINQUERY:
-      c = *ecode++ - OP_CRSTAR;
-      minimize = (c & 1) != 0;
-      min = rep_min[c];                 /* Pick up values from tables; */
-      max = rep_max[c];                 /* zero for max => infinity */
-      if (max == 0) max = INT_MAX;
-      break;
-
-      case OP_CRRANGE:
-      case OP_CRMINRANGE:
-      minimize = (*ecode == OP_CRMINRANGE);
-      min = GET2(ecode, 1);
-      max = GET2(ecode, 1 + IMM2_SIZE);
-      if (max == 0) max = INT_MAX;
-      ecode += 1 + 2 * IMM2_SIZE;
-      break;
-
-      default:                  /* No repeat follows */
-        {
-        int rc = match_ref(offset, offset_top, eptr, mb, caseless, &length);
-        if (rc != 0)
-          {
-          if (rc > 0) eptr = mb->end_subject;   /* Partial match */
-          CHECK_PARTIAL();
-          RRETURN(MATCH_NOMATCH);
-          }
-        }
-      eptr += length;
-      continue;              /* With the main loop */
-      }
-
-    /* Handle repeated back references. If a set group has length zero, just
-    continue with the main loop, because it matches however many times. For an
-    unset reference, if the minimum is zero, we can also just continue. We an
-    also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset
-    group be have as a zero-length group. For any other unset cases, carrying
-    on will result in NOMATCH. */
-
-    if (offset < offset_top && mb->ovector[offset] != PCRE2_UNSET)
-      {
-      if (mb->ovector[offset] == mb->ovector[offset + 1]) continue;
-      }
-    else  /* Group is not set */
-      {
-      if (min == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
-        continue;
-      }
-
-    /* First, ensure the minimum number of matches are present. We get back
-    the length of the reference string explicitly rather than passing the
-    address of eptr, so that eptr can be a register variable. */
-
-    for (i = 1; i <= min; i++)
-      {
-      PCRE2_SIZE slength;
-      int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength);
-      if (rc != 0)
-        {
-        if (rc > 0) eptr = mb->end_subject;   /* Partial match */
-        CHECK_PARTIAL();
-        RRETURN(MATCH_NOMATCH);
-        }
-      eptr += slength;
-      }
-
-    /* If min = max, continue at the same level without recursion.
-    They are not both allowed to be zero. */
-
-    if (min == max) continue;
-
-    /* If minimizing, keep trying and advancing the pointer */
-
-    if (minimize)
-      {
-      for (fi = min;; fi++)
-        {
-        int rc;
-        PCRE2_SIZE slength;
-        RMATCH(eptr, ecode, offset_top, mb, eptrb, RM14);
-        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-        if (fi >= max) RRETURN(MATCH_NOMATCH);
-        rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength);
-        if (rc != 0)
-          {
-          if (rc > 0) eptr = mb->end_subject;   /* Partial match */
-          CHECK_PARTIAL();
-          RRETURN(MATCH_NOMATCH);
-          }
-        eptr += slength;
-        }
-      /* Control never gets here */
-      }
-
-    /* If maximizing, find the longest string and work backwards, as long as
-    the matched lengths for each iteration are the same. */
-
-    else
-      {
-      BOOL samelengths = TRUE;
-      pp = eptr;
-      length = mb->ovector[offset+1] - mb->ovector[offset];
-
-      for (i = min; i < max; i++)
-        {
-        PCRE2_SIZE slength;
-        int rc = match_ref(offset, offset_top, eptr, mb, caseless, &slength);
-
-        if (rc != 0)
-          {
-          /* Can't use CHECK_PARTIAL because we don't want to update eptr in
-          the soft partial matching case. */
-
-          if (rc > 0 && mb->partial != 0 &&
-              mb->end_subject > mb->start_used_ptr)
-            {
-            mb->hitend = TRUE;
-            if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
-            }
-          break;
-          }
-
-        if (slength != length) samelengths = FALSE;
-        eptr += slength;
-        }
-
-      /* If the length matched for each repetition is the same as the length of
-      the captured group, we can easily work backwards. This is the normal
-      case. However, in caseless UTF-8 mode there are pairs of case-equivalent
-      characters whose lengths (in terms of code units) differ. However, this
-      is very rare, so we handle it by re-matching fewer and fewer times. */
-
-      if (samelengths)
-        {
-        while (eptr >= pp)
-          {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM15);
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          eptr -= length;
-          }
-        }
-
-      /* The rare case of non-matching lengths. Re-scan the repetition for each
-      iteration. We know that match_ref() will succeed every time. */
-
-      else
-        {
-        max = i;
-        for (;;)
-          {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM68);
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (eptr == pp) break;  /* Failed after minimal repetition */
-          eptr = pp;
-          max--;
-          for (i = min; i < max; i++)
-            {
-            PCRE2_SIZE slength;
-            (void)match_ref(offset, offset_top, eptr, mb, caseless, &slength);
-            eptr += slength;
-            }
-          }
-        }
-
-      RRETURN(MATCH_NOMATCH);
-      }
-    /* Control never gets here */
-
-    /* Match a bit-mapped character class, possibly repeatedly. This op code is
-    used when all the characters in the class have values in the range 0-255,
-    and either the matching is caseful, or the characters are in the range
-    0-127 when UTF-8 processing is enabled. The only difference between
-    OP_CLASS and OP_NCLASS occurs when a data character outside the range is
-    encountered.
-
-    First, look past the end of the item to see if there is repeat information
-    following. Then obey similar code to character type repeats - written out
-    again for speed. */
-
-    case OP_NCLASS:
-    case OP_CLASS:
-      {
-      /* The data variable is saved across frames, so the byte map needs to
-      be stored there. */
-#define BYTE_MAP ((uint8_t *)data)
-      data = ecode + 1;                /* Save for matching */
-      ecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */
-
-      switch (*ecode)
-        {
-        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:
-        c = *ecode++ - OP_CRSTAR;
-        if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
-        else possessive = TRUE;
-        min = rep_min[c];                 /* Pick up values from tables; */
-        max = rep_max[c];                 /* zero for max => infinity */
-        if (max == 0) max = INT_MAX;
-        break;
-
-        case OP_CRRANGE:
-        case OP_CRMINRANGE:
-        case OP_CRPOSRANGE:
-        minimize = (*ecode == OP_CRMINRANGE);
-        possessive = (*ecode == OP_CRPOSRANGE);
-        min = GET2(ecode, 1);
-        max = GET2(ecode, 1 + IMM2_SIZE);
-        if (max == 0) max = INT_MAX;
-        ecode += 1 + 2 * IMM2_SIZE;
-        break;
-
-        default:               /* No repeat follows */
-        min = max = 1;
-        break;
-        }
-
-      /* First, ensure the minimum number of matches are present. */
-
-#ifdef SUPPORT_UNICODE
-      if (utf)
-        {
-        for (i = 1; i <= min; i++)
-          {
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          GETCHARINC(c, eptr);
-          if (c > 255)
-            {
-            if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
-            }
-          else
-            if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
-          }
-        }
-      else
-#endif
-      /* Not UTF mode */
-        {
-        for (i = 1; i <= min; i++)
-          {
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          c = *eptr++;
-#if PCRE2_CODE_UNIT_WIDTH != 8
-          if (c > 255)
-            {
-            if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
-            }
-          else
-#endif
-            if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
-          }
-        }
-
-      /* If max == min we can continue with the main loop without the
-      need to recurse. */
-
-      if (min == max) continue;
-
-      /* If minimizing, keep testing the rest of the expression and advancing
-      the pointer while it matches the class. */
-
-      if (minimize)
-        {
-#ifdef SUPPORT_UNICODE
-        if (utf)
-          {
-          for (fi = min;; fi++)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM16);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              RRETURN(MATCH_NOMATCH);
-              }
-            GETCHARINC(c, eptr);
-            if (c > 255)
-              {
-              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
-              }
-            else
-              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
-            }
-          }
-        else
-#endif
-        /* Not UTF mode */
-          {
-          for (fi = min;; fi++)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM17);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              RRETURN(MATCH_NOMATCH);
-              }
-            c = *eptr++;
-#if PCRE2_CODE_UNIT_WIDTH != 8
-            if (c > 255)
-              {
-              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
-              }
-            else
-#endif
-              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
-            }
-          }
-        /* Control never gets here */
-        }
-
-      /* If maximizing, find the longest possible run, then work backwards. */
-
-      else
-        {
-        pp = eptr;
-
-#ifdef SUPPORT_UNICODE
-        if (utf)
-          {
-          for (i = min; i < max; i++)
-            {
-            int len = 1;
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              break;
-              }
-            GETCHARLEN(c, eptr, len);
-            if (c > 255)
-              {
-              if (op == OP_CLASS) break;
-              }
-            else
-              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
-            eptr += len;
-            }
-
-          if (possessive) continue;    /* No backtracking */
-
-          for (;;)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM18);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (eptr-- == pp) break;        /* Stop if tried at original pos */
-            BACKCHAR(eptr);
-            }
-          }
-        else
-#endif
-          /* Not UTF mode */
-          {
-          for (i = min; i < max; i++)
-            {
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              break;
-              }
-            c = *eptr;
-#if PCRE2_CODE_UNIT_WIDTH != 8
-            if (c > 255)
-              {
-              if (op == OP_CLASS) break;
-              }
-            else
-#endif
-              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
-            eptr++;
-            }
-
-          if (possessive) continue;    /* No backtracking */
-
-          while (eptr >= pp)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM19);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            eptr--;
-            }
-          }
-
-        RRETURN(MATCH_NOMATCH);
-        }
-#undef BYTE_MAP
-      }
-    /* Control never gets here */
-
-
-    /* Match an extended character class. In the 8-bit library, this opcode is
-    encountered only when UTF-8 mode mode is supported. In the 16-bit and
-    32-bit libraries, codepoints greater than 255 may be encountered even when
-    UTF is not supported. */
-
-#ifdef SUPPORT_WIDE_CHARS
-    case OP_XCLASS:
-      {
-      data = ecode + 1 + LINK_SIZE;                /* Save for matching */
-      ecode += GET(ecode, 1);                      /* Advance past the item */
-
-      switch (*ecode)
-        {
-        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:
-        c = *ecode++ - OP_CRSTAR;
-        if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
-        else possessive = TRUE;
-        min = rep_min[c];                 /* Pick up values from tables; */
-        max = rep_max[c];                 /* zero for max => infinity */
-        if (max == 0) max = INT_MAX;
-        break;
-
-        case OP_CRRANGE:
-        case OP_CRMINRANGE:
-        case OP_CRPOSRANGE:
-        minimize = (*ecode == OP_CRMINRANGE);
-        possessive = (*ecode == OP_CRPOSRANGE);
-        min = GET2(ecode, 1);
-        max = GET2(ecode, 1 + IMM2_SIZE);
-        if (max == 0) max = INT_MAX;
-        ecode += 1 + 2 * IMM2_SIZE;
-        break;
-
-        default:               /* No repeat follows */
-        min = max = 1;
-        break;
-        }
-
-      /* First, ensure the minimum number of matches are present. */
-
-      for (i = 1; i <= min; i++)
-        {
-        if (eptr >= mb->end_subject)
-          {
-          SCHECK_PARTIAL();
-          RRETURN(MATCH_NOMATCH);
-          }
-        GETCHARINCTEST(c, eptr);
-        if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
-        }
-
-      /* If max == min we can continue with the main loop without the
-      need to recurse. */
-
-      if (min == max) continue;
-
-      /* If minimizing, keep testing the rest of the expression and advancing
-      the pointer while it matches the class. */
-
-      if (minimize)
-        {
-        for (fi = min;; fi++)
-          {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM20);
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) RRETURN(MATCH_NOMATCH);
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          GETCHARINCTEST(c, eptr);
-          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
-          }
-        /* Control never gets here */
-        }
-
-      /* If maximizing, find the longest possible run, then work backwards. */
-
-      else
-        {
-        pp = eptr;
-        for (i = min; i < max; i++)
-          {
-          int len = 1;
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            break;
-            }
-#ifdef SUPPORT_UNICODE
-          GETCHARLENTEST(c, eptr, len);
-#else
-          c = *eptr;
-#endif
-          if (!PRIV(xclass)(c, data, utf)) break;
-          eptr += len;
-          }
-
-        if (possessive) continue;    /* No backtracking */
-
-        for(;;)
-          {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM21);
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (eptr-- == pp) break;        /* Stop if tried at original pos */
-#ifdef SUPPORT_UNICODE
-          if (utf) BACKCHAR(eptr);
-#endif
-          }
-        RRETURN(MATCH_NOMATCH);
-        }
-
-      /* Control never gets here */
-      }
-#endif    /* End of XCLASS */
-
-    /* Match a single character, casefully */
-
-    case OP_CHAR:
-#ifdef SUPPORT_UNICODE
-    if (utf)
-      {
-      length = 1;
-      ecode++;
-      GETCHARLEN(fc, ecode, length);
-      if (length > (PCRE2_SIZE)(mb->end_subject - eptr))
-        {
-        CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
-        RRETURN(MATCH_NOMATCH);
-        }
-      for (; length > 0; length--)
-        {
-        if (*ecode++ != UCHAR21INC(eptr)) RRETURN(MATCH_NOMATCH);
-        }
-      }
-    else
-#endif
-    /* Not UTF mode */
-      {
-      if (mb->end_subject - eptr < 1)
-        {
-        SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
-        RRETURN(MATCH_NOMATCH);
-        }
-      if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
-      ecode += 2;
-      }
+    Fecode++;
     break;
 
-    /* Match a single character, caselessly. If we are at the end of the
-    subject, give up immediately. */
-
-    case OP_CHARI:
-    if (eptr >= mb->end_subject)
-      {
-      SCHECK_PARTIAL();
-      RRETURN(MATCH_NOMATCH);
-      }
-
-#ifdef SUPPORT_UNICODE
-    if (utf)
-      {
-      length = 1;
-      ecode++;
-      GETCHARLEN(fc, ecode, length);
-
-      /* If the pattern character's value is < 128, we have only one byte, and
-      we know that its other case must also be one byte long, so we can use the
-      fast lookup table. We know that there is at least one byte left in the
-      subject. */
-
-      if (fc < 128)
-        {
-        uint32_t cc = UCHAR21(eptr);
-        if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
-        ecode++;
-        eptr++;
-        }
-
-      /* Otherwise we must pick up the subject character. Note that we cannot
-      use the value of "length" to check for sufficient bytes left, because the
-      other case of the character may have more or fewer bytes.  */
-
-      else
-        {
-        uint32_t dc;
-        GETCHARINC(dc, eptr);
-        ecode += length;
-
-        /* If we have Unicode property support, we can use it to test the other
-        case of the character, if there is one. */
-
-        if (fc != dc)
-          {
-#ifdef SUPPORT_UNICODE
-          if (dc != UCD_OTHERCASE(fc))
-#endif
-            RRETURN(MATCH_NOMATCH);
-          }
-        }
-      }
-    else
-#endif   /* SUPPORT_UNICODE */
-
-    /* Not UTF mode */
-      {
-      if (TABLE_GET(ecode[1], mb->lcc, ecode[1])
-          != TABLE_GET(*eptr, mb->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
-      eptr++;
-      ecode += 2;
-      }
-    break;
-
-    /* Match a single character repeatedly. */
-
-    case OP_EXACT:
-    case OP_EXACTI:
-    min = max = GET2(ecode, 1);
-    ecode += 1 + IMM2_SIZE;
-    goto REPEATCHAR;
-
-    case OP_POSUPTO:
-    case OP_POSUPTOI:
-    possessive = TRUE;
-    /* Fall through */
-
-    case OP_UPTO:
-    case OP_UPTOI:
-    case OP_MINUPTO:
-    case OP_MINUPTOI:
-    min = 0;
-    max = GET2(ecode, 1);
-    minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
-    ecode += 1 + IMM2_SIZE;
-    goto REPEATCHAR;
-
-    case OP_POSSTAR:
-    case OP_POSSTARI:
-    possessive = TRUE;
-    min = 0;
-    max = INT_MAX;
-    ecode++;
-    goto REPEATCHAR;
-
-    case OP_POSPLUS:
-    case OP_POSPLUSI:
-    possessive = TRUE;
-    min = 1;
-    max = INT_MAX;
-    ecode++;
-    goto REPEATCHAR;
-
-    case OP_POSQUERY:
-    case OP_POSQUERYI:
-    possessive = TRUE;
-    min = 0;
-    max = 1;
-    ecode++;
-    goto REPEATCHAR;
-
-    case OP_STAR:
-    case OP_STARI:
-    case OP_MINSTAR:
-    case OP_MINSTARI:
-    case OP_PLUS:
-    case OP_PLUSI:
-    case OP_MINPLUS:
-    case OP_MINPLUSI:
-    case OP_QUERY:
-    case OP_QUERYI:
-    case OP_MINQUERY:
-    case OP_MINQUERYI:
-    c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI);
-    minimize = (c & 1) != 0;
-    min = rep_min[c];                 /* Pick up values from tables; */
-    max = rep_max[c];                 /* zero for max => infinity */
-    if (max == 0) max = INT_MAX;
-
-    /* Common code for all repeated single-character matches. We first check
-    for the minimum number of characters. If the minimum equals the maximum, we
-    are done. Otherwise, if minimizing, check the rest of the pattern for a
-    match; if there isn't one, advance up to the maximum, one character at a
-    time.
-
-    If maximizing, advance up to the maximum number of matching characters,
-    until eptr is past the end of the maximum run. If possessive, we are
-    then done (no backing up). Otherwise, match at this position; anything
-    other than no match is immediately returned. For nomatch, back up one
-    character, unless we are matching \R and the last thing matched was
-    \r\n, in which case, back up two bytes. When we reach the first optional
-    character position, we can save stack by doing a tail recurse.
-
-    The various UTF/non-UTF and caseful/caseless cases are handled separately,
-    for speed. */
-
-    REPEATCHAR:
-#ifdef SUPPORT_UNICODE
-    if (utf)
-      {
-      length = 1;
-      charptr = ecode;
-      GETCHARLEN(fc, ecode, length);
-      ecode += length;
-
-      /* Handle multibyte character matching specially here. There is
-      support for caseless matching if UCP support is present. */
-
-      if (length > 1)
-        {
-        uint32_t othercase;
-        if (op >= OP_STARI &&     /* Caseless */
-            (othercase = UCD_OTHERCASE(fc)) != fc)
-          oclength = PRIV(ord2utf)(othercase, occhars);
-        else oclength = 0;
-
-        for (i = 1; i <= min; i++)
-          {
-          if (eptr <= mb->end_subject - length &&
-            memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length;
-          else if (oclength > 0 &&
-                   eptr <= mb->end_subject - oclength &&
-                   memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength;
-          else
-            {
-            CHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          }
-
-        if (min == max) continue;
-
-        if (minimize)
-          {
-          for (fi = min;; fi++)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM22);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr <= mb->end_subject - length &&
-              memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length;
-            else if (oclength > 0 &&
-                     eptr <= mb->end_subject - oclength &&
-                     memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength;
-            else
-              {
-              CHECK_PARTIAL();
-              RRETURN(MATCH_NOMATCH);
-              }
-            }
-          /* Control never gets here */
-          }
-
-        else  /* Maximize */
-          {
-          pp = eptr;
-          for (i = min; i < max; i++)
-            {
-            if (eptr <= mb->end_subject - length &&
-                memcmp(eptr, charptr, CU2BYTES(length)) == 0) eptr += length;
-            else if (oclength > 0 &&
-                     eptr <= mb->end_subject - oclength &&
-                     memcmp(eptr, occhars, CU2BYTES(oclength)) == 0) eptr += oclength;
-            else
-              {
-              CHECK_PARTIAL();
-              break;
-              }
-            }
-
-          if (possessive) continue;    /* No backtracking */
-
-          /* After \C in UTF mode, pp might be in the middle of a Unicode
-          character. Use <= pp to ensure backtracking doesn't go too far. */
-
-          for(;;)
-            {
-            if (eptr <= pp) goto TAIL_RECURSE;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM23);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            eptr--;
-            BACKCHAR(eptr);
-            }
-          }
-        /* Control never gets here */
-        }
-
-      /* If the length of a UTF-8 character is 1, we fall through here, and
-      obey the code as for non-UTF-8 characters below, though in this case the
-      value of fc will always be < 128. */
-      }
-    else
 #endif  /* SUPPORT_UNICODE */
 
-      /* When not in UTF-8 mode, load a single-byte character. */
-      fc = *ecode++;
 
-    /* The value of fc at this point is always one character, though we may
-    or may not be in UTF mode. The code is duplicated for the caseless and
-    caseful cases, for speed, since matching characters is likely to be quite
-    common. First, ensure the minimum number of matches are present. If min =
-    max, continue at the same level without recursing. Otherwise, if
-    minimizing, keep trying the rest of the expression and advancing one
-    matching character if failing, up to the maximum. Alternatively, if
-    maximizing, find the maximum number of characters and work backwards. */
+    /* ===================================================================== */
+    /* Match a single character type repeatedly. Note that the property type
+    does not need to be in a stack frame as it not used within an RMATCH()
+    loop. */
 
-    if (op >= OP_STARI)  /* Caseless */
-      {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-      /* fc must be < 128 if UTF is enabled. */
-      foc = mb->fcc[fc];
-#else
-#ifdef SUPPORT_UNICODE
-      if (utf && fc > 127)
-        foc = UCD_OTHERCASE(fc);
-      else
-#endif /* SUPPORT_UNICODE */
-        foc = TABLE_GET(fc, mb->fcc, fc);
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
-
-      for (i = 1; i <= min; i++)
-        {
-        uint32_t cc;                 /* Faster than PCRE2_UCHAR */
-        if (eptr >= mb->end_subject)
-          {
-          SCHECK_PARTIAL();
-          RRETURN(MATCH_NOMATCH);
-          }
-        cc = UCHAR21TEST(eptr);
-        if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
-        eptr++;
-        }
-      if (min == max) continue;
-      if (minimize)
-        {
-        for (fi = min;; fi++)
-          {
-          uint32_t cc;               /* Faster than PCRE2_UCHAR */
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM24);
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) RRETURN(MATCH_NOMATCH);
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          cc = UCHAR21TEST(eptr);
-          if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
-          eptr++;
-          }
-        /* Control never gets here */
-        }
-      else  /* Maximize */
-        {
-        pp = eptr;
-        for (i = min; i < max; i++)
-          {
-          uint32_t cc;               /* Faster than PCRE2_UCHAR */
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            break;
-            }
-          cc = UCHAR21TEST(eptr);
-          if (fc != cc && foc != cc) break;
-          eptr++;
-          }
-        if (possessive) continue;       /* No backtracking */
-        for (;;)
-          {
-          if (eptr == pp) goto TAIL_RECURSE;
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM25);
-          eptr--;
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          }
-        /* Control never gets here */
-        }
-      }
-
-    /* Caseful comparisons (includes all multi-byte characters) */
-
-    else
-      {
-      for (i = 1; i <= min; i++)
-        {
-        if (eptr >= mb->end_subject)
-          {
-          SCHECK_PARTIAL();
-          RRETURN(MATCH_NOMATCH);
-          }
-        if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH);
-        }
-
-      if (min == max) continue;
-
-      if (minimize)
-        {
-        for (fi = min;; fi++)
-          {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM26);
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) RRETURN(MATCH_NOMATCH);
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH);
-          }
-        /* Control never gets here */
-        }
-      else  /* Maximize */
-        {
-        pp = eptr;
-        for (i = min; i < max; i++)
-          {
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            break;
-            }
-          if (fc != UCHAR21TEST(eptr)) break;
-          eptr++;
-          }
-        if (possessive) continue;    /* No backtracking */
-        for (;;)
-          {
-          if (eptr == pp) goto TAIL_RECURSE;
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM27);
-          eptr--;
-          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          }
-        /* Control never gets here */
-        }
-      }
-    /* Control never gets here */
-
-    /* Match a negated single one-byte character. The character we are
-    checking can be multibyte. */
-
-    case OP_NOT:
-    case OP_NOTI:
-    if (eptr >= mb->end_subject)
-      {
-      SCHECK_PARTIAL();
-      RRETURN(MATCH_NOMATCH);
-      }
-#ifdef SUPPORT_UNICODE
-    if (utf)
-      {
-      register uint32_t ch, och;
-
-      ecode++;
-      GETCHARINC(ch, ecode);
-      GETCHARINC(c, eptr);
-
-      if (op == OP_NOT)
-        {
-        if (ch == c) RRETURN(MATCH_NOMATCH);
-        }
-      else
-        {
-        if (ch > 127)
-          och = UCD_OTHERCASE(ch);
-        else
-          och = TABLE_GET(ch, mb->fcc, ch);
-        if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
-        }
-      }
-    else
-#endif  /* SUPPORT_UNICODE */
-      {
-      register uint32_t ch = ecode[1];
-      c = *eptr++;
-      if (ch == c || (op == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == c))
-        RRETURN(MATCH_NOMATCH);
-      ecode += 2;
-      }
-    break;
-
-    /* Match a negated single one-byte character repeatedly. This is almost a
-    repeat of the code for a repeated single character, but I haven't found a
-    nice way of commoning these up that doesn't require a test of the
-    positive/negative option for each character match. Maybe that wouldn't add
-    very much to the time taken, but character matching *is* what this is all
-    about... */
-
-    case OP_NOTEXACT:
-    case OP_NOTEXACTI:
-    min = max = GET2(ecode, 1);
-    ecode += 1 + IMM2_SIZE;
-    goto REPEATNOTCHAR;
-
-    case OP_NOTUPTO:
-    case OP_NOTUPTOI:
-    case OP_NOTMINUPTO:
-    case OP_NOTMINUPTOI:
-    min = 0;
-    max = GET2(ecode, 1);
-    minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
-    ecode += 1 + IMM2_SIZE;
-    goto REPEATNOTCHAR;
-
-    case OP_NOTPOSSTAR:
-    case OP_NOTPOSSTARI:
-    possessive = TRUE;
-    min = 0;
-    max = INT_MAX;
-    ecode++;
-    goto REPEATNOTCHAR;
-
-    case OP_NOTPOSPLUS:
-    case OP_NOTPOSPLUSI:
-    possessive = TRUE;
-    min = 1;
-    max = INT_MAX;
-    ecode++;
-    goto REPEATNOTCHAR;
-
-    case OP_NOTPOSQUERY:
-    case OP_NOTPOSQUERYI:
-    possessive = TRUE;
-    min = 0;
-    max = 1;
-    ecode++;
-    goto REPEATNOTCHAR;
-
-    case OP_NOTPOSUPTO:
-    case OP_NOTPOSUPTOI:
-    possessive = TRUE;
-    min = 0;
-    max = GET2(ecode, 1);
-    ecode += 1 + IMM2_SIZE;
-    goto REPEATNOTCHAR;
-
-    case OP_NOTSTAR:
-    case OP_NOTSTARI:
-    case OP_NOTMINSTAR:
-    case OP_NOTMINSTARI:
-    case OP_NOTPLUS:
-    case OP_NOTPLUSI:
-    case OP_NOTMINPLUS:
-    case OP_NOTMINPLUSI:
-    case OP_NOTQUERY:
-    case OP_NOTQUERYI:
-    case OP_NOTMINQUERY:
-    case OP_NOTMINQUERYI:
-    c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
-    minimize = (c & 1) != 0;
-    min = rep_min[c];                 /* Pick up values from tables; */
-    max = rep_max[c];                 /* zero for max => infinity */
-    if (max == 0) max = INT_MAX;
-
-    /* Common code for all repeated single-byte matches. */
-
-    REPEATNOTCHAR:
-    GETCHARINCTEST(fc, ecode);
-
-    /* The code is duplicated for the caseless and caseful cases, for speed,
-    since matching characters is likely to be quite common. First, ensure the
-    minimum number of matches are present. If min = max, continue at the same
-    level without recursing. Otherwise, if minimizing, keep trying the rest of
-    the expression and advancing one matching character if failing, up to the
-    maximum. Alternatively, if maximizing, find the maximum number of
-    characters and work backwards. */
-
-    if (op >= OP_NOTSTARI)     /* Caseless */
-      {
-#ifdef SUPPORT_UNICODE
-      if (utf && fc > 127)
-        foc = UCD_OTHERCASE(fc);
-      else
-#endif /* SUPPORT_UNICODE */
-        foc = TABLE_GET(fc, mb->fcc, fc);
-
-#ifdef SUPPORT_UNICODE
-      if (utf)
-        {
-        register uint32_t d;
-        for (i = 1; i <= min; i++)
-          {
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          GETCHARINC(d, eptr);
-          if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH);
-          }
-        }
-      else
-#endif  /* SUPPORT_UNICODE */
-      /* Not UTF mode */
-        {
-        for (i = 1; i <= min; i++)
-          {
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
-          eptr++;
-          }
-        }
-
-      if (min == max) continue;
-
-      if (minimize)
-        {
-#ifdef SUPPORT_UNICODE
-        if (utf)
-          {
-          register uint32_t d;
-          for (fi = min;; fi++)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM28);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              RRETURN(MATCH_NOMATCH);
-              }
-            GETCHARINC(d, eptr);
-            if (fc == d || (uint32_t)foc == d) RRETURN(MATCH_NOMATCH);
-            }
-          }
-        else
-#endif  /*SUPPORT_UNICODE */
-        /* Not UTF mode */
-          {
-          for (fi = min;; fi++)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM29);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              RRETURN(MATCH_NOMATCH);
-              }
-            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
-            eptr++;
-            }
-          }
-        /* Control never gets here */
-        }
-
-      /* Maximize case */
-
-      else
-        {
-        pp = eptr;
-
-#ifdef SUPPORT_UNICODE
-        if (utf)
-          {
-          register uint32_t d;
-          for (i = min; i < max; i++)
-            {
-            int len = 1;
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              break;
-              }
-            GETCHARLEN(d, eptr, len);
-            if (fc == d || (uint32_t)foc == d) break;
-            eptr += len;
-            }
-          if (possessive) continue;    /* No backtracking */
-
-          /* After \C in UTF mode, pp might be in the middle of a Unicode
-          character. Use <= pp to ensure backtracking doesn't go too far. */
-
-          for(;;)
-            {
-            if (eptr <= pp) goto TAIL_RECURSE;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM30);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            eptr--;
-            BACKCHAR(eptr);
-            }
-          }
-        else
-#endif  /* SUPPORT_UNICODE */
-        /* Not UTF mode */
-          {
-          for (i = min; i < max; i++)
-            {
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              break;
-              }
-            if (fc == *eptr || foc == *eptr) break;
-            eptr++;
-            }
-          if (possessive) continue;    /* No backtracking */
-          for (;;)
-            {
-            if (eptr == pp) goto TAIL_RECURSE;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM31);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            eptr--;
-            }
-          }
-        /* Control never gets here */
-        }
-      }
-
-    /* Caseful comparisons */
-
-    else
-      {
-#ifdef SUPPORT_UNICODE
-      if (utf)
-        {
-        register uint32_t d;
-        for (i = 1; i <= min; i++)
-          {
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          GETCHARINC(d, eptr);
-          if (fc == d) RRETURN(MATCH_NOMATCH);
-          }
-        }
-      else
-#endif
-      /* Not UTF mode */
-        {
-        for (i = 1; i <= min; i++)
-          {
-          if (eptr >= mb->end_subject)
-            {
-            SCHECK_PARTIAL();
-            RRETURN(MATCH_NOMATCH);
-            }
-          if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
-          }
-        }
-
-      if (min == max) continue;
-
-      if (minimize)
-        {
-#ifdef SUPPORT_UNICODE
-        if (utf)
-          {
-          register uint32_t d;
-          for (fi = min;; fi++)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM32);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              RRETURN(MATCH_NOMATCH);
-              }
-            GETCHARINC(d, eptr);
-            if (fc == d) RRETURN(MATCH_NOMATCH);
-            }
-          }
-        else
-#endif
-        /* Not UTF mode */
-          {
-          for (fi = min;; fi++)
-            {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM33);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              RRETURN(MATCH_NOMATCH);
-              }
-            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
-            }
-          }
-        /* Control never gets here */
-        }
-
-      /* Maximize case */
-
-      else
-        {
-        pp = eptr;
-
-#ifdef SUPPORT_UNICODE
-        if (utf)
-          {
-          register uint32_t d;
-          for (i = min; i < max; i++)
-            {
-            int len = 1;
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              break;
-              }
-            GETCHARLEN(d, eptr, len);
-            if (fc == d) break;
-            eptr += len;
-            }
-          if (possessive) continue;    /* No backtracking */
-
-          /* After \C in UTF mode, pp might be in the middle of a Unicode
-          character. Use <= pp to ensure backtracking doesn't go too far. */
-
-          for(;;)
-            {
-            if (eptr <= pp) goto TAIL_RECURSE;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM34);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            eptr--;
-            BACKCHAR(eptr);
-            }
-          }
-        else
-#endif
-        /* Not UTF mode */
-          {
-          for (i = min; i < max; i++)
-            {
-            if (eptr >= mb->end_subject)
-              {
-              SCHECK_PARTIAL();
-              break;
-              }
-            if (fc == *eptr) break;
-            eptr++;
-            }
-          if (possessive) continue;    /* No backtracking */
-          for (;;)
-            {
-            if (eptr == pp) goto TAIL_RECURSE;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM35);
-            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            eptr--;
-            }
-          }
-        /* Control never gets here */
-        }
-      }
-    /* Control never gets here */
-
-    /* Match a single character type repeatedly; several different opcodes
-    share code. This is very similar to the code for single characters, but we
-    repeat it in the interests of efficiency. */
+#define Lstart_eptr  F->temp_sptr[0]
+#define Lmin         F->temp_32[0]
+#define Lmax         F->temp_32[1]
+#define Lctype       F->temp_32[2]
+#define Lpropvalue   F->temp_32[3]
 
     case OP_TYPEEXACT:
-    min = max = GET2(ecode, 1);
-    minimize = TRUE;
-    ecode += 1 + IMM2_SIZE;
+    Lmin = Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
     goto REPEATTYPE;
 
     case OP_TYPEUPTO:
     case OP_TYPEMINUPTO:
-    min = 0;
-    max = GET2(ecode, 1);
-    minimize = *ecode == OP_TYPEMINUPTO;
-    ecode += 1 + IMM2_SIZE;
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    reptype = (*Fecode == OP_TYPEMINUPTO)? REPTYPE_MIN : REPTYPE_MAX;
+    Fecode += 1 + IMM2_SIZE;
     goto REPEATTYPE;
 
     case OP_TYPEPOSSTAR:
-    possessive = TRUE;
-    min = 0;
-    max = INT_MAX;
-    ecode++;
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = UINT32_MAX;
+    Fecode++;
     goto REPEATTYPE;
 
     case OP_TYPEPOSPLUS:
-    possessive = TRUE;
-    min = 1;
-    max = INT_MAX;
-    ecode++;
+    reptype = REPTYPE_POS;
+    Lmin = 1;
+    Lmax = UINT32_MAX;
+    Fecode++;
     goto REPEATTYPE;
 
     case OP_TYPEPOSQUERY:
-    possessive = TRUE;
-    min = 0;
-    max = 1;
-    ecode++;
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = 1;
+    Fecode++;
     goto REPEATTYPE;
 
     case OP_TYPEPOSUPTO:
-    possessive = TRUE;
-    min = 0;
-    max = GET2(ecode, 1);
-    ecode += 1 + IMM2_SIZE;
+    reptype = REPTYPE_POS;
+    Lmin = 0;
+    Lmax = GET2(Fecode, 1);
+    Fecode += 1 + IMM2_SIZE;
     goto REPEATTYPE;
 
     case OP_TYPESTAR:
@@ -4216,127 +2512,122 @@
     case OP_TYPEMINPLUS:
     case OP_TYPEQUERY:
     case OP_TYPEMINQUERY:
-    c = *ecode++ - OP_TYPESTAR;
-    minimize = (c & 1) != 0;
-    min = rep_min[c];                 /* Pick up values from tables; */
-    max = rep_max[c];                 /* zero for max => infinity */
-    if (max == 0) max = INT_MAX;
+    fc = *Fecode++ - OP_TYPESTAR;
+    Lmin = rep_min[fc];
+    Lmax = rep_max[fc];
+    reptype = rep_typ[fc];
 
-    /* Common code for all repeated single character type matches. Note that
-    in UTF-8 mode, '.' matches a character of any length, but for the other
-    character types, the valid characters are all one-byte long. */
+    /* Common code for all repeated character type matches. */
 
     REPEATTYPE:
-    ctype = *ecode++;      /* Code for the character type */
+    Lctype = *Fecode++;      /* Code for the character type */
 
 #ifdef SUPPORT_UNICODE
-    if (ctype == OP_PROP || ctype == OP_NOTPROP)
+    if (Lctype == OP_PROP || Lctype == OP_NOTPROP)
       {
-      prop_fail_result = ctype == OP_NOTPROP;
-      prop_type = *ecode++;
-      prop_value = *ecode++;
+      proptype = *Fecode++;
+      Lpropvalue = *Fecode++;
       }
-    else prop_type = -1;
+    else proptype = -1;
 #endif
 
     /* First, ensure the minimum number of matches are present. Use inline
     code for maximizing the speed, and do the type test once at the start
-    (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
-    is tidier. Also separate the UCP code, which can be the same for both UTF-8
-    and single-bytes. */
+    (i.e. keep it out of the loop). The code for UTF mode is separated out for
+    tidiness, except for Unicode property tests. */
 
-    if (min > 0)
+    if (Lmin > 0)
       {
 #ifdef SUPPORT_UNICODE
-      if (prop_type >= 0)
+      if (proptype >= 0)  /* Property tests in all modes */
         {
-        switch(prop_type)
+        switch(proptype)
           {
           case PT_ANY:
-          if (prop_fail_result) RRETURN(MATCH_NOMATCH);
-          for (i = 1; i <= min; i++)
+          if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+          for (i = 1; i <= Lmin; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
+            GETCHARINCTEST(fc, Feptr);
             }
           break;
 
           case PT_LAMP:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
             int chartype;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            chartype = UCD_CHARTYPE(c);
+            GETCHARINCTEST(fc, Feptr);
+            chartype = UCD_CHARTYPE(fc);
             if ((chartype == ucp_Lu ||
                  chartype == ucp_Ll ||
-                 chartype == ucp_Lt) == prop_fail_result)
+                 chartype == ucp_Lt) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           break;
 
           case PT_GC:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           break;
 
           case PT_PC:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           break;
 
           case PT_SC:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           break;
 
           case PT_ALNUM:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
             int category;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            category = UCD_CATEGORY(c);
-            if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            category = UCD_CATEGORY(fc);
+            if ((category == ucp_L || category == ucp_N) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           break;
@@ -4347,23 +2638,23 @@
 
           case PT_SPACE:    /* Perl space */
           case PT_PXSPACE:  /* POSIX space */
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            switch(c)
+            GETCHARINCTEST(fc, Feptr);
+            switch(fc)
               {
               HSPACE_CASES:
               VSPACE_CASES:
-              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+              if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
               break;
 
               default:
-              if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+              if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))
                 RRETURN(MATCH_NOMATCH);
               break;
               }
@@ -4371,55 +2662,61 @@
           break;
 
           case PT_WORD:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
             int category;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            category = UCD_CATEGORY(c);
-            if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
-                   == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            category = UCD_CATEGORY(fc);
+            if ((category == ucp_L || category == ucp_N ||
+                fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           break;
 
           case PT_CLIST:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
             const uint32_t *cp;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            cp = PRIV(ucd_caseless_sets) + prop_value;
+            GETCHARINCTEST(fc, Feptr);
+            cp = PRIV(ucd_caseless_sets) + Lpropvalue;
             for (;;)
               {
-              if (c < *cp)
-                { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
-              if (c == *cp++)
-                { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
+              if (fc < *cp)
+                {
+                if (Lctype == OP_NOTPROP) break;
+                RRETURN(MATCH_NOMATCH);
+                }
+              if (fc == *cp++)
+                {
+                if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+                break;
+                }
               }
             }
           break;
 
           case PT_UCNC:
-          for (i = 1; i <= min; i++)
+          for (i = 1; i <= Lmin; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
-                 c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
-                 c >= 0xe000) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
+                 fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
+                 fc >= 0xe000) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           break;
@@ -4427,105 +2724,95 @@
           /* This should not occur */
 
           default:
-          RRETURN(PCRE2_ERROR_INTERNAL);
+          return PCRE2_ERROR_INTERNAL;
           }
         }
 
       /* Match extended Unicode sequences. We will get here only if the
       support is in the binary; otherwise a compile-time error occurs. */
 
-      else if (ctype == OP_EXTUNI)
+      else if (Lctype == OP_EXTUNI)
         {
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
           else
             {
-            int lgb, rgb;
-            GETCHARINCTEST(c, eptr);
-            lgb = UCD_GRAPHBREAK(c);
-           while (eptr < mb->end_subject)
-              {
-              int len = 1;
-              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
-              rgb = UCD_GRAPHBREAK(c);
-              if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
-              lgb = rgb;
-              eptr += len;
-              }
+            GETCHARINCTEST(fc, Feptr);
+            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject,
+              mb->end_subject, utf, NULL);
             }
           CHECK_PARTIAL();
           }
         }
-
       else
 #endif     /* SUPPORT_UNICODE */
 
-/* Handle all other cases when the coding is UTF-8 */
+/* Handle all other cases in UTF mode */
 
 #ifdef SUPPORT_UNICODE
-      if (utf) switch(ctype)
+      if (utf) switch(Lctype)
         {
         case OP_ANY:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+          if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
           if (mb->partial != 0 &&
-              eptr + 1 >= mb->end_subject &&
+              Feptr + 1 >= mb->end_subject &&
               NLBLOCK->nltype == NLTYPE_FIXED &&
               NLBLOCK->nllen == 2 &&
-              UCHAR21(eptr) == NLBLOCK->nl[0])
+              UCHAR21(Feptr) == NLBLOCK->nl[0])
             {
             mb->hitend = TRUE;
-            if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
             }
-          eptr++;
-          ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+          Feptr++;
+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
           }
         break;
 
         case OP_ALLANY:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          eptr++;
-          ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+          Feptr++;
+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
           }
         break;
 
         case OP_ANYBYTE:
-        if (eptr > mb->end_subject - min) RRETURN(MATCH_NOMATCH);
-        eptr += min;
+        if (Feptr > mb->end_subject - Lmin) RRETURN(MATCH_NOMATCH);
+        Feptr += Lmin;
         break;
 
         case OP_ANYNL:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          GETCHARINC(c, eptr);
-          switch(c)
+          GETCHARINC(fc, Feptr);
+          switch(fc)
             {
             default: RRETURN(MATCH_NOMATCH);
 
             case CHAR_CR:
-            if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++;
+            if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;
             break;
 
             case CHAR_LF:
@@ -4545,49 +2832,49 @@
         break;
 
         case OP_NOT_HSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          GETCHARINC(c, eptr);
-          switch(c)
+          GETCHARINC(fc, Feptr);
+          switch(fc)
             {
-            HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */
+            HSPACE_CASES: RRETURN(MATCH_NOMATCH);
             default: break;
             }
           }
         break;
 
         case OP_HSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          GETCHARINC(c, eptr);
-          switch(c)
+          GETCHARINC(fc, Feptr);
+          switch(fc)
             {
-            HSPACE_CASES: break;  /* Byte and multibyte cases */
+            HSPACE_CASES: break;
             default: RRETURN(MATCH_NOMATCH);
             }
           }
         break;
 
         case OP_NOT_VSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          GETCHARINC(c, eptr);
-          switch(c)
+          GETCHARINC(fc, Feptr);
+          switch(fc)
             {
             VSPACE_CASES: RRETURN(MATCH_NOMATCH);
             default: break;
@@ -4596,15 +2883,15 @@
         break;
 
         case OP_VSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          GETCHARINC(c, eptr);
-          switch(c)
+          GETCHARINC(fc, Feptr);
+          switch(fc)
             {
             VSPACE_CASES: break;
             default: RRETURN(MATCH_NOMATCH);
@@ -4613,170 +2900,174 @@
         break;
 
         case OP_NOT_DIGIT:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          GETCHARINC(c, eptr);
-          if (c < 128 && (mb->ctypes[c] & ctype_digit) != 0)
+          GETCHARINC(fc, Feptr);
+          if (fc < 128 && (mb->ctypes[fc] & ctype_digit) != 0)
             RRETURN(MATCH_NOMATCH);
           }
         break;
 
         case OP_DIGIT:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
           uint32_t cc;
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          cc = UCHAR21(eptr);
+          cc = UCHAR21(Feptr);
           if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
-          /* No need to skip more bytes - we know it's a 1-byte character */
+          Feptr++;
+          /* No need to skip more code units - we know it has only one. */
           }
         break;
 
         case OP_NOT_WHITESPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
           uint32_t cc;
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          cc = UCHAR21(eptr);
+          cc = UCHAR21(Feptr);
           if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
-          ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+          Feptr++;
+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
           }
         break;
 
         case OP_WHITESPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
           uint32_t cc;
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          cc = UCHAR21(eptr);
+          cc = UCHAR21(Feptr);
           if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
-          /* No need to skip more bytes - we know it's a 1-byte character */
+          Feptr++;
+          /* No need to skip more code units - we know it has only one. */
           }
         break;
 
         case OP_NOT_WORDCHAR:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
           uint32_t cc;
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          cc = UCHAR21(eptr);
+          cc = UCHAR21(Feptr);
           if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
-          ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+          Feptr++;
+          ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
           }
         break;
 
         case OP_WORDCHAR:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
           uint32_t cc;
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          cc = UCHAR21(eptr);
+          cc = UCHAR21(Feptr);
           if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
-          /* No need to skip more bytes - we know it's a 1-byte character */
+          Feptr++;
+          /* No need to skip more code units - we know it has only one. */
           }
         break;
 
         default:
-        RRETURN(PCRE2_ERROR_INTERNAL);
-        }  /* End switch(ctype) */
+        return PCRE2_ERROR_INTERNAL;
+        }  /* End switch(Lctype) */
 
       else
 #endif     /* SUPPORT_UNICODE */
 
-      /* Code for the non-UTF-8 case for minimum matching of operators other
+      /* Code for the non-UTF case for minimum matching of operators other
       than OP_PROP and OP_NOTPROP. */
 
-      switch(ctype)
+      switch(Lctype)
         {
         case OP_ANY:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+          if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
           if (mb->partial != 0 &&
-              eptr + 1 >= mb->end_subject &&
+              Feptr + 1 >= mb->end_subject &&
               NLBLOCK->nltype == NLTYPE_FIXED &&
               NLBLOCK->nllen == 2 &&
-              *eptr == NLBLOCK->nl[0])
+              *Feptr == NLBLOCK->nl[0])
             {
             mb->hitend = TRUE;
-            if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
             }
-          eptr++;
+          Feptr++;
           }
         break;
 
         case OP_ALLANY:
-        if (eptr > mb->end_subject - min)
+        if (Feptr > mb->end_subject - Lmin)
           {
           SCHECK_PARTIAL();
           RRETURN(MATCH_NOMATCH);
           }
-        eptr += min;
+        Feptr += Lmin;
         break;
 
-        case OP_ANYBYTE:
-        if (eptr > mb->end_subject - min)
-          {
-          SCHECK_PARTIAL();
-          RRETURN(MATCH_NOMATCH);
-          }
-        eptr += min;
-        break;
+        /* This OP_ANYBYTE case will never be reached because \C gets turned
+        into OP_ALLANY in non-UTF mode. Cut out the code so that coverage
+        reports don't complain about it's never being used. */
 
+/*        case OP_ANYBYTE:
+*        if (Feptr > mb->end_subject - Lmin)
+*          {
+*          SCHECK_PARTIAL();
+*          RRETURN(MATCH_NOMATCH);
+*          }
+*        Feptr += Lmin;
+*        break;
+*/
         case OP_ANYNL:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          switch(*eptr++)
+          switch(*Feptr++)
             {
             default: RRETURN(MATCH_NOMATCH);
 
             case CHAR_CR:
-            if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++;
+            if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;
             break;
 
             case CHAR_LF:
@@ -4796,14 +3087,14 @@
         break;
 
         case OP_NOT_HSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          switch(*eptr++)
+          switch(*Feptr++)
             {
             default: break;
             HSPACE_BYTE_CASES:
@@ -4816,14 +3107,14 @@
         break;
 
         case OP_HSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          switch(*eptr++)
+          switch(*Feptr++)
             {
             default: RRETURN(MATCH_NOMATCH);
             HSPACE_BYTE_CASES:
@@ -4836,14 +3127,14 @@
         break;
 
         case OP_NOT_VSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          switch(*eptr++)
+          switch(*Feptr++)
             {
             VSPACE_BYTE_CASES:
 #if PCRE2_CODE_UNIT_WIDTH != 8
@@ -4856,14 +3147,14 @@
         break;
 
         case OP_VSPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          switch(*eptr++)
+          switch(*Feptr++)
             {
             default: RRETURN(MATCH_NOMATCH);
             VSPACE_BYTE_CASES:
@@ -4876,212 +3167,212 @@
         break;
 
         case OP_NOT_DIGIT:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0)
+          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
+          Feptr++;
           }
         break;
 
         case OP_DIGIT:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0)
+          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
+          Feptr++;
           }
         break;
 
         case OP_NOT_WHITESPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0)
+          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
+          Feptr++;
           }
         break;
 
         case OP_WHITESPACE:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0)
+          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
+          Feptr++;
           }
         break;
 
         case OP_NOT_WORDCHAR:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0)
+          if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
+          Feptr++;
           }
         break;
 
         case OP_WORDCHAR:
-        for (i = 1; i <= min; i++)
+        for (i = 1; i <= Lmin; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0)
+          if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)
             RRETURN(MATCH_NOMATCH);
-          eptr++;
+          Feptr++;
           }
         break;
 
         default:
-        RRETURN(PCRE2_ERROR_INTERNAL);
+        return PCRE2_ERROR_INTERNAL;
         }
       }
 
-    /* If min = max, continue at the same level without recursing */
+    /* If Lmin = Lmax we are done. Continue with the main loop. */
 
-    if (min == max) continue;
+    if (Lmin == Lmax) continue;
 
     /* If minimizing, we have to test the rest of the pattern before each
-    subsequent match. Again, separate the UTF-8 case for speed, and also
-    separate the UCP cases. */
+    subsequent match. */
 
-    if (minimize)
+    if (reptype == REPTYPE_MIN)
       {
 #ifdef SUPPORT_UNICODE
-      if (prop_type >= 0)
+      if (proptype >= 0)
         {
-        switch(prop_type)
+        switch(proptype)
           {
           case PT_ANY:
-          for (fi = min;; fi++)
+          for (;;)
             {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM36);
+            RMATCH(Fecode, RM208);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+            GETCHARINCTEST(fc, Feptr);
+            if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
 
           case PT_LAMP:
-          for (fi = min;; fi++)
+          for (;;)
             {
             int chartype;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM37);
+            RMATCH(Fecode, RM209);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            chartype = UCD_CHARTYPE(c);
+            GETCHARINCTEST(fc, Feptr);
+            chartype = UCD_CHARTYPE(fc);
             if ((chartype == ucp_Lu ||
                  chartype == ucp_Ll ||
-                 chartype == ucp_Lt) == prop_fail_result)
+                 chartype == ucp_Lt) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
 
           case PT_GC:
-          for (fi = min;; fi++)
+          for (;;)
             {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM38);
+            RMATCH(Fecode, RM210);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
 
           case PT_PC:
-          for (fi = min;; fi++)
+          for (;;)
             {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM39);
+            RMATCH(Fecode, RM211);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
 
           case PT_SC:
-          for (fi = min;; fi++)
+          for (;;)
             {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM40);
+            RMATCH(Fecode, RM212);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
 
           case PT_ALNUM:
-          for (fi = min;; fi++)
+          for (;;)
             {
             int category;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM59);
+            RMATCH(Fecode, RM213);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            category = UCD_CATEGORY(c);
-            if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            category = UCD_CATEGORY(fc);
+            if ((category == ucp_L || category == ucp_N) ==
+                (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
@@ -5092,26 +3383,26 @@
 
           case PT_SPACE:    /* Perl space */
           case PT_PXSPACE:  /* POSIX space */
-          for (fi = min;; fi++)
+          for (;;)
             {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM61);
+            RMATCH(Fecode, RM214);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            switch(c)
+            GETCHARINCTEST(fc, Feptr);
+            switch(fc)
               {
               HSPACE_CASES:
               VSPACE_CASES:
-              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+              if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
               break;
 
               default:
-              if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+              if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))
                 RRETURN(MATCH_NOMATCH);
               break;
               }
@@ -5119,105 +3410,101 @@
           /* Control never gets here */
 
           case PT_WORD:
-          for (fi = min;; fi++)
+          for (;;)
             {
             int category;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM62);
+            RMATCH(Fecode, RM215);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            category = UCD_CATEGORY(c);
+            GETCHARINCTEST(fc, Feptr);
+            category = UCD_CATEGORY(fc);
             if ((category == ucp_L ||
                  category == ucp_N ||
-                 c == CHAR_UNDERSCORE)
-                   == prop_fail_result)
+                 fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
 
           case PT_CLIST:
-          for (fi = min;; fi++)
+          for (;;)
             {
             const uint32_t *cp;
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM67);
+            RMATCH(Fecode, RM216);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            cp = PRIV(ucd_caseless_sets) + prop_value;
+            GETCHARINCTEST(fc, Feptr);
+            cp = PRIV(ucd_caseless_sets) + Lpropvalue;
             for (;;)
               {
-              if (c < *cp)
-                { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
-              if (c == *cp++)
-                { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
+              if (fc < *cp)
+                {
+                if (Lctype == OP_NOTPROP) break;
+                RRETURN(MATCH_NOMATCH);
+                }
+              if (fc == *cp++)
+                {
+                if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+                break;
+                }
               }
             }
           /* Control never gets here */
 
           case PT_UCNC:
-          for (fi = min;; fi++)
+          for (;;)
             {
-            RMATCH(eptr, ecode, offset_top, mb, eptrb, RM60);
+            RMATCH(Fecode, RM217);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-            if (fi >= max) RRETURN(MATCH_NOMATCH);
-            if (eptr >= mb->end_subject)
+            if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               RRETURN(MATCH_NOMATCH);
               }
-            GETCHARINCTEST(c, eptr);
-            if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
-                 c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
-                 c >= 0xe000) == prop_fail_result)
+            GETCHARINCTEST(fc, Feptr);
+            if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
+                 fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
+                 fc >= 0xe000) == (Lctype == OP_NOTPROP))
               RRETURN(MATCH_NOMATCH);
             }
           /* Control never gets here */
 
           /* This should never occur */
           default:
-          RRETURN(PCRE2_ERROR_INTERNAL);
+          return PCRE2_ERROR_INTERNAL;
           }
         }
 
       /* Match extended Unicode sequences. We will get here only if the
       support is in the binary; otherwise a compile-time error occurs. */
 
-      else if (ctype == OP_EXTUNI)
+      else if (Lctype == OP_EXTUNI)
         {
-        for (fi = min;; fi++)
+        for (;;)
           {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM41);
+          RMATCH(Fecode, RM218);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) RRETURN(MATCH_NOMATCH);
-          if (eptr >= mb->end_subject)
+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
           else
             {
-            int lgb, rgb;
-            GETCHARINCTEST(c, eptr);
-            lgb = UCD_GRAPHBREAK(c);
-            while (eptr < mb->end_subject)
-              {
-              int len = 1;
-              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
-              rgb = UCD_GRAPHBREAK(c);
-              if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
-              lgb = rgb;
-              eptr += len;
-              }
+            GETCHARINCTEST(fc, Feptr);
+            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
+              utf, NULL);
             }
           CHECK_PARTIAL();
           }
@@ -5225,33 +3512,34 @@
       else
 #endif     /* SUPPORT_UNICODE */
 
+      /* UTF mode for non-property testing character types. */
+
 #ifdef SUPPORT_UNICODE
       if (utf)
         {
-        for (fi = min;; fi++)
+        for (;;)
           {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM42);
+          RMATCH(Fecode, RM219);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) RRETURN(MATCH_NOMATCH);
-          if (eptr >= mb->end_subject)
+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (ctype == OP_ANY && IS_NEWLINE(eptr))
-            RRETURN(MATCH_NOMATCH);
-          GETCHARINC(c, eptr);
-          switch(ctype)
+          if (Lctype == OP_ANY && IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
+          GETCHARINC(fc, Feptr);
+          switch(Lctype)
             {
             case OP_ANY:               /* This is the non-NL case */
             if (mb->partial != 0 &&    /* Take care with CRLF partial */
-                eptr >= mb->end_subject &&
+                Feptr >= mb->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
-                c == NLBLOCK->nl[0])
+                fc == NLBLOCK->nl[0])
               {
               mb->hitend = TRUE;
-              if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
               }
             break;
 
@@ -5260,11 +3548,12 @@
             break;
 
             case OP_ANYNL:
-            switch(c)
+            switch(fc)
               {
               default: RRETURN(MATCH_NOMATCH);
+
               case CHAR_CR:
-              if (eptr < mb->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++;
+              if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;
               break;
 
               case CHAR_LF:
@@ -5277,13 +3566,14 @@
               case 0x2028:
               case 0x2029:
 #endif  /* Not EBCDIC */
-              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
+              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)
+                RRETURN(MATCH_NOMATCH);
               break;
               }
             break;
 
             case OP_NOT_HSPACE:
-            switch(c)
+            switch(fc)
               {
               HSPACE_CASES: RRETURN(MATCH_NOMATCH);
               default: break;
@@ -5291,7 +3581,7 @@
             break;
 
             case OP_HSPACE:
-            switch(c)
+            switch(fc)
               {
               HSPACE_CASES: break;
               default: RRETURN(MATCH_NOMATCH);
@@ -5299,7 +3589,7 @@
             break;
 
             case OP_NOT_VSPACE:
-            switch(c)
+            switch(fc)
               {
               VSPACE_CASES: RRETURN(MATCH_NOMATCH);
               default: break;
@@ -5307,7 +3597,7 @@
             break;
 
             case OP_VSPACE:
-            switch(c)
+            switch(fc)
               {
               VSPACE_CASES: break;
               default: RRETURN(MATCH_NOMATCH);
@@ -5315,68 +3605,69 @@
             break;
 
             case OP_NOT_DIGIT:
-            if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0)
+            if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0)
               RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_DIGIT:
-            if (c >= 256 || (mb->ctypes[c] & ctype_digit) == 0)
+            if (fc >= 256 || (mb->ctypes[fc] & ctype_digit) == 0)
               RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_NOT_WHITESPACE:
-            if (c < 256 && (mb->ctypes[c] & ctype_space) != 0)
+            if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0)
               RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_WHITESPACE:
-            if (c >= 256 || (mb->ctypes[c] & ctype_space) == 0)
+            if (fc >= 256 || (mb->ctypes[fc] & ctype_space) == 0)
               RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_NOT_WORDCHAR:
-            if (c < 256 && (mb->ctypes[c] & ctype_word) != 0)
+            if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0)
               RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_WORDCHAR:
-            if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0)
+            if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0)
               RRETURN(MATCH_NOMATCH);
             break;
 
             default:
-            RRETURN(PCRE2_ERROR_INTERNAL);
+            return PCRE2_ERROR_INTERNAL;
             }
           }
         }
       else
-#endif
+#endif  /* SUPPORT_UNICODE */
+
       /* Not UTF mode */
         {
-        for (fi = min;; fi++)
+        for (;;)
           {
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM43);
+          RMATCH(Fecode, RM33);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          if (fi >= max) RRETURN(MATCH_NOMATCH);
-          if (eptr >= mb->end_subject)
+          if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             RRETURN(MATCH_NOMATCH);
             }
-          if (ctype == OP_ANY && IS_NEWLINE(eptr))
+          if (Lctype == OP_ANY && IS_NEWLINE(Feptr))
             RRETURN(MATCH_NOMATCH);
-          c = *eptr++;
-          switch(ctype)
+          fc = *Feptr++;
+          switch(Lctype)
             {
             case OP_ANY:               /* This is the non-NL case */
             if (mb->partial != 0 &&    /* Take care with CRLF partial */
-                eptr >= mb->end_subject &&
+                Feptr >= mb->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
-                c == NLBLOCK->nl[0])
+                fc == NLBLOCK->nl[0])
               {
               mb->hitend = TRUE;
-              if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
               }
             break;
 
@@ -5385,11 +3676,12 @@
             break;
 
             case OP_ANYNL:
-            switch(c)
+            switch(fc)
               {
               default: RRETURN(MATCH_NOMATCH);
+
               case CHAR_CR:
-              if (eptr < mb->end_subject && *eptr == CHAR_LF) eptr++;
+              if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;
               break;
 
               case CHAR_LF:
@@ -5402,13 +3694,14 @@
               case 0x2028:
               case 0x2029:
 #endif
-              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
+              if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)
+                RRETURN(MATCH_NOMATCH);
               break;
               }
             break;
 
             case OP_NOT_HSPACE:
-            switch(c)
+            switch(fc)
               {
               default: break;
               HSPACE_BYTE_CASES:
@@ -5420,7 +3713,7 @@
             break;
 
             case OP_HSPACE:
-            switch(c)
+            switch(fc)
               {
               default: RRETURN(MATCH_NOMATCH);
               HSPACE_BYTE_CASES:
@@ -5432,7 +3725,7 @@
             break;
 
             case OP_NOT_VSPACE:
-            switch(c)
+            switch(fc)
               {
               default: break;
               VSPACE_BYTE_CASES:
@@ -5444,7 +3737,7 @@
             break;
 
             case OP_VSPACE:
-            switch(c)
+            switch(fc)
               {
               default: RRETURN(MATCH_NOMATCH);
               VSPACE_BYTE_CASES:
@@ -5456,31 +3749,37 @@
             break;
 
             case OP_NOT_DIGIT:
-            if (MAX_255(c) && (mb->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
+            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)
+              RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_DIGIT:
-            if (!MAX_255(c) || (mb->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
+            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)
+              RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_NOT_WHITESPACE:
-            if (MAX_255(c) && (mb->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
+            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)
+              RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_WHITESPACE:
-            if (!MAX_255(c) || (mb->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
+            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)
+              RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_NOT_WORDCHAR:
-            if (MAX_255(c) && (mb->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
+            if (MAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)
+              RRETURN(MATCH_NOMATCH);
             break;
 
             case OP_WORDCHAR:
-            if (!MAX_255(c) || (mb->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
+            if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)
+              RRETURN(MATCH_NOMATCH);
             break;
 
             default:
-            RRETURN(PCRE2_ERROR_INTERNAL);
+            return PCRE2_ERROR_INTERNAL;
             }
           }
         }
@@ -5488,113 +3787,116 @@
       }
 
     /* If maximizing, it is worth using inline code for speed, doing the type
-    test once at the start (i.e. keep it out of the loop). Again, keep the
-    UTF-8 and UCP stuff separate. */
+    test once at the start (i.e. keep it out of the loop). */
 
     else
       {
-      pp = eptr;  /* Remember where we started */
+      Lstart_eptr = Feptr;  /* Remember where we started */
 
 #ifdef SUPPORT_UNICODE
-      if (prop_type >= 0)
+      if (proptype >= 0)
         {
-        switch(prop_type)
+        switch(proptype)
           {
           case PT_ANY:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            if (prop_fail_result) break;
-            eptr+= len;
+            GETCHARLENTEST(fc, Feptr, len);
+            if (Lctype == OP_NOTPROP) break;
+            Feptr+= len;
             }
           break;
 
           case PT_LAMP:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int chartype;
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            chartype = UCD_CHARTYPE(c);
+            GETCHARLENTEST(fc, Feptr, len);
+            chartype = UCD_CHARTYPE(fc);
             if ((chartype == ucp_Lu ||
                  chartype == ucp_Ll ||
-                 chartype == ucp_Lt) == prop_fail_result)
+                 chartype == ucp_Lt) == (Lctype == OP_NOTPROP))
               break;
-            eptr+= len;
+            Feptr+= len;
             }
           break;
 
           case PT_GC:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break;
-            eptr+= len;
+            GETCHARLENTEST(fc, Feptr, len);
+            if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
+              break;
+            Feptr+= len;
             }
           break;
 
           case PT_PC:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break;
-            eptr+= len;
+            GETCHARLENTEST(fc, Feptr, len);
+            if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
+              break;
+            Feptr+= len;
             }
           break;
 
           case PT_SC:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break;
-            eptr+= len;
+            GETCHARLENTEST(fc, Feptr, len);
+            if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
+              break;
+            Feptr+= len;
             }
           break;
 
           case PT_ALNUM:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int category;
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            category = UCD_CATEGORY(c);
-            if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+            GETCHARLENTEST(fc, Feptr, len);
+            category = UCD_CATEGORY(fc);
+            if ((category == ucp_L || category == ucp_N) ==
+                (Lctype == OP_NOTPROP))
               break;
-            eptr+= len;
+            Feptr+= len;
             }
           break;
 
@@ -5604,186 +3906,178 @@
 
           case PT_SPACE:    /* Perl space */
           case PT_PXSPACE:  /* POSIX space */
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            switch(c)
+            GETCHARLENTEST(fc, Feptr, len);
+            switch(fc)
               {
               HSPACE_CASES:
               VSPACE_CASES:
-              if (prop_fail_result) goto ENDLOOP99;  /* Break the loop */
+              if (Lctype == OP_NOTPROP) goto ENDLOOP99;  /* Break the loop */
               break;
 
               default:
-              if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+              if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))
                 goto ENDLOOP99;   /* Break the loop */
               break;
               }
-            eptr+= len;
+            Feptr+= len;
             }
           ENDLOOP99:
           break;
 
           case PT_WORD:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int category;
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            category = UCD_CATEGORY(c);
+            GETCHARLENTEST(fc, Feptr, len);
+            category = UCD_CATEGORY(fc);
             if ((category == ucp_L || category == ucp_N ||
-                 c == CHAR_UNDERSCORE) == prop_fail_result)
+                 fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP))
               break;
-            eptr+= len;
+            Feptr+= len;
             }
           break;
 
           case PT_CLIST:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             const uint32_t *cp;
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            cp = PRIV(ucd_caseless_sets) + prop_value;
+            GETCHARLENTEST(fc, Feptr, len);
+            cp = PRIV(ucd_caseless_sets) + Lpropvalue;
             for (;;)
               {
-              if (c < *cp)
-                { if (prop_fail_result) break; else goto GOT_MAX; }
-              if (c == *cp++)
-                { if (prop_fail_result) goto GOT_MAX; else break; }
+              if (fc < *cp)
+                { if (Lctype == OP_NOTPROP) break; else goto GOT_MAX; }
+              if (fc == *cp++)
+                { if (Lctype == OP_NOTPROP) goto GOT_MAX; else break; }
               }
-            eptr += len;
+            Feptr += len;
             }
           GOT_MAX:
           break;
 
           case PT_UCNC:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLENTEST(c, eptr, len);
-            if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
-                 c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
-                 c >= 0xe000) == prop_fail_result)
+            GETCHARLENTEST(fc, Feptr, len);
+            if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
+                 fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
+                 fc >= 0xe000) == (Lctype == OP_NOTPROP))
               break;
-            eptr += len;
+            Feptr += len;
             }
           break;
 
           default:
-          RRETURN(PCRE2_ERROR_INTERNAL);
+          return PCRE2_ERROR_INTERNAL;
           }
 
-        /* eptr is now past the end of the maximum run */
+        /* Feptr is now past the end of the maximum run */
 
-        if (possessive) continue;    /* No backtracking */
+        if (reptype == REPTYPE_POS) continue;    /* No backtracking */
 
-        /* After \C in UTF mode, pp might be in the middle of a Unicode
-        character. Use <= pp to ensure backtracking doesn't go too far. */
+        /* After \C in UTF mode, Lstart_eptr might be in the middle of a
+        Unicode character. Use <= pp to ensure backtracking doesn't go too far.
+        */
 
         for(;;)
           {
-          if (eptr <= pp) goto TAIL_RECURSE;
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM44);
+          if (Feptr <= Lstart_eptr) break;
+          RMATCH(Fecode, RM222);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          eptr--;
-          if (utf) BACKCHAR(eptr);
+          Feptr--;
+          if (utf) BACKCHAR(Feptr);
           }
         }
 
       /* Match extended Unicode grapheme clusters. We will get here only if the
       support is in the binary; otherwise a compile-time error occurs. */
 
-      else if (ctype == OP_EXTUNI)
+      else if (Lctype == OP_EXTUNI)
         {
-        for (i = min; i < max; i++)
+        for (i = Lmin; i < Lmax; i++)
           {
-          if (eptr >= mb->end_subject)
+          if (Feptr >= mb->end_subject)
             {
             SCHECK_PARTIAL();
             break;
             }
           else
             {
-            int lgb, rgb;
-            GETCHARINCTEST(c, eptr);
-            lgb = UCD_GRAPHBREAK(c);
-            while (eptr < mb->end_subject)
-              {
-              int len = 1;
-              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
-              rgb = UCD_GRAPHBREAK(c);
-              if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
-              lgb = rgb;
-              eptr += len;
-              }
+            GETCHARINCTEST(fc, Feptr);
+            Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
+              utf, NULL);
             }
           CHECK_PARTIAL();
           }
 
-        /* eptr is now past the end of the maximum run */
+        /* Feptr is now past the end of the maximum run */
 
-        if (possessive) continue;    /* No backtracking */
+        if (reptype == REPTYPE_POS) continue;    /* No backtracking */
 
-        /* We use <= pp rather than == pp to detect the start of the run while
-        backtracking because the use of \C in UTF mode can cause BACKCHAR to
-        move back past pp. This is just palliative; the use of \C in UTF mode
-        is fraught with danger. */
+        /* We use <= Lstart_eptr rather than == Lstart_eptr to detect the start
+        of the run while backtracking because the use of \C in UTF mode can
+        cause BACKCHAR to move back past Lstart_eptr. This is just palliative;
+        the use of \C in UTF mode is fraught with danger. */
 
         for(;;)
           {
           int lgb, rgb;
           PCRE2_SPTR fptr;
 
-          if (eptr <= pp) goto TAIL_RECURSE;   /* At start of char run */
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM45);
+          if (Feptr <= Lstart_eptr) break;   /* At start of char run */
+          RMATCH(Fecode, RM220);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
 
           /* Backtracking over an extended grapheme cluster involves inspecting
           the previous two characters (if present) to see if a break is
           permitted between them. */
 
-          eptr--;
-          if (!utf) c = *eptr; else
+          Feptr--;
+          if (!utf) fc = *Feptr; else
             {
-            BACKCHAR(eptr);
-            GETCHAR(c, eptr);
+            BACKCHAR(Feptr);
+            GETCHAR(fc, Feptr);
             }
-          rgb = UCD_GRAPHBREAK(c);
+          rgb = UCD_GRAPHBREAK(fc);
 
           for (;;)
             {
-            if (eptr <= pp) goto TAIL_RECURSE;   /* At start of char run */
-            fptr = eptr - 1;
-            if (!utf) c = *fptr; else
+            if (Feptr <= Lstart_eptr) break;   /* At start of char run */
+            fptr = Feptr - 1;
+            if (!utf) fc = *fptr; else
               {
               BACKCHAR(fptr);
-              GETCHAR(c, fptr);
+              GETCHAR(fc, fptr);
               }
-            lgb = UCD_GRAPHBREAK(c);
+            lgb = UCD_GRAPHBREAK(fc);
             if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
-            eptr = fptr;
+            Feptr = fptr;
             rgb = lgb;
             }
           }
@@ -5795,325 +4089,328 @@
 #ifdef SUPPORT_UNICODE
       if (utf)
         {
-        switch(ctype)
+        switch(Lctype)
           {
           case OP_ANY:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (IS_NEWLINE(eptr)) break;
+            if (IS_NEWLINE(Feptr)) break;
             if (mb->partial != 0 &&    /* Take care with CRLF partial */
-                eptr + 1 >= mb->end_subject &&
+                Feptr + 1 >= mb->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
-                UCHAR21(eptr) == NLBLOCK->nl[0])
+                UCHAR21(Feptr) == NLBLOCK->nl[0])
               {
               mb->hitend = TRUE;
-              if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
               }
-            eptr++;
-            ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+            Feptr++;
+            ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
             }
           break;
 
           case OP_ALLANY:
-          if (max < INT_MAX)
+          if (Lmax < UINT32_MAX)
             {
-            for (i = min; i < max; i++)
+            for (i = Lmin; i < Lmax; i++)
               {
-              if (eptr >= mb->end_subject)
+              if (Feptr >= mb->end_subject)
                 {
                 SCHECK_PARTIAL();
                 break;
                 }
-              eptr++;
-              ACROSSCHAR(eptr < mb->end_subject, *eptr, eptr++);
+              Feptr++;
+              ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
               }
             }
           else
             {
-            eptr = mb->end_subject;   /* Unlimited UTF-8 repeat */
+            Feptr = mb->end_subject;   /* Unlimited UTF-8 repeat */
             SCHECK_PARTIAL();
             }
           break;
 
-          /* The byte case is the same as non-UTF8 */
+          /* The "byte" (i.e. "code unit")  case is the same as non-UTF */
 
           case OP_ANYBYTE:
-          c = max - min;
-          if (c > (uint32_t)(mb->end_subject - eptr))
+          fc = Lmax - Lmin;
+          if (fc > (uint32_t)(mb->end_subject - Feptr))
             {
-            eptr = mb->end_subject;
+            Feptr = mb->end_subject;
             SCHECK_PARTIAL();
             }
-          else eptr += c;
+          else Feptr += fc;
           break;
 
           case OP_ANYNL:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            if (c == CHAR_CR)
+            GETCHARLEN(fc, Feptr, len);
+            if (fc == CHAR_CR)
               {
-              if (++eptr >= mb->end_subject) break;
-              if (UCHAR21(eptr) == CHAR_LF) eptr++;
+              if (++Feptr >= mb->end_subject) break;
+              if (UCHAR21(Feptr) == CHAR_LF) Feptr++;
               }
             else
               {
-              if (c != CHAR_LF &&
+              if (fc != CHAR_LF &&
                   (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
-                   (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
+                   (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL
 #ifndef EBCDIC
-                    && c != 0x2028 && c != 0x2029
+                    && fc != 0x2028 && fc != 0x2029
 #endif  /* Not EBCDIC */
                     )))
                 break;
-              eptr += len;
+              Feptr += len;
               }
             }
           break;
 
           case OP_NOT_HSPACE:
           case OP_HSPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             BOOL gotspace;
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            switch(c)
+            GETCHARLEN(fc, Feptr, len);
+            switch(fc)
               {
               HSPACE_CASES: gotspace = TRUE; break;
               default: gotspace = FALSE; break;
               }
-            if (gotspace == (ctype == OP_NOT_HSPACE)) break;
-            eptr += len;
+            if (gotspace == (Lctype == OP_NOT_HSPACE)) break;
+            Feptr += len;
             }
           break;
 
           case OP_NOT_VSPACE:
           case OP_VSPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             BOOL gotspace;
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            switch(c)
+            GETCHARLEN(fc, Feptr, len);
+            switch(fc)
               {
               VSPACE_CASES: gotspace = TRUE; break;
               default: gotspace = FALSE; break;
               }
-            if (gotspace == (ctype == OP_NOT_VSPACE)) break;
-            eptr += len;
+            if (gotspace == (Lctype == OP_NOT_VSPACE)) break;
+            Feptr += len;
             }
           break;
 
           case OP_NOT_DIGIT:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            if (c < 256 && (mb->ctypes[c] & ctype_digit) != 0) break;
-            eptr+= len;
+            GETCHARLEN(fc, Feptr, len);
+            if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0) break;
+            Feptr+= len;
             }
           break;
 
           case OP_DIGIT:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            if (c >= 256 ||(mb->ctypes[c] & ctype_digit) == 0) break;
-            eptr+= len;
+            GETCHARLEN(fc, Feptr, len);
+            if (fc >= 256 ||(mb->ctypes[fc] & ctype_digit) == 0) break;
+            Feptr+= len;
             }
           break;
 
           case OP_NOT_WHITESPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            if (c < 256 && (mb->ctypes[c] & ctype_space) != 0) break;
-            eptr+= len;
+            GETCHARLEN(fc, Feptr, len);
+            if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0) break;
+            Feptr+= len;
             }
           break;
 
           case OP_WHITESPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            if (c >= 256 ||(mb->ctypes[c] & ctype_space) == 0) break;
-            eptr+= len;
+            GETCHARLEN(fc, Feptr, len);
+            if (fc >= 256 ||(mb->ctypes[fc] & ctype_space) == 0) break;
+            Feptr+= len;
             }
           break;
 
           case OP_NOT_WORDCHAR:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            if (c < 256 && (mb->ctypes[c] & ctype_word) != 0) break;
-            eptr+= len;
+            GETCHARLEN(fc, Feptr, len);
+            if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0) break;
+            Feptr+= len;
             }
           break;
 
           case OP_WORDCHAR:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
             int len = 1;
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            GETCHARLEN(c, eptr, len);
-            if (c >= 256 || (mb->ctypes[c] & ctype_word) == 0) break;
-            eptr+= len;
+            GETCHARLEN(fc, Feptr, len);
+            if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0) break;
+            Feptr+= len;
             }
           break;
 
           default:
-          RRETURN(PCRE2_ERROR_INTERNAL);
+          return PCRE2_ERROR_INTERNAL;
           }
 
-        if (possessive) continue;    /* No backtracking */
+        if (reptype == REPTYPE_POS) continue;    /* No backtracking */
 
-        /* After \C in UTF mode, pp might be in the middle of a Unicode
-        character. Use <= pp to ensure backtracking doesn't go too far. */
+        /* 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(;;)
           {
-          if (eptr <= pp) goto TAIL_RECURSE;
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM46);
+          if (Feptr <= Lstart_eptr) break;
+          RMATCH(Fecode, RM221);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          eptr--;
-          BACKCHAR(eptr);
-          if (ctype == OP_ANYNL && eptr > pp  && UCHAR21(eptr) == CHAR_NL &&
-              UCHAR21(eptr - 1) == CHAR_CR) eptr--;
+          Feptr--;
+          BACKCHAR(Feptr);
+          if (Lctype == OP_ANYNL && Feptr > Lstart_eptr &&
+              UCHAR21(Feptr) == CHAR_NL && UCHAR21(Feptr - 1) == CHAR_CR)
+            Feptr--;
           }
         }
       else
 #endif  /* SUPPORT_UNICODE */
+
       /* Not UTF mode */
         {
-        switch(ctype)
+        switch(Lctype)
           {
           case OP_ANY:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (IS_NEWLINE(eptr)) break;
+            if (IS_NEWLINE(Feptr)) break;
             if (mb->partial != 0 &&    /* Take care with CRLF partial */
-                eptr + 1 >= mb->end_subject &&
+                Feptr + 1 >= mb->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
-                *eptr == NLBLOCK->nl[0])
+                *Feptr == NLBLOCK->nl[0])
               {
               mb->hitend = TRUE;
-              if (mb->partial > 1) RRETURN(PCRE2_ERROR_PARTIAL);
+              if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
               }
-            eptr++;
+            Feptr++;
             }
           break;
 
           case OP_ALLANY:
           case OP_ANYBYTE:
-          c = max - min;
-          if (c > (uint32_t)(mb->end_subject - eptr))
+          fc = Lmax - Lmin;
+          if (fc > (uint32_t)(mb->end_subject - Feptr))
             {
-            eptr = mb->end_subject;
+            Feptr = mb->end_subject;
             SCHECK_PARTIAL();
             }
-          else eptr += c;
+          else Feptr += fc;
           break;
 
           case OP_ANYNL:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            c = *eptr;
-            if (c == CHAR_CR)
+            fc = *Feptr;
+            if (fc == CHAR_CR)
               {
-              if (++eptr >= mb->end_subject) break;
-              if (*eptr == CHAR_LF) eptr++;
+              if (++Feptr >= mb->end_subject) break;
+              if (*Feptr == CHAR_LF) Feptr++;
               }
             else
               {
-              if (c != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
-                 (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
+              if (fc != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
+                 (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL
 #if PCRE2_CODE_UNIT_WIDTH != 8
-                 && c != 0x2028 && c != 0x2029
+                 && fc != 0x2028 && fc != 0x2029
 #endif
                  ))) break;
-              eptr++;
+              Feptr++;
               }
             }
           break;
 
           case OP_NOT_HSPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            switch(*eptr)
+            switch(*Feptr)
               {
-              default: eptr++; break;
+              default: Feptr++; break;
               HSPACE_BYTE_CASES:
 #if PCRE2_CODE_UNIT_WIDTH != 8
               HSPACE_MULTIBYTE_CASES:
@@ -6125,37 +4422,37 @@
           break;
 
           case OP_HSPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            switch(*eptr)
+            switch(*Feptr)
               {
               default: goto ENDLOOP01;
               HSPACE_BYTE_CASES:
 #if PCRE2_CODE_UNIT_WIDTH != 8
               HSPACE_MULTIBYTE_CASES:
 #endif
-              eptr++; break;
+              Feptr++; break;
               }
             }
           ENDLOOP01:
           break;
 
           case OP_NOT_VSPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            switch(*eptr)
+            switch(*Feptr)
               {
-              default: eptr++; break;
+              default: Feptr++; break;
               VSPACE_BYTE_CASES:
 #if PCRE2_CODE_UNIT_WIDTH != 8
               VSPACE_MULTIBYTE_CASES:
@@ -6167,253 +4464,1496 @@
           break;
 
           case OP_VSPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            switch(*eptr)
+            switch(*Feptr)
               {
               default: goto ENDLOOP03;
               VSPACE_BYTE_CASES:
 #if PCRE2_CODE_UNIT_WIDTH != 8
               VSPACE_MULTIBYTE_CASES:
 #endif
-              eptr++; break;
+              Feptr++; break;
               }
             }
           ENDLOOP03:
           break;
 
           case OP_NOT_DIGIT:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_digit) != 0) break;
-            eptr++;
+            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)
+              break;
+            Feptr++;
             }
           break;
 
           case OP_DIGIT:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_digit) == 0) break;
-            eptr++;
+            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)
+              break;
+            Feptr++;
             }
           break;
 
           case OP_NOT_WHITESPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_space) != 0) break;
-            eptr++;
+            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)
+              break;
+            Feptr++;
             }
           break;
 
           case OP_WHITESPACE:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_space) == 0) break;
-            eptr++;
+            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)
+              break;
+            Feptr++;
             }
           break;
 
           case OP_NOT_WORDCHAR:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (MAX_255(*eptr) && (mb->ctypes[*eptr] & ctype_word) != 0) break;
-            eptr++;
+            if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)
+              break;
+            Feptr++;
             }
           break;
 
           case OP_WORDCHAR:
-          for (i = min; i < max; i++)
+          for (i = Lmin; i < Lmax; i++)
             {
-            if (eptr >= mb->end_subject)
+            if (Feptr >= mb->end_subject)
               {
               SCHECK_PARTIAL();
               break;
               }
-            if (!MAX_255(*eptr) || (mb->ctypes[*eptr] & ctype_word) == 0) break;
-            eptr++;
+            if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)
+              break;
+            Feptr++;
             }
           break;
 
           default:
-          RRETURN(PCRE2_ERROR_INTERNAL);
+          return PCRE2_ERROR_INTERNAL;
           }
 
-        if (possessive) continue;    /* No backtracking */
+        if (reptype == REPTYPE_POS) continue;    /* No backtracking */
+
         for (;;)
           {
-          if (eptr == pp) goto TAIL_RECURSE;
-          RMATCH(eptr, ecode, offset_top, mb, eptrb, RM47);
+          if (Feptr == Lstart_eptr) break;
+          RMATCH(Fecode, RM34);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-          eptr--;
-          if (ctype == OP_ANYNL && eptr > pp  && *eptr == CHAR_LF &&
-              eptr[-1] == CHAR_CR) eptr--;
+          Feptr--;
+          if (Lctype == OP_ANYNL && Feptr > Lstart_eptr && *Feptr == CHAR_LF &&
+              Feptr[-1] == CHAR_CR) Feptr--;
           }
         }
+      }
+    break;  /* End of repeat character type processing */
 
+#undef Lstart_eptr
+#undef Lmin
+#undef Lmax
+#undef Lctype
+#undef Lpropvalue
+
+
+    /* ===================================================================== */
+    /* Match a back reference, possibly repeatedly. Look past the end of the
+    item to see if there is repeat information following. The OP_REF and
+    OP_REFI opcodes are used for a reference to a numbered group or to a
+    non-duplicated named group. For a duplicated named group, OP_DNREF and
+    OP_DNREFI are used. In this case we must scan the list of groups to which
+    the name refers, and use the first one that is set. */
+
+#define Lmin      F->temp_32[0]
+#define Lmax      F->temp_32[1]
+#define Lcaseless F->temp_32[2]
+#define Lstart    F->temp_sptr[0]
+#define Loffset   F->temp_size
+
+    case OP_DNREF:
+    case OP_DNREFI:
+    Lcaseless = (Fop == OP_DNREFI);
+      {
+      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;
+
+      while (count-- > 0)
+        {
+        Loffset = (GET2(slot, 0) << 1) - 2;
+        if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET) break;
+        slot += mb->name_entry_size;
+        }
+      }
+    goto REF_REPEAT;
+
+    case OP_REF:
+    case OP_REFI:
+    Lcaseless = (Fop == OP_REFI);
+    Loffset = (GET2(Fecode, 1) << 1) - 2;
+    Fecode += 1 + IMM2_SIZE;
+
+    /* 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
+    use temporary fields. */
+
+    REF_REPEAT:
+    switch (*Fecode)
+      {
+      case OP_CRSTAR:
+      case OP_CRMINSTAR:
+      case OP_CRPLUS:
+      case OP_CRMINPLUS:
+      case OP_CRQUERY:
+      case OP_CRMINQUERY:
+      fc = *Fecode++ - OP_CRSTAR;
+      Lmin = rep_min[fc];
+      Lmax = rep_max[fc];
+      reptype = rep_typ[fc];
+      break;
+
+      case OP_CRRANGE:
+      case OP_CRMINRANGE:
+      Lmin = GET2(Fecode, 1);
+      Lmax = GET2(Fecode, 1 + IMM2_SIZE);
+      reptype = rep_typ[*Fecode - OP_CRSTAR];
+      if (Lmax == 0) Lmax = UINT32_MAX;  /* Max 0 => infinity */
+      Fecode += 1 + 2 * IMM2_SIZE;
+      break;
+
+      default:                  /* No repeat follows */
+        {
+        rrc = match_ref(Loffset, Lcaseless, F, mb, &length);
+        if (rrc != 0)
+          {
+          if (rrc > 0) Feptr = mb->end_subject;   /* Partial match */
+          CHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        }
+      Feptr += length;
+      continue;              /* With the main loop */
+      }
+
+    /* Handle repeated back references. If a set group has length zero, just
+    continue with the main loop, because it matches however many times. For an
+    unset reference, if the minimum is zero, we can also just continue. We can
+    also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset
+    group behave as a zero-length group. For any other unset cases, carrying
+    on will result in NOMATCH. */
+
+    if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET)
+      {
+      if (Fovector[Loffset] == Fovector[Loffset + 1]) continue;
+      }
+    else  /* Group is not set */
+      {
+      if (Lmin == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
+        continue;
+      }
+
+    /* First, ensure the minimum number of matches are present. */
+
+    for (i = 1; i <= Lmin; i++)
+      {
+      PCRE2_SIZE slength;
+      rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
+      if (rrc != 0)
+        {
+        if (rrc > 0) Feptr = mb->end_subject;   /* Partial match */
+        CHECK_PARTIAL();
+        RRETURN(MATCH_NOMATCH);
+        }
+      Feptr += slength;
+      }
+
+    /* If min = max, we are done. They are not both allowed to be zero. */
+
+    if (Lmin == Lmax) continue;
+
+    /* If minimizing, keep trying and advancing the pointer. */
+
+    if (reptype == REPTYPE_MIN)
+      {
+      for (;;)
+        {
+        PCRE2_SIZE slength;
+        RMATCH(Fecode, RM20);
+        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+        if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
+        rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
+        if (rrc != 0)
+          {
+          if (rrc > 0) Feptr = mb->end_subject;   /* Partial match */
+          CHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        Feptr += slength;
+        }
       /* Control never gets here */
       }
 
+    /* If maximizing, find the longest string and work backwards, as long as
+    the matched lengths for each iteration are the same. */
+
+    else
+      {
+      BOOL samelengths = TRUE;
+      Lstart = Feptr;     /* Starting position */
+      Flength = Fovector[Loffset+1] - Fovector[Loffset];
+
+      for (i = Lmin; i < Lmax; i++)
+        {
+        PCRE2_SIZE slength;
+        rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
+        if (rrc != 0)
+          {
+          /* Can't use CHECK_PARTIAL because we don't want to update Feptr in
+          the soft partial matching case. */
+
+          if (rrc > 0 && mb->partial != 0 &&
+              mb->end_subject > mb->start_used_ptr)
+            {
+            mb->hitend = TRUE;
+            if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
+            }
+          break;
+          }
+
+        if (slength != Flength) samelengths = FALSE;
+        Feptr += slength;
+        }
+
+      /* If the length matched for each repetition is the same as the length of
+      the captured group, we can easily work backwards. This is the normal
+      case. However, in caseless UTF-8 mode there are pairs of case-equivalent
+      characters whose lengths (in terms of code units) differ. However, this
+      is very rare, so we handle it by re-matching fewer and fewer times. */
+
+      if (samelengths)
+        {
+        while (Feptr >= Lstart)
+          {
+          RMATCH(Fecode, RM21);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          Feptr -= Flength;
+          }
+        }
+
+      /* The rare case of non-matching lengths. Re-scan the repetition for each
+      iteration. We know that match_ref() will succeed every time. */
+
+      else
+        {
+        Lmax = i;
+        for (;;)
+          {
+          RMATCH(Fecode, RM22);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (Feptr == Lstart) break; /* Failed after minimal repetition */
+          Feptr = Lstart;
+          Lmax--;
+          for (i = Lmin; i < Lmax; i++)
+            {
+            PCRE2_SIZE slength;
+            (void)match_ref(Loffset, Lcaseless, F, mb, &slength);
+            Feptr += slength;
+            }
+          }
+        }
+
+      RRETURN(MATCH_NOMATCH);
+      }
+    /* Control never gets here */
+
+#undef Lcaseless
+#undef Lmin
+#undef Lmax
+#undef Lstart
+#undef Loffset
+
+
+
+/* ========================================================================= */
+/*           Opcodes for the start of various parenthesized items            */
+/* ========================================================================= */
+
+    /* In all cases, if the result of RMATCH() is MATCH_THEN, check whether the
+    (*THEN) is within the current branch by comparing the address of OP_THEN
+    that is passed back with the end of the branch. If (*THEN) is within the
+    current branch, and the branch is one of two or more alternatives (it
+    either starts or ends with OP_ALT), we have reached the limit of THEN's
+    action, so convert the return code to NOMATCH, which will cause normal
+    backtracking to happen from now on. Otherwise, THEN is passed back to an
+    outer alternative. This implements Perl's treatment of parenthesized
+    groups, where a group not containing | does not affect the current
+    alternative, that is, (X) is NOT the same as (X|(*F)). */
+
+
+    /* ===================================================================== */
+    /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a non-possessive
+    bracket group, indicating that it may occur zero times. It may repeat
+    infinitely, or not at all - i.e. it could be ()* or ()? or even (){0} in
+    the pattern. Brackets with fixed upper repeat limits are compiled as a
+    number of copies, with the optional ones preceded by BRAZERO or BRAMINZERO.
+    Possessive groups with possible zero repeats are preceded by BRAPOSZERO. */
+
+#define Lnext_ecode F->temp_sptr[0]
+
+    case OP_BRAZERO:
+    Lnext_ecode = Fecode + 1;
+    RMATCH(Lnext_ecode, RM9);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);
+    Fecode = Lnext_ecode + 1 + LINK_SIZE;
+    break;
+
+    case OP_BRAMINZERO:
+    Lnext_ecode = Fecode + 1;
+    do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);
+    RMATCH(Lnext_ecode + 1 + LINK_SIZE, RM10);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    Fecode++;
+    break;
+
+#undef Lnext_ecode
+
+    case OP_SKIPZERO:
+    Fecode++;
+    do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);
+    Fecode += 1 + LINK_SIZE;
+    break;
+
+
+    /* ===================================================================== */
+    /* Handle possessive brackets with an unlimited repeat. The end of these
+    brackets will always be OP_KETRPOS, which returns MATCH_KETRPOS without
+    going further in the pattern. */
+
+#define Lframe_type    F->temp_32[0]
+#define Lmatched_once  F->temp_32[1]
+#define Lzero_allowed  F->temp_32[2]
+#define Lstart_eptr    F->temp_sptr[0]
+#define Lstart_group   F->temp_sptr[1]
+
+    case OP_BRAPOSZERO:
+    Lzero_allowed = TRUE;                /* Zero repeat is allowed */
+    Fecode += 1;
+    if (*Fecode == OP_CBRAPOS || *Fecode == OP_SCBRAPOS)
+      goto POSSESSIVE_CAPTURE;
+    goto POSSESSIVE_NON_CAPTURE;
+
+    case OP_BRAPOS:
+    case OP_SBRAPOS:
+    Lzero_allowed = FALSE;               /* Zero repeat not allowed */
+
+    POSSESSIVE_NON_CAPTURE:
+    Lframe_type = GF_NOCAPTURE;          /* Remembered frame type */
+    goto POSSESSIVE_GROUP;
+
+    case OP_CBRAPOS:
+    case OP_SCBRAPOS:
+    Lzero_allowed = FALSE;               /* Zero repeat not allowed */
+
+    POSSESSIVE_CAPTURE:
+    number = GET2(Fecode, 1+LINK_SIZE);
+    Lframe_type = GF_CAPTURE | number;   /* Remembered frame type */
+
+    POSSESSIVE_GROUP:
+    Lmatched_once = FALSE;               /* Never matched */
+    Lstart_group = Fecode;               /* Start of this group */
+
+    for (;;)
+      {
+      Lstart_eptr = Feptr;               /* Position at group start */
+      group_frame_type = Lframe_type;
+      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM8);
+      if (rrc == MATCH_KETRPOS)
+        {
+        Lmatched_once = TRUE;            /* Matched at least once */
+        if (Feptr == Lstart_eptr)        /* Empty match; skip to end */
+          {
+          do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
+          break;
+          }
+
+        Fecode = Lstart_group;
+        continue;
+        }
+
+      /* See comment above about handling THEN. */
+
+      if (rrc == MATCH_THEN)
+        {
+        PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);
+        if (mb->verb_ecode_ptr < next_ecode &&
+            (*Fecode == OP_ALT || *next_ecode == OP_ALT))
+          rrc = MATCH_NOMATCH;
+        }
+
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      Fecode += GET(Fecode, 1);
+      if (*Fecode != OP_ALT) break;
+      }
+
+    /* Success if matched something or zero repeat allowed */
+
+    if (Lmatched_once || Lzero_allowed)
+      {
+      Fecode += 1 + LINK_SIZE;
+      break;
+      }
+
+    RRETURN(MATCH_NOMATCH);
+
+#undef Lmatched_once
+#undef Lzero_allowed
+#undef Lframe_type
+#undef Lstart_eptr
+#undef Lstart_group
+
+
+    /* ===================================================================== */
+    /* Handle non-capturing brackets that cannot match an empty string. When we
+    get to the final alternative within the brackets, as long as there are no
+    THEN's in the pattern, we can optimize by not recording a new backtracking
+    point. (Ideally we should test for a THEN within this group, but we don't
+    have that information.) Don't do this if we are at the very top level,
+    however, because that would make handling assertions and once-only brackets
+    messier when there is nothing to go back to. */
+
+#define Lframe_type F->temp_32[0]     /* Set for all that use GROUPLOOP */
+#define Lnext_branch F->temp_sptr[0]  /* Used only in OP_BRA handling */
+
+    case OP_BRA:
+    if (mb->hasthen || Frdepth == 0)
+      {
+      Lframe_type = 0;
+      goto GROUPLOOP;
+      }
+
+    for (;;)
+      {
+      Lnext_branch = Fecode + GET(Fecode, 1);
+      if (*Lnext_branch != OP_ALT) break;
+
+      /* This is never the final branch. We do not need to test for MATCH_THEN
+      here because this code is not used when there is a THEN in the pattern. */
+
+      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM1);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      Fecode = Lnext_branch;
+      }
+
+    /* Hit the start of the final branch. Continue at this level. */
+
+    Fecode += PRIV(OP_lengths)[*Fecode];
+    break;
+
+#undef Lnext_branch
+
+
+    /* ===================================================================== */
+    /* Handle a capturing bracket, other than those that are possessive with an
+    unlimited repeat. */
+
+    case OP_CBRA:
+    case OP_SCBRA:
+    Lframe_type = GF_CAPTURE | GET2(Fecode, 1+LINK_SIZE);
+    goto GROUPLOOP;
+
+
+    /* ===================================================================== */
+    /* Atomic groups and non-capturing brackets that can match an empty string
+    must record a backtracking point and also set up a chained frame. */
+
+    case OP_ONCE:
+    case OP_SBRA:
+    Lframe_type = GF_NOCAPTURE | Fop;
+
+    GROUPLOOP:
+    for (;;)
+      {
+      group_frame_type = Lframe_type;
+      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM2);
+      if (rrc == MATCH_THEN)
+        {
+        PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);
+        if (mb->verb_ecode_ptr < next_ecode &&
+            (*Fecode == OP_ALT || *next_ecode == OP_ALT))
+          rrc = MATCH_NOMATCH;
+        }
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      Fecode += GET(Fecode, 1);
+      if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+      }
+    /* Control never reaches here. */
+
+#undef Lframe_type
+
+
+    /* ===================================================================== */
+    /* Recursion either matches the current regex, or some subexpression. The
+    offset data is the offset to the starting bracket from the start of the
+    whole pattern. (This is so that it works from duplicated subpatterns.) */
+
+#define Lframe_type F->temp_32[0]
+#define Lstart_branch F->temp_sptr[0]
+
+    case OP_RECURSE:
+    bracode = mb->start_code + GET(Fecode, 1);
+    number = (bracode == mb->start_code)? 0 : GET2(bracode, 1 + LINK_SIZE);
+
+    /* If we are already in a recursion, check for repeating the same one
+    without advancing the subject pointer. This should catch convoluted mutual
+    recursions. (Some simple cases are caught at compile time.) */
+
+    if (Fcurrent_recurse != RECURSE_UNSET)
+      {
+      offset = Flast_group_offset;
+      while (offset != PCRE2_UNSET)
+        {
+        N = (heapframe *)((char *)mb->match_frames + offset);
+        P = (heapframe *)((char *)N - frame_size);
+        if (N->group_frame_type == (GF_RECURSE | number))
+          {
+          if (Feptr == P->eptr) return PCRE2_ERROR_RECURSELOOP;
+          break;
+          }
+        offset = P->last_group_offset;
+        }
+      }
+
+    /* Now run the recursion, branch by branch. */
+
+    Lstart_branch = bracode;
+    Lframe_type = GF_RECURSE | number;
+
+    for (;;)
+      {
+      PCRE2_SPTR next_ecode;
+
+      group_frame_type = Lframe_type;
+      RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM11);
+      next_ecode = Lstart_branch + GET(Lstart_branch,1);
+
+      /* Handle backtracking verbs, which are defined in a range that can
+      easily be tested for. PCRE does not allow THEN, SKIP, PRUNE or COMMIT to
+      escape beyond a recursion; they cause a NOMATCH for the entire recursion.
+
+      When one of these verbs triggers, the current recursion group number is
+      recorded. If it matches the recursion we are processing, the verb
+      happened within the recursion and we must deal with it. Otherwise it must
+      have happened after the recursion completed, and so has to be passed
+      back. See comment above about handling THEN. */
+
+      if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX &&
+          mb->verb_current_recurse == (Lframe_type ^ GF_RECURSE))
+        {
+        if (rrc == MATCH_THEN && mb->verb_ecode_ptr < next_ecode &&
+            (*Lstart_branch == OP_ALT || *next_ecode == OP_ALT))
+          rrc = MATCH_NOMATCH;
+        else RRETURN(MATCH_NOMATCH);
+        }
+
+      /* Note that carrying on after (*ACCEPT) in a recursion is handled in the
+      OP_ACCEPT code. Nothing needs to be done here. */
+
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      Lstart_branch = next_ecode;
+      if (*Lstart_branch != OP_ALT) RRETURN(MATCH_NOMATCH);
+      }
+    /* Control never reaches here. */
+
+#undef Lframe_type
+#undef Lstart_branch
+
+
+    /* ===================================================================== */
+    /* Positive assertions are like other groups except that PCRE doesn't allow
+    the effect of (*THEN) to escape beyond an assertion; it is therefore
+    treated as NOMATCH. (*ACCEPT) is treated as successful assertion, with its
+    captures retained. Any other return is an error. */
+
+#define Lframe_type  F->temp_32[0]
+
+    case OP_ASSERT:
+    case OP_ASSERTBACK:
+    Lframe_type = GF_NOCAPTURE | Fop;
+    for (;;)
+      {
+      group_frame_type = Lframe_type;
+      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM3);
+      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;
+        break;
+        }
+      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+      Fecode += GET(Fecode, 1);
+      if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+      }
+
+    do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
+    Fecode += 1 + LINK_SIZE;
+    break;
+
+#undef Lframe_type
+
+
+    /* ===================================================================== */
+    /* Handle negative assertions. Loop for each non-matching branch as for
+    positive assertions. */
+
+#define Lframe_type  F->temp_32[0]
+
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK_NOT:
+    Lframe_type  = GF_NOCAPTURE | Fop;
+
+    for (;;)
+      {
+      group_frame_type = Lframe_type;
+      RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM4);
+      switch(rrc)
+        {
+        case MATCH_ACCEPT:   /* Assertion matched, therefore it fails. */
+        case MATCH_MATCH:
+        RRETURN (MATCH_NOMATCH);
+
+        case MATCH_NOMATCH:  /* Branch failed, try next if present. */
+        case MATCH_THEN:
+        Fecode += GET(Fecode, 1);
+        if (*Fecode != OP_ALT) goto ASSERT_NOT_FAILED;
+        break;
+
+        case MATCH_COMMIT:   /* Assertion forced to fail, therefore continue. */
+        case MATCH_SKIP:
+        case MATCH_PRUNE:
+        do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
+        goto ASSERT_NOT_FAILED;
+
+        default:             /* Pass back any other return */
+        RRETURN(rrc);
+        }
+      }
+
+    /* None of the branches have matched or there was a backtrack to (*COMMIT),
+    (*SKIP), (*PRUNE), or (*THEN) in the last branch. This is success for a
+    negative assertion, so carry on. */
+
+    ASSERT_NOT_FAILED:
+    Fecode += 1 + LINK_SIZE;
+    break;
+
+#undef Lframe_type
+
+
+    /* ===================================================================== */
+    /* The callout item calls an external function, if one is provided, passing
+    details of the match so far. This is mainly for debugging, though the
+    function is able to force a failure. */
+
+    case OP_CALLOUT:
+    case OP_CALLOUT_STR:
+    rrc = do_callout(F, mb, &length);
+    if (rrc > 0) RRETURN(MATCH_NOMATCH);
+    if (rrc < 0) RRETURN(rrc);
+    Fecode += length;
+    break;
+
+
+    /* ===================================================================== */
+    /* Conditional group: compilation checked that there are no more than two
+    branches. If the condition is false, skipping the first branch takes us
+    past the end of the item if there is only one branch, but that's exactly
+    what we want. */
+
+    case OP_COND:
+    case OP_SCOND:
+
+    /* The variable Flength will be added to Fecode when the condition is
+    false, to get to the second branch. Setting it to the offset to the ALT or
+    KET, then incrementing Fecode achieves this effect. However, if the second
+    branch is non-existent, we must point to the KET so that the end of the
+    group is correctly processed. We now have Fecode pointing to the condition
+    or callout. */
+
+    Flength = GET(Fecode, 1);    /* Offset to the second branch */
+    if (Fecode[Flength] != OP_ALT) Flength -= 1 + LINK_SIZE;
+    Fecode += 1 + LINK_SIZE;     /* From this opcode */
+
+    /* Because of the way auto-callout works during compile, a callout item is
+    inserted between OP_COND and an assertion condition. Such a callout can
+    also be inserted manually. */
+
+    if (*Fecode == OP_CALLOUT || *Fecode == OP_CALLOUT_STR)
+      {
+      rrc = do_callout(F, mb, &length);
+      if (rrc > 0) RRETURN(MATCH_NOMATCH);
+      if (rrc < 0) RRETURN(rrc);
+
+      /* Advance Fecode past the callout, so it now points to the condition. We
+      must adjust Flength so that the value of Fecode+Flength is unchanged. */
+
+      Fecode += length;
+      Flength -= length;
+      }
+
+    /* Test the various possible conditions */
+
+    condition = FALSE;
+    switch(*Fecode)
+      {
+      case OP_RREF:                  /* Group recursion test */
+      if (Fcurrent_recurse != RECURSE_UNSET)
+        {
+        number = GET2(Fecode, 1);
+        condition = (number == RREF_ANY || number == Fcurrent_recurse);
+        }
+      break;
+
+      case OP_DNRREF:       /* Duplicate named group recursion test */
+      if (Fcurrent_recurse != RECURSE_UNSET)
+        {
+        int count = GET2(Fecode, 1 + IMM2_SIZE);
+        PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
+        while (count-- > 0)
+          {
+          number = GET2(slot, 0);
+          condition = number == Fcurrent_recurse;
+          if (condition) break;
+          slot += mb->name_entry_size;
+          }
+        }
+      break;
+
+      case OP_CREF:                         /* Numbered group used test */
+      offset = (GET2(Fecode, 1) << 1) - 2;  /* Doubled ref number */
+      condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;
+      break;
+
+      case OP_DNCREF:      /* Duplicate named group used test */
+        {
+        int count = GET2(Fecode, 1 + IMM2_SIZE);
+        PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
+        while (count-- > 0)
+          {
+          offset = (GET2(slot, 0) << 1) - 2;
+          condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;
+          if (condition) break;
+          slot += mb->name_entry_size;
+          }
+        }
+      break;
+
+      case OP_FALSE:
+      case OP_FAIL:   /* The assertion (?!) becomes OP_FAIL */
+      break;
+
+      case OP_TRUE:
+      condition = TRUE;
+      break;
+
+      /* The condition is an assertion. Run code similar to the assertion code
+      above. */
+
+#define Lpositive      F->temp_32[0]
+#define Lstart_branch  F->temp_sptr[0]
+
+      default:
+      Lpositive = (*Fecode == OP_ASSERT || *Fecode == OP_ASSERTBACK);
+      Lstart_branch = Fecode;
+
+      for (;;)
+        {
+        group_frame_type = GF_CONDASSERT | *Fecode;
+        RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM5);
+
+        switch(rrc)
+          {
+          case MATCH_ACCEPT:  /* Save captures */
+          memcpy(Fovector,
+                (char *)assert_accept_frame + offsetof(heapframe, ovector),
+                assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));
+          Foffset_top = assert_accept_frame->offset_top;
+
+          /* Fall through */
+          /* In the case of a match, the captures have already been put into
+          the current frame. */
+
+          case MATCH_MATCH:
+          condition = Lpositive;   /* TRUE for positive assertion */
+          break;
+
+          /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
+          assertion; it is therefore always treated as NOMATCH. */
+
+          case MATCH_NOMATCH:
+          case MATCH_THEN:
+          Lstart_branch += GET(Lstart_branch, 1);
+          if (*Lstart_branch == OP_ALT) continue;  /* Try next branch */
+          condition = !Lpositive;  /* TRUE for negative assertion */
+          break;
+
+          /* These force no match without checking other branches. */
+
+          case MATCH_COMMIT:
+          case MATCH_SKIP:
+          case MATCH_PRUNE:
+          condition = !Lpositive;
+          break;
+
+          default:
+          RRETURN(rrc);
+          }
+        break;  /* Out of the branch loop */
+        }
+
+      /* If the condition is true, find the end of the assertion so that
+      advancing past it gets us to the start of the first branch. */
+
+      if (condition)
+        {
+        do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
+        }
+      break;  /* End of assertion condition */
+      }
+
+#undef Lpositive
+#undef Lstart_branch
+
+    /* Choose branch according to the condition. */
+
+    Fecode += condition? PRIV(OP_lengths)[*Fecode] : Flength;
+
+    /* If the opcode is OP_SCOND it means we are at a repeated conditional
+    group that might match an empty string. We must therefore descend a level
+    so that the start is remembered for checking. For OP_COND we can just
+    continue at this level. */
+
+    if (Fop == OP_SCOND)
+      {
+      group_frame_type  = GF_NOCAPTURE | Fop;
+      RMATCH(Fecode, RM35);
+      RRETURN(rrc);
+      }
+    break;
+
+
+
+/* ========================================================================= */
+/*                  End of start of parenthesis opcodes                      */
+/* ========================================================================= */
+
+
+    /* ===================================================================== */
+    /* Move the subject pointer back. This occurs only at the start of each
+    branch of a lookbehind assertion. If we are too close to the start to move
+    back, fail. When working with UTF-8 we move back a number of characters,
+    not bytes. */
+
+    case OP_REVERSE:
+    number = GET(Fecode, 1);
+#ifdef SUPPORT_UNICODE
+    if (utf)
+      {
+      while (number-- > 0)
+        {
+        if (Feptr <= mb->start_subject) RRETURN(MATCH_NOMATCH);
+        Feptr--;
+        BACKCHAR(Feptr);
+        }
+      }
+    else
+#endif
+
+    /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
+
+      {
+      if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH);
+      Feptr -= number;
+      }
+
+    /* Save the earliest consulted character, then skip to next op code */
+
+    if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr;
+    Fecode += 1 + LINK_SIZE;
+    break;
+
+
+    /* ===================================================================== */
+    /* An alternation is the end of a branch; scan along to find the end of the
+    bracketed group. */
+
+    case OP_ALT:
+    do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);
+    break;
+
+
+    /* ===================================================================== */
+    /* The end of a parenthesized group. For all but OP_BRA and OP_COND, the
+    starting frame was added to the chained frames in order to remember the
+    starting subject position for the group. */
+
+    case OP_KET:
+    case OP_KETRMIN:
+    case OP_KETRMAX:
+    case OP_KETRPOS:
+
+    bracode = Fecode - GET(Fecode, 1);
+
+    /* Point N to the frame at the start of the most recent group.
+    Remember the subject pointer at the start of the group. */
+
+    if (*bracode != OP_BRA && *bracode != OP_COND)
+      {
+      N = (heapframe *)((char *)mb->match_frames + Flast_group_offset);
+      P = (heapframe *)((char *)N - frame_size);
+      Flast_group_offset = P->last_group_offset;
+
+#ifdef DEBUG_SHOW_RMATCH
+      fprintf(stderr, "++ KET for frame=%d type=%x prev char offset=%lu\n",
+        N->rdepth, N->group_frame_type,
+        (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
+      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)
+        {
+        memcpy((char *)P + offsetof(heapframe, ovector), Fovector,
+          Foffset_top * sizeof(PCRE2_SIZE));
+        P->offset_top = Foffset_top;
+        Fback_frame = (char *)F - (char *)P;
+        RRETURN(MATCH_MATCH);
+        }
+      }
+    else P = NULL;   /* Indicates starting frame not recorded */
+
+    /* The group was not a conditional assertion. */
+
+    switch (*bracode)
+      {
+      case OP_BRA:    /* No need to do anything for these */
+      case OP_COND:
+      case OP_SCOND:
+      break;
+
+      /* Positive assertions are like OP_ONCE, except that in addition the
+      subject pointer must be put back to where it was at the start of the
+      assertion. */
+
+      case OP_ASSERT:
+      case OP_ASSERTBACK:
+      if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
+      Feptr = P->eptr;
+      /* Fall through */
+
+      /* For an atomic group, discard internal backtracking points. We must
+      also ensure that any remaining branches within the top-level of the group
+      are not tried. Do this by adjusting the code pointer within the backtrack
+      frame so that it points to the final branch. */
+
+      case OP_ONCE:
+      Fback_frame = ((char *)F - (char *)P) + frame_size;
+      for (;;)
+        {
+        uint32_t y = GET(P->ecode,1);
+        if ((P->ecode)[y] != OP_ALT) break;
+        P->ecode += y;
+        }
+      break;
+
+      /* A matching negative assertion returns MATCH, which is turned into
+      NOMATCH at the assertion level. */
+
+      case OP_ASSERT_NOT:
+      case OP_ASSERTBACK_NOT:
+      RRETURN(MATCH_MATCH);
+
+      /* Whole-pattern recursion is coded as a recurse into group 0, so it
+      won't be picked up here. Instead, we catch it when the OP_END is reached.
+      Other recursion is handled here. */
+
+      case OP_CBRA:
+      case OP_CBRAPOS:
+      case OP_SCBRA:
+      case OP_SCBRAPOS:
+      number = GET2(bracode, 1+LINK_SIZE);
+
+      /* Handle a recursively called group. We reinstate the previous set of
+      captures and then carry on after the recursion call. */
+
+      if (Fcurrent_recurse == number)
+        {
+        P = (heapframe *)((char *)N - frame_size);
+        memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
+          P->offset_top * sizeof(PCRE2_SIZE));
+        Foffset_top = P->offset_top;
+        Fcapture_last = P->capture_last;
+        Fcurrent_recurse = P->current_recurse;
+        Fecode = P->ecode + 1 + LINK_SIZE;
+        continue;  /* With next opcode */
+        }
+
+      /* Deal with actual capturing. */
+
+      offset = (number << 1) - 2;
+      Fcapture_last = number;
+      Fovector[offset] = P->eptr - mb->start_subject;
+      Fovector[offset+1] = Feptr - mb->start_subject;
+      if (offset >= Foffset_top) Foffset_top = offset + 2;
+      break;
+      }  /* End actions relating to the starting opcode */
+
+    /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
+    and return the MATCH_KETRPOS. This makes it possible to do the repeats one
+    at a time from the outer level. This must precede the empty string test -
+    in this case that test is done at the outer level. */
+
+    if (*Fecode == OP_KETRPOS)
+      {
+      memcpy((char *)P + offsetof(heapframe, eptr),
+             (char *)F + offsetof(heapframe, eptr),
+             frame_copy_size);
+      RRETURN(MATCH_KETRPOS);
+      }
+
+    /* Handle the different kinds of closing brackets. A non-repeating ket
+    needs no special action, just continuing at this level. This also happens
+    for the repeating kets if the group matched no characters, in order to
+    forcibly break infinite loops. Otherwise, the repeating kets try the rest
+    of the pattern or restart from the preceding bracket, in the appropriate
+    order. */
+
+    if (Fop != OP_KET && (P == NULL || Feptr != P->eptr))
+      {
+      if (Fop == OP_KETRMIN)
+        {
+        RMATCH(Fecode + 1 + LINK_SIZE, RM6);
+        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+        Fecode -= GET(Fecode, 1);
+        break;   /* End of ket processing */
+        }
+
+      /* Repeat the maximum number of times (KETRMAX) */
+
+      RMATCH(bracode, RM7);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      }
+
+    /* Carry on at this level for a non-repeating ket, or after matching an
+    empty string, or after repeating for a maximum number of times. */
+
+    Fecode += 1 + LINK_SIZE;
+    break;
+
+
+    /* ===================================================================== */
+    /* Start and end of line assertions, not multiline mode. */
+
+    case OP_CIRC:   /* Start of line, unless PCRE2_NOTBOL is set. */
+    if (Feptr != mb->start_subject || (mb->moptions & PCRE2_NOTBOL) != 0)
+      RRETURN(MATCH_NOMATCH);
+    Fecode++;
+    break;
+
+    case OP_SOD:    /* Unconditional start of subject */
+    if (Feptr != mb->start_subject) RRETURN(MATCH_NOMATCH);
+    Fecode++;
+    break;
+
+    /* When PCRE2_NOTEOL is unset, assert before the subject end, or a
+    terminating newline unless PCRE2_DOLLAR_ENDONLY is set. */
+
+    case OP_DOLL:
+    if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
+    if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;
+
+    /* Fall through */
+    /* Unconditional end of subject assertion (\z) */
+
+    case OP_EOD:
+    if (Feptr < mb->end_subject) RRETURN(MATCH_NOMATCH);
+    SCHECK_PARTIAL();
+    Fecode++;
+    break;
+
+    /* End of subject or ending \n assertion (\Z) */
+
+    case OP_EODN:
+    ASSERT_NL_OR_EOS:
+    if (Feptr < mb->end_subject &&
+        (!IS_NEWLINE(Feptr) || Feptr != mb->end_subject - mb->nllen))
+      {
+      if (mb->partial != 0 &&
+          Feptr + 1 >= mb->end_subject &&
+          NLBLOCK->nltype == NLTYPE_FIXED &&
+          NLBLOCK->nllen == 2 &&
+          UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
+        {
+        mb->hitend = TRUE;
+        if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
+        }
+      RRETURN(MATCH_NOMATCH);
+      }
+
+    /* Either at end of string or \n before end. */
+
+    SCHECK_PARTIAL();
+    Fecode++;
+    break;
+
+
+    /* ===================================================================== */
+    /* Start and end of line assertions, multiline mode. */
+
+    /* Start of subject unless notbol, or after any newline except for one at
+    the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */
+
+    case OP_CIRCM:
+    if ((mb->moptions & PCRE2_NOTBOL) != 0 && Feptr == mb->start_subject)
+      RRETURN(MATCH_NOMATCH);
+    if (Feptr != mb->start_subject &&
+        ((Feptr == mb->end_subject &&
+           (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) ||
+         !WAS_NEWLINE(Feptr)))
+      RRETURN(MATCH_NOMATCH);
+    Fecode++;
+    break;
+
+    /* Assert before any newline, or before end of subject unless noteol is
+    set. */
+
+    case OP_DOLLM:
+    if (Feptr < mb->end_subject)
+      {
+      if (!IS_NEWLINE(Feptr))
+        {
+        if (mb->partial != 0 &&
+            Feptr + 1 >= mb->end_subject &&
+            NLBLOCK->nltype == NLTYPE_FIXED &&
+            NLBLOCK->nllen == 2 &&
+            UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
+          {
+          mb->hitend = TRUE;
+          if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
+          }
+        RRETURN(MATCH_NOMATCH);
+        }
+      }
+    else
+      {
+      if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
+      SCHECK_PARTIAL();
+      }
+    Fecode++;
+    break;
+
+
+    /* ===================================================================== */
+    /* Start of match assertion */
+
+    case OP_SOM:
+    if (Feptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH);
+    Fecode++;
+    break;
+
+
+    /* ===================================================================== */
+    /* Reset the start of match point */
+
+    case OP_SET_SOM:
+    Fstart_match = Feptr;
+    Fecode++;
+    break;
+
+
+    /* ===================================================================== */
+    /* Word boundary assertions. Find out if the previous and current
+    characters are "word" characters. It takes a bit more work in UTF mode.
+    Characters > 255 are assumed to be "non-word" characters when PCRE2_UCP is
+    not set. When it is set, use Unicode properties if available, even when not
+    in UTF mode. Remember the earliest and latest consulted characters. */
+
+    case OP_NOT_WORD_BOUNDARY:
+    case OP_WORD_BOUNDARY:
+    if (Feptr == mb->start_subject) prev_is_word = FALSE; else
+      {
+      PCRE2_SPTR lastptr = Feptr - 1;
+#ifdef SUPPORT_UNICODE
+      if (utf)
+        {
+        BACKCHAR(lastptr);
+        GETCHAR(fc, lastptr);
+        }
+      else
+#endif  /* SUPPORT_UNICODE */
+      fc = *lastptr;
+      if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr;
+#ifdef SUPPORT_UNICODE
+      if ((mb->poptions & PCRE2_UCP) != 0)
+        {
+        if (fc == '_') prev_is_word = TRUE; else
+          {
+          int cat = UCD_CATEGORY(fc);
+          prev_is_word = (cat == ucp_L || cat == ucp_N);
+          }
+        }
+      else
+#endif  /* SUPPORT_UNICODE */
+      prev_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;
+      }
+
+    /* Get status of next character */
+
+    if (Feptr >= mb->end_subject)
+      {
+      SCHECK_PARTIAL();
+      cur_is_word = FALSE;
+      }
+    else
+      {
+      PCRE2_SPTR nextptr = Feptr + 1;
+#ifdef SUPPORT_UNICODE
+      if (utf)
+        {
+        FORWARDCHARTEST(nextptr, mb->end_subject);
+        GETCHAR(fc, Feptr);
+        }
+      else
+#endif  /* SUPPORT_UNICODE */
+      fc = *Feptr;
+      if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr;
+#ifdef SUPPORT_UNICODE
+      if ((mb->poptions & PCRE2_UCP) != 0)
+        {
+        if (fc == '_') cur_is_word = TRUE; else
+          {
+          int cat = UCD_CATEGORY(fc);
+          cur_is_word = (cat == ucp_L || cat == ucp_N);
+          }
+        }
+      else
+#endif  /* SUPPORT_UNICODE */
+      cur_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;
+      }
+
+    /* Now see if the situation is what we want */
+
+    if ((*Fecode++ == OP_WORD_BOUNDARY)?
+         cur_is_word == prev_is_word : cur_is_word != prev_is_word)
+      RRETURN(MATCH_NOMATCH);
+    break;
+
+
+    /* ===================================================================== */
+    /* Backtracking (*VERB)s, with and without arguments. Note that if the
+    pattern is successfully matched, we do not come back from RMATCH. */
+
+    case OP_MARK:
+    Fmark = mb->nomatch_mark = Fecode + 2;
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM12);
+
+    /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
+    argument, and we must check whether that argument matches this MARK's
+    argument. It is passed back in mb->verb_skip_ptr. If it does match, we
+    return MATCH_SKIP with mb->verb_skip_ptr now pointing to the subject
+    position that corresponds to this mark. Otherwise, pass back the return
+    code unaltered. */
+
+    if (rrc == MATCH_SKIP_ARG &&
+             PRIV(strcmp)(Fecode + 2, mb->verb_skip_ptr) == 0)
+      {
+      mb->verb_skip_ptr = Feptr;   /* Pass back current position */
+      RRETURN(MATCH_SKIP);
+      }
+    RRETURN(rrc);
+
+    case OP_FAIL:
+    RRETURN(MATCH_NOMATCH);
+
+    /* Record the current recursing group number in mb->verb_current_recurse
+    when a backtracking return such as MATCH_COMMIT is given. This enables the
+    recurse processing to catch verbs from within the recursion. */
+
+    case OP_COMMIT:
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM13);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    mb->verb_current_recurse = Fcurrent_recurse;
+    RRETURN(MATCH_COMMIT);
+
+    case OP_PRUNE:
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM14);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    mb->verb_current_recurse = Fcurrent_recurse;
+    RRETURN(MATCH_PRUNE);
+
+    case OP_PRUNE_ARG:
+    Fmark = mb->nomatch_mark = Fecode + 2;
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM15);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    mb->verb_current_recurse = Fcurrent_recurse;
+    RRETURN(MATCH_PRUNE);
+
+    case OP_SKIP:
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM16);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    mb->verb_skip_ptr = Feptr;   /* Pass back current position */
+    mb->verb_current_recurse = Fcurrent_recurse;
+    RRETURN(MATCH_SKIP);
+
+    /* Note that, for Perl compatibility, SKIP with an argument does NOT set
+    nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
+    not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
+    that failed and any that precede it (either they also failed, or were not
+    triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
+    SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg
+    set to the count of the one that failed. */
+
+    case OP_SKIP_ARG:
+    mb->skip_arg_count++;
+    if (mb->skip_arg_count <= mb->ignore_skip_arg)
+      {
+      Fecode += PRIV(OP_lengths)[*Fecode] + Fecode[1];
+      break;
+      }
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM17);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+
+    /* Pass back the current skip name and return the special MATCH_SKIP_ARG
+    return code. This will either be caught by a matching MARK, or get to the
+    top, where it causes a rematch with mb->ignore_skip_arg set to the value of
+    mb->skip_arg_count. */
+
+    mb->verb_skip_ptr = Fecode + 2;
+    mb->verb_current_recurse = Fcurrent_recurse;
+    RRETURN(MATCH_SKIP_ARG);
+
+    /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
+    the branch in which it occurs can be determined. */
+
+    case OP_THEN:
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM18);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    mb->verb_ecode_ptr = Fecode;
+    mb->verb_current_recurse = Fcurrent_recurse;
+    RRETURN(MATCH_THEN);
+
+    case OP_THEN_ARG:
+    Fmark = mb->nomatch_mark = Fecode + 2;
+    RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM19);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    mb->verb_ecode_ptr = Fecode;
+    mb->verb_current_recurse = Fcurrent_recurse;
+    RRETURN(MATCH_THEN);
+
+
+    /* ===================================================================== */
     /* There's been some horrible disaster. Arrival here can only mean there is
     something seriously wrong in the code above or the OP_xxx definitions. */
 
     default:
-    RRETURN(PCRE2_ERROR_INTERNAL);
+    return PCRE2_ERROR_INTERNAL;
     }
 
-  /* Do not stick any code in here without much thought; it is assumed
+  /* Do not insert any code in here without much thought; it is assumed
   that "continue" in the code above comes out to here to repeat the main
   loop. */
 
-  }             /* End of main loop */
+  }  /* End of main loop */
 /* Control never reaches here */
 
 
-/* When compiling to use the heap rather than the stack for recursive calls to
-match(), the RRETURN() macro jumps here. The number that is saved in
-frame->Xwhere indicates which label we actually want to return to. */
+/* ========================================================================= */
+/* The RRETURN() macro jumps here. The number that is saved in Freturn_id
+indicates which label we actually want to return to. The value in Frdepth is
+the index number of the frame in the vector. The return value has been placed
+in rrc. */
 
-#ifdef HEAP_MATCH_RECURSE
 #define LBL(val) case val: goto L_RM##val;
-HEAP_RETURN:
-switch (frame->Xwhere)
+
+RETURN_SWITCH:
+if (Frdepth == 0) return rrc;                     /* Exit from the top level */
+F = (heapframe *)((char *)F - Fback_frame);       /* Back track */
+mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */
+
+#ifdef DEBUG_SHOW_RMATCH
+fprintf(stderr, "++ RETURN %d to %d\n", rrc, Freturn_id);
+#endif
+
+switch (Freturn_id)
   {
   LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
-  LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
-  LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
-  LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
-  LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
-  LBL(65) LBL(66) LBL(68)
+  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)
+
 #ifdef SUPPORT_WIDE_CHARS
-  LBL(20) LBL(21)
+  LBL(100) LBL(101)
 #endif
+
 #ifdef SUPPORT_UNICODE
-  LBL(16) LBL(18)
-  LBL(22) LBL(23) LBL(28) LBL(30)
-  LBL(32) LBL(34) LBL(42) LBL(46)
-  LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
-  LBL(59) LBL(60) LBL(61) LBL(62) LBL(67)
-#endif  /* 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)
+#endif
+
   default:
   return PCRE2_ERROR_INTERNAL;
   }
 #undef LBL
-#endif  /* HEAP_MATCH_RECURSE */
 }
 
 
-/***************************************************************************
-****************************************************************************
-                   RECURSION IN THE match() FUNCTION
-
-Undefine all the macros that were defined above to handle this. */
-
-#ifdef HEAP_MATCH_RECURSE
-#undef eptr
-#undef ecode
-#undef mstart
-#undef offset_top
-#undef eptrb
-#undef flags
-
-#undef callpat
-#undef charptr
-#undef data
-#undef next_ecode
-#undef pp
-#undef prev
-#undef saved_eptr
-
-#undef new_recursive
-
-#undef cur_is_word
-#undef condition
-#undef prev_is_word
-
-#undef ctype
-#undef length
-#undef max
-#undef min
-#undef number
-#undef offset
-#undef op
-#undef save_capture_last
-#undef save_offset1
-#undef save_offset2
-#undef save_offset3
-
-#undef newptrb
-#endif  /* HEAP_MATCH_RECURSE */
-
-/* These two are defined as macros in both cases */
-
-#undef fc
-#undef fi
-
-/***************************************************************************
-***************************************************************************/
-
-
-#ifdef HEAP_MATCH_RECURSE
-/*************************************************
-*          Release allocated heap frames         *
-*************************************************/
-
-/* This function releases all the allocated frames. The base frame is on the
-machine stack, and so must not be freed.
-
-Argument:
-  frame_base    the address of the base frame
-  mb            the match block
-
-Returns:  nothing
-*/
-
-static void
-release_match_heapframes (heapframe *frame_base, match_block *mb)
-{
-heapframe *nextframe = frame_base->Xnextframe;
-while (nextframe != NULL)
-  {
-  heapframe *oldframe = nextframe;
-  nextframe = nextframe->Xnextframe;
-  mb->stack_memctl.free(oldframe, mb->stack_memctl.memory_data);
-  }
-}
-#endif  /* HEAP_MATCH_RECURSE */
-
-
-
 /*************************************************
 *           Match a Regular Expression           *
 *************************************************/
@@ -6444,8 +5984,6 @@
   pcre2_match_context *mcontext)
 {
 int rc;
-int ocount;
-
 const uint8_t *start_bits = NULL;
 
 const pcre2_real_code *re = (const pcre2_real_code *)code;
@@ -6455,7 +5993,6 @@
 BOOL has_first_cu = FALSE;
 BOOL has_req_cu = FALSE;
 BOOL startline;
-BOOL using_temporary_offsets = FALSE;
 BOOL utf;
 
 PCRE2_UCHAR first_cu = 0;
@@ -6470,18 +6007,22 @@
 PCRE2_SPTR start_partial = NULL;
 PCRE2_SPTR match_partial = NULL;
 
-/* We need to have mb pointing to a match block, because the IS_NEWLINE macro
-is used below, and it expects NLBLOCK to be defined as a pointer. */
+PCRE2_SIZE frame_size;
 
+/* We need to have mb as a pointer to a match block, because the IS_NEWLINE
+macro is used below, and it expects NLBLOCK to be defined as a pointer. */
+
+pcre2_callout_block cb;
 match_block actual_match_block;
 match_block *mb = &actual_match_block;
 
-#ifdef HEAP_MATCH_RECURSE
-heapframe frame_zero;
-frame_zero.Xprevframe = NULL;            /* Marks the top level */
-frame_zero.Xnextframe = NULL;            /* None are allocated yet */
-mb->match_frames_base = &frame_zero;
-#endif
+/* Allocate an initial vector of backtracking frames on the stack. If this
+proves to be too small, it is replaced by a larger one on the heap. To get a
+vector of the size required that is aligned for pointers, allocate it as a
+vector of pointers. */
+
+PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)];
+mb->stack_frames = (heapframe *)stack_frames_vector;
 
 /* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated
 subject string. */
@@ -6510,8 +6051,8 @@
 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
 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
+(*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
 adjacent, but do not have the same values. This bit of Boolean trickery assumes
 that the match-time bits are not more significant than the flag bits. If by
 accident this is not the case, a compile-time division by zero error will
@@ -6523,20 +6064,22 @@
 #undef FF
 #undef OO
 
-/* A NULL match context means "use a default context" */
-
-if (mcontext == NULL)
-  mcontext = (pcre2_match_context *)(&PRIV(default_match_context));
-
 /* These two settings are used in the code for checking a UTF string that
 follows immediately afterwards. Other values in the mb block are used only
-during interpretive pcre_match() processing, not when the JIT support is in
-use, so they are set up later. */
+during interpretive processing, not when the JIT support is in use, so they are
+set up later. */
 
 utf = (re->overall_options & PCRE2_UTF) != 0;
 mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 :
               ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0;
 
+/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
+time. */
+
+if (mb->partial != 0 &&
+   ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
+  return PCRE2_ERROR_BADOPTION;
+
 /* Check a UTF string for validity if required. For 8-bit and 16-bit strings,
 we must also check that a starting offset does not point into the middle of a
 multiunit character. We check only the portion of the subject that is going to
@@ -6595,7 +6138,7 @@
 /* It is an error to set an offset limit without setting the flag at compile
 time. */
 
-if (mcontext->offset_limit != PCRE2_UNSET &&
+if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&
      (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
   return PCRE2_ERROR_BADOFFSETLIMIT;
 
@@ -6614,7 +6157,15 @@
   }
 #endif
 
-/* Carry on with non-JIT matching. */
+/* Carry on with non-JIT matching. A NULL match context means "use a default
+context", but we take the memory control functions from the pattern. */
+
+if (mcontext == NULL)
+  {
+  mcontext = (pcre2_match_context *)(&PRIV(default_match_context));
+  mb->memctl = re->memctl;
+  }
+else mb->memctl = mcontext->memctl;
 
 anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0;
 firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
@@ -6622,14 +6173,19 @@
 bumpalong_limit =  (mcontext->offset_limit == PCRE2_UNSET)?
   end_subject : subject + mcontext->offset_limit;
 
-/* Fill in the fields in the match block. */
+/* Initialize and set up the fixed fields in the callout block, with a pointer
+in the match block. */
+
+mb->cb = &cb;
+cb.version = 2;
+cb.subject = subject;
+cb.subject_length = (PCRE2_SIZE)(end_subject - subject);
+cb.callout_flags = 0;
+
+/* Fill in the remaining fields in the match block. */
 
 mb->callout = mcontext->callout;
 mb->callout_data = mcontext->callout_data;
-mb->memctl = mcontext->memctl;
-#ifdef HEAP_MATCH_RECURSE
-mb->stack_memctl = mcontext->stack_memctl;
-#endif
 
 mb->start_subject = subject;
 mb->start_offset = start_offset;
@@ -6641,8 +6197,6 @@
 
 mb->ignore_skip_arg = 0;
 mb->mark = mb->nomatch_mark = NULL;     /* In case never set */
-mb->recursive = NULL;                   /* No recursion at top level */
-mb->ovecsave_chain = NULL;              /* No ovecsave blocks yet */
 mb->hitend = FALSE;
 
 /* The name table is needed for finding all the numbers associated with a
@@ -6653,20 +6207,6 @@
 mb->name_entry_size = re->name_entry_size;
 mb->start_code = mb->name_table + re->name_count * re->name_entry_size;
 
-/* Limits set in the pattern override the match context only if they are
-smaller. */
-
-mb->match_limit = (mcontext->match_limit < re->limit_match)?
-                  mcontext->match_limit : re->limit_match;
-mb->match_limit_recursion = (mcontext->recursion_limit < re->limit_recursion)?
-                            mcontext->recursion_limit : re->limit_recursion;
-
-/* Pointers to the individual character tables */
-
-mb->lcc = re->tables + lcc_offset;
-mb->fcc = re->tables + fcc_offset;
-mb->ctypes = re->tables + ctypes_offset;
-
 /* Process the \R and newline settings. */
 
 mb->bsr_convention = re->bsr_convention;
@@ -6683,6 +6223,11 @@
   mb->nl[0] = CHAR_NL;
   break;
 
+  case PCRE2_NEWLINE_NUL:
+  mb->nllen = 1;
+  mb->nl[0] = CHAR_NUL;
+  break;
+
   case PCRE2_NEWLINE_CRLF:
   mb->nllen = 2;
   mb->nl[0] = CHAR_CR;
@@ -6700,71 +6245,91 @@
   default: return PCRE2_ERROR_INTERNAL;
   }
 
-/* If the expression has got more back references than the offsets supplied can
-hold, we get a temporary chunk of memory to use during the matching. Otherwise,
-we can use the vector supplied. The size of the ovector is three times the
-value in the oveccount field. Two-thirds of it is pairs for storing matching
-offsets, and the top third is working space. */
+/* The backtracking frames have fixed data at the front, and a PCRE2_SIZE
+vector at the end, whose size depends on the number of capturing parentheses in
+the pattern. It is not used at all if there are no capturing parentheses.
 
-if (re->top_backref >= match_data->oveccount)
+  frame_size             is the total size of each frame
+  mb->frame_vector_size  is the total usable size of the vector (rounded down
+                           to a whole number of frames)
+
+The last of these is changed within the match() function if the frame vector
+has to be expanded. We therefore put it into the match block so that it is
+correct when calling match() more than once for non-anchored patterns. */
+
+frame_size = offsetof(heapframe, ovector) +
+  re->top_bracket * 2 * sizeof(PCRE2_SIZE);
+
+/* Limits set in the pattern override the match context only if they are
+smaller. */
+
+mb->heap_limit = (mcontext->heap_limit < re->limit_heap)?
+  mcontext->heap_limit : re->limit_heap;
+
+mb->match_limit = (mcontext->match_limit < re->limit_match)?
+  mcontext->match_limit : re->limit_match;
+
+mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
+  mcontext->depth_limit : re->limit_depth;
+
+/* If a pattern has very many capturing parentheses, the frame size may be very
+large. Ensure that there are at least 10 available frames by getting an initial
+vector on the heap if necessary, except when the heap limit prevents this. Get
+fewer if possible. (The heap limit is in kilobytes.) */
+
+if (frame_size <= START_FRAMES_SIZE/10)
   {
-  ocount = re->top_backref * 3 + 3;
-  mb->ovector = (PCRE2_SIZE *)(mb->memctl.malloc(ocount * sizeof(PCRE2_SIZE),
-    mb->memctl.memory_data));
-  if (mb->ovector == NULL) return PCRE2_ERROR_NOMEMORY;
-  using_temporary_offsets = TRUE;
+  mb->match_frames = mb->stack_frames;   /* Initial frame vector on the stack */
+  mb->frame_vector_size = ((START_FRAMES_SIZE/frame_size) * frame_size);
   }
 else
   {
-  ocount = 3 * match_data->oveccount;
-  mb->ovector = match_data->ovector;
-  }
-
-mb->offset_end = ocount;
-mb->offset_max = (2*ocount)/3;
-
-/* Reset the working variable associated with each extraction. These should
-never be used unless previously set, but they get saved and restored, and so we
-initialize them to avoid reading uninitialized locations. Also, unset the
-offsets for the matched string. This is really just for tidiness with callouts,
-in case they inspect these fields. */
-
-if (ocount > 0)
-  {
-  register PCRE2_SIZE *iptr = mb->ovector + ocount;
-  register PCRE2_SIZE *iend = iptr - re->top_bracket;
-  if (iend < mb->ovector + 2) iend = mb->ovector + 2;
-  while (--iptr >= iend) *iptr = PCRE2_UNSET;
-  mb->ovector[0] = mb->ovector[1] = PCRE2_UNSET;
-  }
-
-/* Set up the first code unit to match, if available. The first_codeunit value
-is never set for an anchored regular expression, but the anchoring may be
-forced at run time, so we have to test for anchoring. The first code unit may
-be unset for an unanchored pattern, of course. If there's no first code unit
-there may be a bitmap of possible first characters. */
-
-if (!anchored)
-  {
-  if ((re->flags & PCRE2_FIRSTSET) != 0)
+  mb->frame_vector_size = frame_size * 10;
+  if ((mb->frame_vector_size / 1024) > mb->heap_limit)
     {
-    has_first_cu = TRUE;
-    first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
-    if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
-      {
-      first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
-      if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu);
-#endif
-      }
+    if (frame_size > mb->heap_limit * 1024) return PCRE2_ERROR_HEAPLIMIT;
+    mb->frame_vector_size = ((mb->heap_limit * 1024)/frame_size) * frame_size;
     }
-  else
-    if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
-      start_bits = re->start_bitmap;
+  mb->match_frames = mb->memctl.malloc(mb->frame_vector_size,
+    mb->memctl.memory_data);
+  if (mb->match_frames == NULL) return PCRE2_ERROR_NOMEMORY;
   }
 
-/* For anchored or unanchored matches, there may be a "last known required
-character" set. */
+mb->match_frames_top =
+  (heapframe *)((char *)mb->match_frames + mb->frame_vector_size);
+
+/* Write to the ovector within the first frame to mark every capture unset and
+to avoid uninitialized memory read errors when it is copied to a new frame. */
+
+memset((char *)(mb->match_frames) + offsetof(heapframe, ovector), 0xff,
+  re->top_bracket * 2 * sizeof(PCRE2_SIZE));
+
+/* Pointers to the individual character tables */
+
+mb->lcc = re->tables + lcc_offset;
+mb->fcc = re->tables + fcc_offset;
+mb->ctypes = re->tables + ctypes_offset;
+
+/* Set up the first code unit to match, if available. If there's no first code
+unit there may be a bitmap of possible first characters. */
+
+if ((re->flags & PCRE2_FIRSTSET) != 0)
+  {
+  has_first_cu = TRUE;
+  first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
+  if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
+    {
+    first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
+    if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu);
+#endif
+    }
+  }
+else
+  if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
+    start_bits = re->start_bitmap;
+
+/* There may also be a "last known required character" set. */
 
 if ((re->flags & PCRE2_LASTSET) != 0)
   {
@@ -6788,7 +6353,6 @@
 for(;;)
   {
   PCRE2_SPTR new_start_match;
-  mb->capture_last = 0;
 
   /* ----------------- Start of match optimizations ---------------- */
 
@@ -6799,13 +6363,11 @@
 
   if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
     {
-    PCRE2_SPTR save_end_subject = end_subject;
-
     /* 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
-    first newline. Implement this by temporarily adjusting end_subject so that
-    we stop the optimization scans at a newline. If the match fails at the
-    newline, later code breaks this loop. */
+    first newline following the start of matching. Temporarily adjust
+    end_subject so that we stop the scans for a first code unit at a newline.
+    If the match fails at the newline, later code breaks the loop. */
 
     if (firstline)
       {
@@ -6813,102 +6375,179 @@
 #ifdef SUPPORT_UNICODE
       if (utf)
         {
-        while (t < mb->end_subject && !IS_NEWLINE(t))
+        while (t < end_subject && !IS_NEWLINE(t))
           {
           t++;
-          ACROSSCHAR(t < end_subject, *t, t++);
+          ACROSSCHAR(t < end_subject, t, t++);
           }
         }
       else
 #endif
-      while (t < mb->end_subject && !IS_NEWLINE(t)) t++;
+      while (t < end_subject && !IS_NEWLINE(t)) t++;
       end_subject = t;
       }
 
-    /* Advance to a unique first code unit if there is one. In 8-bit mode, the
-    use of memchr() gives a big speed up. */
+    /* Anchored: check the first code unit if one is recorded. This may seem
+    pointless but it can help in detecting a no match case without scanning for
+    the required code unit. */
 
-    if (has_first_cu)
+    if (anchored)
       {
-      PCRE2_UCHAR smc;
-      if (first_cu != first_cu2)
-        while (start_match < end_subject &&
-          (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2)
-          start_match++;
-      else
+      if (has_first_cu || start_bits != NULL)
         {
-#if PCRE2_CODE_UNIT_WIDTH != 8
-        while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu)
-          start_match++;
-#else
-        start_match = memchr(start_match, first_cu, end_subject - start_match);
-        if (start_match == NULL) start_match = end_subject;
-#endif
-        }
-      }
-
-    /* Or to just after a linebreak for a multiline match */
-
-    else if (startline)
-      {
-      if (start_match > mb->start_subject + start_offset)
-        {
-#ifdef SUPPORT_UNICODE
-        if (utf)
+        BOOL ok = start_match < end_subject;
+        if (ok)
           {
-          while (start_match < end_subject && !WAS_NEWLINE(start_match))
+          PCRE2_UCHAR c = UCHAR21TEST(start_match);
+          ok = has_first_cu && (c == first_cu || c == first_cu2);
+          if (!ok && start_bits != NULL)
             {
-            start_match++;
-            ACROSSCHAR(start_match < end_subject, *start_match,
-              start_match++);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+            if (c > 255) c = 255;
+#endif
+            ok = (start_bits[c/8] & (1 << (c&7))) != 0;
             }
           }
-        else
-#endif
-        while (start_match < end_subject && !WAS_NEWLINE(start_match))
-          start_match++;
-
-        /* If we have just passed a CR and the newline option is ANY or
-        ANYCRLF, and we are now at a LF, advance the match position by one more
-        code unit. */
-
-        if (start_match[-1] == CHAR_CR &&
-             (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
-             start_match < end_subject &&
-             UCHAR21TEST(start_match) == CHAR_NL)
-          start_match++;
+        if (!ok)
+          {
+          rc = MATCH_NOMATCH;
+          break;
+          }
         }
       }
 
-    /* Or to a non-unique first code unit if any have been identified. The
-    bitmap contains only 256 bits. When code units are 16 or 32 bits wide, all
-    code units greater than 254 set the 255 bit. */
+    /* Not anchored. Advance to a unique first code unit if there is one. In
+    8-bit mode, the use of memchr() gives a big speed up, even though we have
+    to call it twice in caseless mode, in order to find the earliest occurrence
+    of the character in either of its cases. */
 
-    else if (start_bits != NULL)
+    else
       {
-      while (start_match < end_subject)
+      if (has_first_cu)
         {
-        register uint32_t c = UCHAR21TEST(start_match);
+        if (first_cu != first_cu2)  /* Caseless */
+          {
 #if PCRE2_CODE_UNIT_WIDTH != 8
-        if (c > 255) c = 255;
+          PCRE2_UCHAR smc;
+          while (start_match < end_subject &&
+                (smc = UCHAR21TEST(start_match)) != first_cu &&
+                  smc != first_cu2)
+            start_match++;
+#else  /* 8-bit code units */
+          PCRE2_SPTR pp1 =
+            memchr(start_match, first_cu, end_subject-start_match);
+          PCRE2_SPTR pp2 =
+            memchr(start_match, first_cu2, end_subject-start_match);
+          if (pp1 == NULL)
+            start_match = (pp2 == NULL)? end_subject : pp2;
+          else
+            start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;
 #endif
-        if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
-        start_match++;
+          }
+
+        /* The caseful case */
+
+        else
+          {
+#if PCRE2_CODE_UNIT_WIDTH != 8
+          while (start_match < end_subject && UCHAR21TEST(start_match) !=
+                 first_cu)
+            start_match++;
+#else
+          start_match = memchr(start_match, first_cu, end_subject - start_match);
+          if (start_match == NULL) start_match = end_subject;
+#endif
+          }
+
+        /* If we can't find the required code unit, having reached the true end
+        of the subject, break the bumpalong loop, to force a match failure,
+        except when doing partial matching, when we let the next cycle run at
+        the end of the subject. To see why, consider the pattern /(?<=abc)def/,
+        which partially matches "abc", even though the string does not contain
+        the starting character "d". If we have not reached the true end of the
+        subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified)
+        we also let the cycle run, because the matching string is legitimately
+        allowed to start with the first code unit of a newline. */
+
+        if (!mb->partial && start_match >= mb->end_subject)
+          {
+          rc = MATCH_NOMATCH;
+          break;
+          }
         }
-      }
+
+      /* If there's no first code unit, advance to just after a linebreak for a
+      multiline match if required. */
+
+      else if (startline)
+        {
+        if (start_match > mb->start_subject + start_offset)
+          {
+#ifdef SUPPORT_UNICODE
+          if (utf)
+            {
+            while (start_match < end_subject && !WAS_NEWLINE(start_match))
+              {
+              start_match++;
+              ACROSSCHAR(start_match < end_subject, start_match, start_match++);
+              }
+            }
+          else
+#endif
+          while (start_match < end_subject && !WAS_NEWLINE(start_match))
+            start_match++;
+
+          /* If we have just passed a CR and the newline option is ANY or
+          ANYCRLF, and we are now at a LF, advance the match position by one
+          more code unit. */
+
+          if (start_match[-1] == CHAR_CR &&
+               (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
+               start_match < end_subject &&
+               UCHAR21TEST(start_match) == CHAR_NL)
+            start_match++;
+          }
+        }
+
+      /* If there's no first code unit or a requirement for a multiline line
+      start, advance to a non-unique first code unit if any have been
+      identified. The bitmap contains only 256 bits. When code units are 16 or
+      32 bits wide, all code units greater than 254 set the 255 bit. */
+
+      else if (start_bits != NULL)
+        {
+        while (start_match < end_subject)
+          {
+          uint32_t c = UCHAR21TEST(start_match);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+          if (c > 255) c = 255;
+#endif
+          if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
+          start_match++;
+          }
+
+        /* See comment above in first_cu checking about the next few lines. */
+
+        if (!mb->partial && start_match >= mb->end_subject)
+          {
+          rc = MATCH_NOMATCH;
+          break;
+          }
+        }
+      }   /* End first code unit handling */
 
     /* Restore fudged end_subject */
 
-    end_subject = save_end_subject;
+    end_subject = mb->end_subject;
 
-    /* The following two optimizations are disabled for partial matching. */
+    /* The following two optimizations must be disabled for partial matching. */
 
     if (!mb->partial)
       {
-      /* The minimum matching length is a lower bound; no actual string of that
-      length may actually match the pattern. Although the value is, strictly,
-      in characters, we treat it as code units to avoid spending too much time
-      in this optimization. */
+      /* The minimum matching length is a lower bound; no string of that length
+      may actually match the pattern. Although the value is, strictly, in
+      characters, we treat it as code units to avoid spending too much time in
+      this optimization. */
 
       if (end_subject - start_match < re->minlength)
         {
@@ -6917,12 +6556,16 @@
         }
 
       /* If req_cu is set, we know that that code unit must appear in the
-      subject for the match to succeed. If the first code unit is set, req_cu
-      must be later in the subject; otherwise the test starts at the match
-      point. This optimization can save a huge amount of backtracking in
-      patterns with nested unlimited repeats that aren't going to match.
-      Writing separate code for cased/caseless versions makes it go faster, as
-      does using an autoincrement and backing off on a match.
+      subject for the (non-partial) match to succeed. If the first code unit is
+      set, req_cu must be later in the subject; otherwise the test starts at
+      the match point. This optimization can save a huge amount of backtracking
+      in patterns with nested unlimited repeats that aren't going to match.
+      Writing separate code for caseful/caseless versions makes it go faster,
+      as does using an autoincrement and backing off on a match. As in the case
+      of the first code unit, using memchr() in the 8-bit library gives a big
+      speed up. Unlike the first_cu check above, we do not need to call
+      memchr() twice in the caseless case because we only need to check for the
+      presence of the character in either case, not find the first occurrence.
 
       HOWEVER: when the subject string is very, very long, searching to its end
       can take a long time, and give bad performance on quite ordinary
@@ -6932,30 +6575,55 @@
 
       if (has_req_cu && end_subject - start_match < REQ_CU_MAX)
         {
-        register PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
+        PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
 
         /* We don't need to repeat the search if we haven't yet reached the
-        place we found it at last time. */
+        place we found it last time round the bumpalong loop. */
 
         if (p > req_cu_ptr)
           {
-          if (req_cu != req_cu2)
+          if (p < end_subject)
             {
-            while (p < end_subject)
+            if (req_cu != req_cu2)  /* Caseless */
               {
-              register uint32_t pp = UCHAR21INCTEST(p);
-              if (pp == req_cu || pp == req_cu2) { p--; break; }
+#if PCRE2_CODE_UNIT_WIDTH != 8
+              do
+                {
+                uint32_t pp = UCHAR21INCTEST(p);
+                if (pp == req_cu || pp == req_cu2) { p--; break; }
+                }
+              while (p < end_subject);
+
+#else  /* 8-bit code units */
+              PCRE2_SPTR pp = p;
+              p = memchr(pp, req_cu, end_subject - pp);
+              if (p == NULL)
+                {
+                p = memchr(pp, req_cu2, end_subject - pp);
+                if (p == NULL) p = end_subject;
+                }
+#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
               }
-            }
-          else
-            {
-            while (p < end_subject)
+
+            /* The caseful case */
+
+            else
               {
-              if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
+#if PCRE2_CODE_UNIT_WIDTH != 8
+              do
+                {
+                if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
+                }
+              while (p < end_subject);
+
+#else  /* 8-bit code units */
+              p = memchr(p, req_cu, end_subject - p);
+              if (p == NULL) p = end_subject;
+#endif
               }
             }
 
-          /* If we can't find the required code unit, break the matching loop,
+          /* If we can't find the required code unit, break the bumpalong loop,
           forcing a match failure. */
 
           if (p >= end_subject)
@@ -6965,8 +6633,8 @@
             }
 
           /* If we have found the required code unit, save the point where we
-          found it, so that we don't search again next time round the loop if
-          the start hasn't passed this code unit yet. */
+          found it, so that we don't search again next time round the bumpalong
+          loop if the start hasn't yet passed this code unit. */
 
           req_cu_ptr = p;
           }
@@ -6987,14 +6655,17 @@
   /* OK, we can now run the match. If "hitend" is set afterwards, remember the
   first starting point for which a partial match was found. */
 
-  mb->start_match_ptr = start_match;
+  cb.start_match = (PCRE2_SIZE)(start_match - subject);
+  cb.callout_flags |= PCRE2_CALLOUT_STARTMATCH;
+
   mb->start_used_ptr = start_match;
   mb->last_used_ptr = start_match;
   mb->match_call_count = 0;
-  mb->match_function_type = 0;
   mb->end_offset_top = 0;
   mb->skip_arg_count = 0;
-  rc = match(start_match, mb->start_code, start_match, 2, mb, NULL, 0);
+
+  rc = match(start_match, mb->start_code, match_data->ovector,
+    match_data->oveccount, re->top_bracket, frame_size, mb);
 
   if (mb->hitend && start_partial == NULL)
     {
@@ -7020,9 +6691,9 @@
     greater than the match we have just done, treat it as NOMATCH. */
 
     case MATCH_SKIP:
-    if (mb->start_match_ptr > start_match)
+    if (mb->verb_skip_ptr > start_match)
       {
-      new_start_match = mb->start_match_ptr;
+      new_start_match = mb->verb_skip_ptr;
       break;
       }
     /* Fall through */
@@ -7037,7 +6708,7 @@
     new_start_match = start_match + 1;
 #ifdef SUPPORT_UNICODE
     if (utf)
-      ACROSSCHAR(new_start_match < end_subject, *new_start_match,
+      ACROSSCHAR(new_start_match < end_subject, new_start_match,
         new_start_match++);
 #endif
     break;
@@ -7096,11 +6767,11 @@
 
 /* ==========================================================================*/
 
-/* When we reach here, one of the stopping conditions is true:
+/* When we reach here, one of the following stopping conditions is true:
 
 (1) The match succeeded, either completely, or partially;
 
-(2) The pattern is anchored or the match was failed by (*COMMIT);
+(2) The pattern is anchored or the match was failed after (*COMMIT);
 
 (3) We are past the end of the subject or the bumpalong limit;
 
@@ -7114,18 +6785,10 @@
 
 ENDLOOP:
 
-#ifdef HEAP_MATCH_RECURSE
-release_match_heapframes(&frame_zero, mb);
-#endif
+/* Release an enlarged frame vector that is on the heap. */
 
-/* Release any frames that were saved from recursions. */
-
-while (mb->ovecsave_chain != NULL)
-  {
-  ovecsave_frame *this = mb->ovecsave_chain;
-  mb->ovecsave_chain = this->next;
-  mb->memctl.free(this, mb->memctl.memory_data);
-  }
+if (mb->match_frames != mb->stack_frames)
+  mb->memctl.free(mb->match_frames, mb->memctl.memory_data);
 
 /* Fill in fields that are always returned in the match data. */
 
@@ -7134,68 +6797,14 @@
 match_data->mark = mb->mark;
 match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER;
 
-/* Handle a fully successful match. */
+/* Handle a fully successful match. Set the return code to the number of
+captured strings, or 0 if there were too many to fit into the ovector, and then
+set the remaining returned values before returning. */
 
-if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
+if (rc == MATCH_MATCH)
   {
-  uint32_t arg_offset_max = 2 * match_data->oveccount;
-
-  /* When the offset vector is big enough to deal with any backreferences,
-  captured substring offsets will already be set up. In the case where we had
-  to get some local memory to hold offsets for backreference processing, copy
-  those that we can. In this case there need not be overflow if certain parts
-  of the pattern were not used, even though there are more capturing
-  parentheses than vector slots. */
-
-  if (using_temporary_offsets)
-    {
-    if (arg_offset_max >= 4)
-      {
-      memcpy(match_data->ovector + 2, mb->ovector + 2,
-        (arg_offset_max - 2) * sizeof(PCRE2_SIZE));
-      }
-    if (mb->end_offset_top > arg_offset_max) mb->capture_last |= OVFLBIT;
-    mb->memctl.free(mb->ovector, mb->memctl.memory_data);
-    }
-
-  /* Set the return code to the number of captured strings, or 0 if there were
-  too many to fit into the ovector. */
-
-  match_data->rc = ((mb->capture_last & OVFLBIT) != 0)?
-    0 : mb->end_offset_top/2;
-
-  /* If there is space in the offset vector, set any pairs that follow the
-  highest-numbered captured string but are less than the number of capturing
-  groups in the pattern (and are within the ovector) to PCRE2_UNSET. It is
-  documented that this happens. In earlier versions, the whole set of potential
-  capturing offsets was initialized each time round the loop, but this is
-  handled differently now. "Gaps" are set to PCRE2_UNSET dynamically instead
-  (this fixed a bug). Thus, it is only those at the end that need setting here.
-  We can't just mark them all unset at the start of the whole thing because
-  they may get set in one branch that is not the final matching branch. */
-
-  if (mb->end_offset_top/2 <= re->top_bracket)
-    {
-    register PCRE2_SIZE *iptr, *iend;
-    int resetcount = re->top_bracket + 1;
-    if (resetcount > match_data->oveccount) resetcount = match_data->oveccount;
-    iptr = match_data->ovector + mb->end_offset_top;
-    iend = match_data->ovector + 2 * resetcount;
-    while (iptr < iend) *iptr++ = PCRE2_UNSET;
-    }
-
-  /* If there is space, set up the whole thing as substring 0. The value of
-  mb->start_match_ptr might be modified if \K was encountered on the success
-  matching path. */
-
-  if (match_data->oveccount < 1) rc = 0; else
-    {
-    match_data->ovector[0] = mb->start_match_ptr - mb->start_subject;
-    match_data->ovector[1] = mb->end_match_ptr - mb->start_subject;
-    }
-
-  /* Set the remaining returned values */
-
+  match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)?
+    0 : (int)mb->end_offset_top/2 + 1;
   match_data->startchar = start_match - subject;
   match_data->leftchar = mb->start_used_ptr - subject;
   match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?
@@ -7211,18 +6820,14 @@
 
 /* For anything other than nomatch or partial match, just return the code. */
 
-if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL)
-  match_data->rc = rc;
+if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) match_data->rc = rc;
 
-/* Else handle a partial match. */
+/* Handle a partial match. */
 
 else if (match_partial != NULL)
   {
-  if (match_data->oveccount > 0)
-    {
-    match_data->ovector[0] = match_partial - subject;
-    match_data->ovector[1] = end_subject - subject;
-    }
+  match_data->ovector[0] = match_partial - subject;
+  match_data->ovector[1] = end_subject - subject;
   match_data->startchar = match_partial - subject;
   match_data->leftchar = start_partial - subject;
   match_data->rightchar = end_subject - subject;
@@ -7233,10 +6838,6 @@
 
 else match_data->rc = PCRE2_ERROR_NOMATCH;
 
-/* Free any temporary offsets. */
-
-if (using_temporary_offsets)
-  mb->memctl.free(mb->ovector, mb->memctl.memory_data);
 return match_data->rc;
 }
 
diff --git a/dist2/src/pcre2_match_data.c b/dist2/src/pcre2_match_data.c
index 85ac998..b297f32 100644
--- a/dist2/src/pcre2_match_data.c
+++ b/dist2/src/pcre2_match_data.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
 *  Create a match data block given ovector size  *
 *************************************************/
 
-/* A minimum of 1 is imposed on the number of ovector triplets. */
+/* A minimum of 1 is imposed on the number of ovector pairs. */
 
 PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION
 pcre2_match_data_create(uint32_t oveccount, pcre2_general_context *gcontext)
@@ -59,7 +59,7 @@
 pcre2_match_data *yield;
 if (oveccount < 1) oveccount = 1;
 yield = PRIV(memctl_malloc)(
-  sizeof(pcre2_match_data) + 3*oveccount*sizeof(PCRE2_SIZE),
+  offsetof(pcre2_match_data, ovector) + 2*oveccount*sizeof(PCRE2_SIZE),
   (pcre2_memctl *)gcontext);
 if (yield == NULL) return NULL;
 yield->oveccount = oveccount;
diff --git a/dist2/src/pcre2_ord2utf.c b/dist2/src/pcre2_ord2utf.c
index 75252b7..1403730 100644
--- a/dist2/src/pcre2_ord2utf.c
+++ b/dist2/src/pcre2_ord2utf.c
@@ -83,7 +83,7 @@
 /* Convert to UTF-8 */
 
 #if PCRE2_CODE_UNIT_WIDTH == 8
-register int i, j;
+int i, j;
 for (i = 0; i < PRIV(utf8_table1_size); i++)
   if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
 buffer += i;
diff --git a/dist2/src/pcre2_pattern_info.c b/dist2/src/pcre2_pattern_info.c
index 5b32a90..906e919 100644
--- a/dist2/src/pcre2_pattern_info.c
+++ b/dist2/src/pcre2_pattern_info.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -75,10 +75,13 @@
     case PCRE2_INFO_BACKREFMAX:
     case PCRE2_INFO_BSR:
     case PCRE2_INFO_CAPTURECOUNT:
+    case PCRE2_INFO_DEPTHLIMIT:
+    case PCRE2_INFO_EXTRAOPTIONS:
     case PCRE2_INFO_FIRSTCODETYPE:
     case PCRE2_INFO_FIRSTCODEUNIT:
     case PCRE2_INFO_HASBACKSLASHC:
     case PCRE2_INFO_HASCRORLF:
+    case PCRE2_INFO_HEAPLIMIT:
     case PCRE2_INFO_JCHANGED:
     case PCRE2_INFO_LASTCODETYPE:
     case PCRE2_INFO_LASTCODEUNIT:
@@ -89,7 +92,6 @@
     case PCRE2_INFO_NAMEENTRYSIZE:
     case PCRE2_INFO_NAMECOUNT:
     case PCRE2_INFO_NEWLINE:
-    case PCRE2_INFO_RECURSIONLIMIT:
     return sizeof(uint32_t);
 
     case PCRE2_INFO_FIRSTBITMAP:
@@ -97,6 +99,7 @@
 
     case PCRE2_INFO_JITSIZE:
     case PCRE2_INFO_SIZE:
+    case PCRE2_INFO_FRAMESIZE:
     return sizeof(size_t);
 
     case PCRE2_INFO_NAMETABLE:
@@ -137,6 +140,15 @@
   *((uint32_t *)where) = re->top_bracket;
   break;
 
+  case PCRE2_INFO_DEPTHLIMIT:
+  *((uint32_t *)where) = re->limit_depth;
+  if (re->limit_depth == UINT32_MAX) return PCRE2_ERROR_UNSET;
+  break;
+
+  case PCRE2_INFO_EXTRAOPTIONS:
+  *((uint32_t *)where) = re->extra_options;
+  break;
+
   case PCRE2_INFO_FIRSTCODETYPE:
   *((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 :
                          ((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0;
@@ -152,6 +164,11 @@
     &(re->start_bitmap[0]) : NULL;
   break;
 
+  case PCRE2_INFO_FRAMESIZE:
+  *((size_t *)where) = offsetof(heapframe, ovector) +
+    re->top_bracket * 2 * sizeof(PCRE2_SIZE);
+  break;
+
   case PCRE2_INFO_HASBACKSLASHC:
   *((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0;
   break;
@@ -160,6 +177,11 @@
   *((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0;
   break;
 
+  case PCRE2_INFO_HEAPLIMIT:
+  *((uint32_t *)where) = re->limit_heap;
+  if (re->limit_heap == UINT32_MAX) return PCRE2_ERROR_UNSET;
+  break;
+
   case PCRE2_INFO_JCHANGED:
   *((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0;
   break;
@@ -215,11 +237,6 @@
   *((uint32_t *)where) = re->newline_convention;
   break;
 
-  case PCRE2_INFO_RECURSIONLIMIT:
-  *((uint32_t *)where) = re->limit_recursion;
-  if (re->limit_recursion == UINT32_MAX) return PCRE2_ERROR_UNSET;
-  break;
-
   case PCRE2_INFO_SIZE:
   *((size_t *)where) = re->blocksize;
   break;
@@ -255,11 +272,15 @@
 pcre2_callout_enumerate_block cb;
 PCRE2_SPTR cc;
 #ifdef SUPPORT_UNICODE
-BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
+BOOL utf;
 #endif
 
 if (re == NULL) return PCRE2_ERROR_NULL;
 
+#ifdef SUPPORT_UNICODE
+utf = (re->overall_options & PCRE2_UTF) != 0;
+#endif
+
 /* Check that the first field in the block is the magic number. If it is not,
 return with PCRE2_ERROR_BADMAGIC. */
 
diff --git a/dist2/src/pcre2_printint.c b/dist2/src/pcre2_printint.c
index 2d30926..e4dd53f 100644
--- a/dist2/src/pcre2_printint.c
+++ b/dist2/src/pcre2_printint.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -206,7 +206,7 @@
 {
 while (*ptr != '\0')
   {
-  register uint32_t c = *ptr++;
+  uint32_t c = *ptr++;
   if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
   }
 }
@@ -216,7 +216,7 @@
 {
 for (; len > 0; len--)
   {
-  register uint32_t c = *ptr++;
+  uint32_t c = *ptr++;
   if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
   }
 }
@@ -340,7 +340,7 @@
       case OP_TABLE_LENGTH +
         ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
         (sizeof(OP_lengths) == OP_TABLE_LENGTH)):
-      break;
+      return;
 /* ========================================================================== */
 
     case OP_END:
@@ -393,7 +393,6 @@
     case OP_ASSERTBACK:
     case OP_ASSERTBACK_NOT:
     case OP_ONCE:
-    case OP_ONCE_NC:
     case OP_COND:
     case OP_SCOND:
     case OP_REVERSE:
diff --git a/dist2/src/pcre2_serialize.c b/dist2/src/pcre2_serialize.c
index 0af26d8..d2cc603 100644
--- a/dist2/src/pcre2_serialize.c
+++ b/dist2/src/pcre2_serialize.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -214,7 +214,10 @@
   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); 
     return PCRE2_ERROR_BADSERIALIZEDDATA;
+    } 
 
   /* At the moment only one table is supported. */
 
diff --git a/dist2/src/pcre2_study.c b/dist2/src/pcre2_study.c
index db08266..b926867 100644
--- a/dist2/src/pcre2_study.c
+++ b/dist2/src/pcre2_study.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -46,9 +46,11 @@
 #include "config.h"
 #endif
 
-
 #include "pcre2_internal.h"
 
+/* The maximum remembered capturing brackets minimum. */
+
+#define MAX_CACHE_BACKREF 128
 
 /* Set a bit in the starting code unit bit map. */
 
@@ -71,6 +73,12 @@
 pathological), so we give up when we reach that amount. This also means that
 integer overflow for really crazy patterns cannot happen.
 
+Backreference minimum lengths are cached to speed up multiple references. This
+function is called only when the highest back reference in the pattern is less
+than or equal to MAX_CACHE_BACKREF, which is one less than the size of the
+caching vector. The zeroth element contains the number of the highest set
+value.
+
 Arguments:
   re              compiled pattern block
   code            pointer to start of group (the bracket)
@@ -78,6 +86,7 @@
   utf             UTF flag
   recurses        chain of recurse_check to catch mutual recursion
   countptr        pointer to call count (to catch over complexity)
+  backref_cache   vector for caching back references.
 
 Returns:   the minimum length
            -1 \C in UTF-8 mode
@@ -90,7 +99,8 @@
 
 static int
 find_minlength(const pcre2_real_code *re, PCRE2_SPTR code,
-  PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr)
+  PCRE2_SPTR startcode, BOOL utf, recurse_check *recurses, int *countptr,
+  int *backref_cache)
 {
 int length = -1;
 int prev_cap_recno = -1;
@@ -101,8 +111,8 @@
 BOOL had_recurse = FALSE;
 BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0;
 recurse_check this_recurse;
-register int branchlength = 0;
-register PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE;
+int branchlength = 0;
+PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE;
 
 /* If this is a "could be empty" group, its minimum length is 0. */
 
@@ -124,7 +134,7 @@
   {
   int d, min, recno;
   PCRE2_UCHAR *cs, *ce;
-  register PCRE2_UCHAR op = *cc;
+  PCRE2_UCHAR op = *cc;
 
   if (branchlength >= UINT16_MAX) return UINT16_MAX;
 
@@ -146,12 +156,12 @@
       }
     goto PROCESS_NON_CAPTURE;
 
-    /* There's a special case of OP_ONCE, when it is wrapped round an
+    case OP_BRA:
+    /* There's a special case of OP_BRA, when it is wrapped round a repeated
     OP_RECURSE. We'd like to process the latter at this level so that
     remembering the value works for repeated cases. So we do nothing, but
     set a fudge value to skip over the OP_KET after the recurse. */
 
-    case OP_ONCE:
     if (cc[1+LINK_SIZE] == OP_RECURSE && cc[2*(1+LINK_SIZE)] == OP_KET)
       {
       once_fudge = 1 + LINK_SIZE;
@@ -160,13 +170,13 @@
       }
     /* Fall through */
 
-    case OP_ONCE_NC:
-    case OP_BRA:
+    case OP_ONCE:
     case OP_SBRA:
     case OP_BRAPOS:
     case OP_SBRAPOS:
     PROCESS_NON_CAPTURE:
-    d = find_minlength(re, cc, startcode, utf, recurses, countptr);
+    d = find_minlength(re, cc, startcode, utf, recurses, countptr,
+      backref_cache);
     if (d < 0) return d;
     branchlength += d;
     do cc += GET(cc, 1); while (*cc == OP_ALT);
@@ -182,11 +192,12 @@
     case OP_SCBRA:
     case OP_CBRAPOS:
     case OP_SCBRAPOS:
-    recno = dupcapused? prev_cap_recno - 1 : (int)GET2(cc, 1+LINK_SIZE);
-    if (recno != prev_cap_recno)
+    recno = (int)GET2(cc, 1+LINK_SIZE);
+    if (dupcapused || recno != prev_cap_recno)
       {
       prev_cap_recno = recno;
-      prev_cap_d = find_minlength(re, cc, startcode, utf, recurses, countptr);
+      prev_cap_d = find_minlength(re, cc, startcode, utf, recurses, countptr,
+        backref_cache);
       if (prev_cap_d < 0) return prev_cap_d;
       }
     branchlength += prev_cap_d;
@@ -456,38 +467,52 @@
 
       d = INT_MAX;
 
-      /* Scan all groups with the same name */
+      /* Scan all groups with the same name; find the shortest. */
 
       while (count-- > 0)
         {
-        ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0));
-        if (cs == NULL) return -2;
-        do ce += GET(ce, 1); while (*ce == OP_ALT);
-        if (cc > cs && cc < ce)    /* Simple recursion */
-          {
-          d = 0;
-          had_recurse = TRUE;
-          break;
-          }
+        int dd, i;
+        recno = GET2(slot, 0);
+
+        if (recno <= backref_cache[0] && backref_cache[recno] >= 0)
+          dd = backref_cache[recno];
         else
           {
-          recurse_check *r = recurses;
-          for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
-          if (r != NULL)           /* Mutual recursion */
+          ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
+          if (cs == NULL) return -2;
+          do ce += GET(ce, 1); while (*ce == OP_ALT);
+          if (cc > cs && cc < ce)    /* Simple recursion */
             {
-            d = 0;
+            dd = 0;
             had_recurse = TRUE;
-            break;
             }
           else
             {
-            int dd;
-            this_recurse.prev = recurses;
-            this_recurse.group = cs;
-            dd = find_minlength(re, cs, startcode, utf, &this_recurse, countptr);
-            if (dd < d) d = dd;
+            recurse_check *r = recurses;
+            for (r = recurses; r != NULL; r = r->prev)
+              if (r->group == cs) break;
+            if (r != NULL)           /* Mutual recursion */
+              {
+              dd = 0;
+              had_recurse = TRUE;
+              }
+            else
+              {
+              this_recurse.prev = recurses;
+              this_recurse.group = cs;
+              dd = find_minlength(re, cs, startcode, utf, &this_recurse,
+                countptr, backref_cache);
+              if (dd < 0) return dd;
+              }
             }
+
+          backref_cache[recno] = dd;
+          for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;
+          backref_cache[0] = recno;
           }
+
+        if (dd < d) d = dd;
+        if (d <= 0) break;    /* No point looking at any more */
         slot += re->name_entry_size;
         }
       }
@@ -501,34 +526,48 @@
     case OP_REF:
     case OP_REFI:
     if (dupcapused) return -1;
-    if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
+    recno = GET2(cc, 1);
+    if (recno <= backref_cache[0] && backref_cache[recno] >= 0)
+      d = backref_cache[recno];
+    else
       {
-      ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1));
-      if (cs == NULL) return -2;
-      do ce += GET(ce, 1); while (*ce == OP_ALT);
-      if (cc > cs && cc < ce)    /* Simple recursion */
+      int i;
+      if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
         {
-        d = 0;
-        had_recurse = TRUE;
-        }
-      else
-        {
-        recurse_check *r = recurses;
-        for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
-        if (r != NULL)           /* Mutual recursion */
+        ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
+        if (cs == NULL) return -2;
+        do ce += GET(ce, 1); while (*ce == OP_ALT);
+        if (cc > cs && cc < ce)    /* Simple recursion */
           {
           d = 0;
           had_recurse = TRUE;
           }
         else
           {
-          this_recurse.prev = recurses;
-          this_recurse.group = cs;
-          d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr);
+          recurse_check *r = recurses;
+          for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
+          if (r != NULL)           /* Mutual recursion */
+            {
+            d = 0;
+            had_recurse = TRUE;
+            }
+          else
+            {
+            this_recurse.prev = recurses;
+            this_recurse.group = cs;
+            d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr,
+              backref_cache);
+            if (d < 0) return d;
+            }
           }
         }
+      else d = 0;
+
+      backref_cache[recno] = d;
+      for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;
+      backref_cache[0] = recno;
       }
-    else d = 0;
+
     cc += 1 + IMM2_SIZE;
 
     /* Handle repeated back references */
@@ -601,7 +640,7 @@
           this_recurse.prev = recurses;
           this_recurse.group = cs;
           prev_recurse_d = find_minlength(re, cs, startcode, utf, &this_recurse,
-            countptr);
+            countptr, backref_cache);
           if (prev_recurse_d < 0) return prev_recurse_d;
           prev_recurse_recno = recno;
           branchlength += prev_recurse_d;
@@ -747,6 +786,7 @@
 
 if (caseless)
   {
+#ifdef SUPPORT_UNICODE
   if (utf)
     {
 #if PCRE2_CODE_UNIT_WIDTH == 8
@@ -759,10 +799,12 @@
     if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
 #endif
     }
+  else
+#endif  /* SUPPORT_UNICODE */
 
   /* Not UTF */
 
-  else if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);
+  if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);
   }
 
 return p;
@@ -792,7 +834,7 @@
 static void
 set_type_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)
 {
-register uint32_t c;
+uint32_t c;
 for (c = 0; c < table_limit; c++)
   re->start_bitmap[c] |= re->tables[c+cbits_offset+cbit_type];
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
@@ -833,7 +875,7 @@
 static void
 set_nottype_bits(pcre2_real_code *re, int cbit_type, unsigned int table_limit)
 {
-register uint32_t c;
+uint32_t c;
 for (c = 0; c < table_limit; c++)
   re->start_bitmap[c] |= ~(re->tables[c+cbits_offset+cbit_type]);
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
@@ -873,7 +915,7 @@
 static int
 set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf)
 {
-register uint32_t c;
+uint32_t c;
 int yield = SSB_DONE;
 
 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
@@ -911,7 +953,6 @@
       case OP_ALLANY:
       case OP_ANY:
       case OP_ANYBYTE:
-      case OP_CIRC:
       case OP_CIRCM:
       case OP_CLOSE:
       case OP_COMMIT:
@@ -979,6 +1020,13 @@
       case OP_THEN_ARG:
       return SSB_FAIL;
 
+      /* OP_CIRC happens only at the start of an anchored branch (multiline ^
+      uses OP_CIRCM). Skip over it. */
+
+      case OP_CIRC:
+      tcode += PRIV(OP_lengths)[OP_CIRC];
+      break;
+
       /* A "real" property test implies no starting bits, but the fake property
       PT_CLIST identifies a list of characters. These lists are short, as they
       are used for characters with more than one "other case", so there is no
@@ -1025,7 +1073,6 @@
       case OP_CBRAPOS:
       case OP_SCBRAPOS:
       case OP_ONCE:
-      case OP_ONCE_NC:
       case OP_ASSERT:
       rc = set_start_bits(re, tcode, utf);
       if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
@@ -1407,6 +1454,10 @@
       classmap = ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0)? NULL :
         (uint8_t *)(tcode + 1 + LINK_SIZE + 1);
 #endif
+      /* It seems that the fall through comment must be outside the #ifdef if
+      it is to avoid the gcc compiler warning. */
+
+      /* Fall through */
 
       /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are
       in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter
@@ -1534,24 +1585,31 @@
 code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) +
   re->name_entry_size * re->name_count;
 
-/* For an anchored pattern, or an unanchored 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 code units. */
+/* 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
+code units. */
 
-if ((re->overall_options & PCRE2_ANCHORED) == 0 &&
-    (re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
+if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
   {
   int rc = set_start_bits(re, code, utf);
   if (rc == SSB_UNKNOWN) return 1;
   if (rc == SSB_DONE) re->flags |= PCRE2_FIRSTMAPSET;
   }
 
-/* Find the minimum length of subject string. If it can match an empty string,
-the minimum length is already known. */
+/* Find the minimum length of subject string. If the pattern can match an empty
+string, the minimum length is already known. If there are more back references
+than the size of the vector we are going to cache them in, do nothing. A
+pattern that complicated will probably take a long time to analyze and may in
+any case turn out to be too complicated. Note that back reference minima are
+held as 16-bit numbers. */
 
-if ((re->flags & PCRE2_MATCH_EMPTY) == 0)
+if ((re->flags & PCRE2_MATCH_EMPTY) == 0 &&
+     re->top_backref <= MAX_CACHE_BACKREF)
   {
-  switch(min = find_minlength(re, code, code, utf, NULL, &count))
+  int backref_cache[MAX_CACHE_BACKREF+1];
+  backref_cache[0] = 0;    /* Highest one that is set */
+  min = find_minlength(re, code, code, utf, NULL, &count, backref_cache);
+  switch(min)
     {
     case -1:  /* \C in UTF mode or (*ACCEPT) or over-complex regex */
     break;    /* Leave minlength unchanged (will be zero) */
diff --git a/dist2/src/pcre2_substitute.c b/dist2/src/pcre2_substitute.c
index 0bf781e..8da951f 100644
--- a/dist2/src/pcre2_substitute.c
+++ b/dist2/src/pcre2_substitute.c
@@ -114,7 +114,7 @@
   else if (*ptr == CHAR_BACKSLASH)
     {
     int erc;
-    int errorcode = 0;
+    int errorcode;
     uint32_t ch;
 
     if (ptr < ptrend - 1) switch (ptr[1])
@@ -127,8 +127,10 @@
       continue;
       }
 
+    ptr += 1;  /* Must point after \ */
     erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode,
       code->overall_options, FALSE, NULL);
+    ptr -= 1;  /* Back to last code unit of escape */
     if (errorcode != 0)
       {
       rc = errorcode;
@@ -287,6 +289,12 @@
 
 /* Copy up to the start offset */
 
+if (start_offset > length)
+  {
+  match_data->leftchar = 0;
+  rc = PCRE2_ERROR_BADOFFSET;
+  goto EXIT;
+  }
 CHECKMEMCPY(subject, start_offset);
 
 /* Loop for global substituting. */
@@ -698,7 +706,7 @@
     else if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 &&
               *ptr == CHAR_BACKSLASH)
       {
-      int errorcode = 0;
+      int errorcode;
 
       if (ptr < repend - 1) switch (ptr[1])
         {
@@ -728,10 +736,10 @@
         break;
         }
 
+      ptr++;  /* Point after \ */
       rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode,
         code->overall_options, FALSE, NULL);
       if (errorcode != 0) goto BADESCAPE;
-      ptr++;
 
       switch(rc)
         {
diff --git a/dist2/src/pcre2_substring.c b/dist2/src/pcre2_substring.c
index f6d7c39..ddf5774 100644
--- a/dist2/src/pcre2_substring.c
+++ b/dist2/src/pcre2_substring.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2018 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -414,7 +414,12 @@
 for (i = 0; i < count2; i += 2)
   {
   size = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0;
-  memcpy(sp, match_data->subject + ovector[i], CU2BYTES(size));
+
+  /* Size == 0 includes the case when the capture is unset. Avoid adding
+  PCRE2_UNSET to match_data->subject because it overflows, even though with
+  zero size calling memcpy() is harmless. */
+
+  if (size != 0) memcpy(sp, match_data->subject + ovector[i], CU2BYTES(size));
   *listp++ = sp;
   if (lensp != NULL) *lensp++ = size;
   sp += size;
diff --git a/dist2/src/pcre2_tables.c b/dist2/src/pcre2_tables.c
index b945ed7..9f8dc29 100644
--- a/dist2/src/pcre2_tables.c
+++ b/dist2/src/pcre2_tables.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@
 */
 
 /* This module contains some fixed tables that are used by more than one of the
-PCRE code modules. The tables are also #included by the pcre2test program,
+PCRE2 code modules. The tables are also #included by the pcre2test program,
 which uses macros to change their names from _pcre2_xxx to xxxx, thereby
 avoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is
 defined. */
@@ -148,7 +148,7 @@
 
 1. Break at the start and end of text (pretty obviously).
 
-2. Do not break between a CR and LF; otherwise, break before and   after
+2. Do not break between a CR and LF; otherwise, break before and after
    controls.
 
 3. Do not break Hangul syllable sequences, the rules for which are:
@@ -157,44 +157,62 @@
     LV or V may be followed by V or T
     LVT or T may be followed by T
 
-4. Do not break before extending characters.
+4. Do not break before extending characters or zero-width-joiner (ZWJ).
 
-The next two rules are only for extended grapheme clusters (but that's what we
+The following rules are only for extended grapheme clusters (but that's what we
 are implementing).
 
 5. Do not break before SpacingMarks.
 
 6. Do not break after Prepend characters.
 
-7. Otherwise, break everywhere.
+7. Do not break within emoji modifier sequences (E_Base or E_Base_GAZ followed
+   by E_Modifier). Extend characters are allowed before the modifier; this
+   cannot be represented in this table, the code has to deal with it.
+
+8. Do not break within emoji zwj sequences (ZWJ followed by Glue_After_Zwj   or
+   E_Base_GAZ).
+
+9. Do not break within emoji flag sequences. That is, do not break between
+   regional indicator (RI) symbols if there are an odd number of RI characters
+   before the break point. This table encodes "join RI characters"; the code
+   has to deal with checking for previous adjoining RIs.
+
+10. Otherwise, break everywhere.
 */
 
+#define ESZ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbZWJ)
+
 const uint32_t PRIV(ucp_gbtable)[] = {
    (1<<ucp_gbLF),                                           /*  0 CR */
    0,                                                       /*  1 LF */
    0,                                                       /*  2 Control */
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark),                /*  3 Extend */
-   (1<<ucp_gbExtend)|(1<<ucp_gbPrepend)|                    /*  4 Prepend */
-     (1<<ucp_gbSpacingMark)|(1<<ucp_gbL)|
-     (1<<ucp_gbV)|(1<<ucp_gbT)|(1<<ucp_gbLV)|
-     (1<<ucp_gbLVT)|(1<<ucp_gbOther),
-
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark),                /*  5 SpacingMark */
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbL)|   /*  6 L */
-     (1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbLV)|(1<<ucp_gbLVT),
-
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)|   /*  7 V */
-     (1<<ucp_gbT),
-
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT),   /*  8 T */
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)|   /*  9 LV */
-     (1<<ucp_gbT),
-
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT),   /* 10 LVT */
+   ESZ,                                                     /*  3 Extend */
+   ESZ|(1<<ucp_gbPrepend)|                                  /*  4 Prepend */
+       (1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbT)|
+       (1<<ucp_gbLV)|(1<<ucp_gbLVT)|(1<<ucp_gbOther)|
+       (1<<ucp_gbRegionalIndicator)|
+       (1<<ucp_gbE_Base)|(1<<ucp_gbE_Modifier)|
+       (1<<ucp_gbE_Base_GAZ)|
+       (1<<ucp_gbZWJ)|(1<<ucp_gbGlue_After_Zwj),
+   ESZ,                                                     /*  5 SpacingMark */
+   ESZ|(1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbLV)|             /*  6 L */
+       (1<<ucp_gbLVT),
+   ESZ|(1<<ucp_gbV)|(1<<ucp_gbT),                           /*  7 V */
+   ESZ|(1<<ucp_gbT),                                        /*  8 T */
+   ESZ|(1<<ucp_gbV)|(1<<ucp_gbT),                           /*  9 LV */
+   ESZ|(1<<ucp_gbT),                                        /* 10 LVT */
    (1<<ucp_gbRegionalIndicator),                            /* 11 RegionalIndicator */
-   (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)                 /* 12 Other */
+   ESZ,                                                     /* 12 Other */
+   ESZ|(1<<ucp_gbE_Modifier),                               /* 13 E_Base */
+   ESZ,                                                     /* 14 E_Modifier */
+   ESZ|(1<<ucp_gbE_Modifier),                               /* 15 E_Base_GAZ */
+   ESZ|(1<<ucp_gbGlue_After_Zwj)|(1<<ucp_gbE_Base_GAZ),     /* 16 ZWJ */
+   ESZ                                                      /* 12 Glue_After_Zwj */
 };
 
+#undef ESZ
+
 #ifdef SUPPORT_JIT
 /* This table reverses PRIV(ucp_gentype). We can save the cost
 of a memory load. */
@@ -227,6 +245,7 @@
 the regular expression pattern, we must use STR_ macros instead of literal
 strings to make sure that UTF-8 support works on EBCDIC platforms. */
 
+#define STRING_Adlam0 STR_A STR_d STR_l STR_a STR_m "\0"
 #define STRING_Ahom0 STR_A STR_h STR_o STR_m "\0"
 #define STRING_Anatolian_Hieroglyphs0 STR_A STR_n STR_a STR_t STR_o STR_l STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
 #define STRING_Any0 STR_A STR_n STR_y "\0"
@@ -238,6 +257,7 @@
 #define STRING_Bassa_Vah0 STR_B STR_a STR_s STR_s STR_a STR_UNDERSCORE STR_V STR_a STR_h "\0"
 #define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
 #define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
+#define STRING_Bhaiksuki0 STR_B STR_h STR_a STR_i STR_k STR_s STR_u STR_k STR_i "\0"
 #define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
 #define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0"
 #define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
@@ -313,6 +333,8 @@
 #define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
 #define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
 #define STRING_Manichaean0 STR_M STR_a STR_n STR_i STR_c STR_h STR_a STR_e STR_a STR_n "\0"
+#define STRING_Marchen0 STR_M STR_a STR_r STR_c STR_h STR_e STR_n "\0"
+#define STRING_Masaram_Gondi0 STR_M STR_a STR_s STR_a STR_r STR_a STR_m STR_UNDERSCORE STR_G STR_o STR_n STR_d STR_i "\0"
 #define STRING_Mc0 STR_M STR_c "\0"
 #define STRING_Me0 STR_M STR_e "\0"
 #define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
@@ -330,9 +352,11 @@
 #define STRING_Nabataean0 STR_N STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0"
 #define STRING_Nd0 STR_N STR_d "\0"
 #define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
+#define STRING_Newa0 STR_N STR_e STR_w STR_a "\0"
 #define STRING_Nko0 STR_N STR_k STR_o "\0"
 #define STRING_Nl0 STR_N STR_l "\0"
 #define STRING_No0 STR_N STR_o "\0"
+#define STRING_Nushu0 STR_N STR_u STR_s STR_h STR_u "\0"
 #define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
 #define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
 #define STRING_Old_Hungarian0 STR_O STR_l STR_d STR_UNDERSCORE STR_H STR_u STR_n STR_g STR_a STR_r STR_i STR_a STR_n "\0"
@@ -343,6 +367,7 @@
 #define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
 #define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
 #define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
+#define STRING_Osage0 STR_O STR_s STR_a STR_g STR_e "\0"
 #define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
 #define STRING_P0 STR_P "\0"
 #define STRING_Pahawh_Hmong0 STR_P STR_a STR_h STR_a STR_w STR_h STR_UNDERSCORE STR_H STR_m STR_o STR_n STR_g "\0"
@@ -373,6 +398,7 @@
 #define STRING_Sm0 STR_S STR_m "\0"
 #define STRING_So0 STR_S STR_o "\0"
 #define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0"
+#define STRING_Soyombo0 STR_S STR_o STR_y STR_o STR_m STR_b STR_o "\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_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
 #define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
@@ -383,6 +409,7 @@
 #define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
 #define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0"
 #define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
+#define STRING_Tangut0 STR_T STR_a STR_n STR_g STR_u STR_t "\0"
 #define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
 #define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
 #define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
@@ -399,11 +426,13 @@
 #define STRING_Xwd0 STR_X STR_w STR_d "\0"
 #define STRING_Yi0 STR_Y STR_i "\0"
 #define STRING_Z0 STR_Z "\0"
+#define STRING_Zanabazar_Square0 STR_Z STR_a STR_n STR_a STR_b STR_a STR_z STR_a STR_r STR_UNDERSCORE STR_S STR_q STR_u STR_a STR_r STR_e "\0"
 #define STRING_Zl0 STR_Z STR_l "\0"
 #define STRING_Zp0 STR_Z STR_p "\0"
 #define STRING_Zs0 STR_Z STR_s "\0"
 
 const char PRIV(utt_names)[] =
+  STRING_Adlam0
   STRING_Ahom0
   STRING_Anatolian_Hieroglyphs0
   STRING_Any0
@@ -415,6 +444,7 @@
   STRING_Bassa_Vah0
   STRING_Batak0
   STRING_Bengali0
+  STRING_Bhaiksuki0
   STRING_Bopomofo0
   STRING_Brahmi0
   STRING_Braille0
@@ -490,6 +520,8 @@
   STRING_Malayalam0
   STRING_Mandaic0
   STRING_Manichaean0
+  STRING_Marchen0
+  STRING_Masaram_Gondi0
   STRING_Mc0
   STRING_Me0
   STRING_Meetei_Mayek0
@@ -507,9 +539,11 @@
   STRING_Nabataean0
   STRING_Nd0
   STRING_New_Tai_Lue0
+  STRING_Newa0
   STRING_Nko0
   STRING_Nl0
   STRING_No0
+  STRING_Nushu0
   STRING_Ogham0
   STRING_Ol_Chiki0
   STRING_Old_Hungarian0
@@ -520,6 +554,7 @@
   STRING_Old_South_Arabian0
   STRING_Old_Turkic0
   STRING_Oriya0
+  STRING_Osage0
   STRING_Osmanya0
   STRING_P0
   STRING_Pahawh_Hmong0
@@ -550,6 +585,7 @@
   STRING_Sm0
   STRING_So0
   STRING_Sora_Sompeng0
+  STRING_Soyombo0
   STRING_Sundanese0
   STRING_Syloti_Nagri0
   STRING_Syriac0
@@ -560,6 +596,7 @@
   STRING_Tai_Viet0
   STRING_Takri0
   STRING_Tamil0
+  STRING_Tangut0
   STRING_Telugu0
   STRING_Thaana0
   STRING_Thai0
@@ -576,186 +613,197 @@
   STRING_Xwd0
   STRING_Yi0
   STRING_Z0
+  STRING_Zanabazar_Square0
   STRING_Zl0
   STRING_Zp0
   STRING_Zs0;
 
 const ucp_type_table PRIV(utt)[] = {
-  {   0, PT_SC, ucp_Ahom },
-  {   5, PT_SC, ucp_Anatolian_Hieroglyphs },
-  {  27, PT_ANY, 0 },
-  {  31, PT_SC, ucp_Arabic },
-  {  38, PT_SC, ucp_Armenian },
-  {  47, PT_SC, ucp_Avestan },
-  {  55, PT_SC, ucp_Balinese },
-  {  64, PT_SC, ucp_Bamum },
-  {  70, PT_SC, ucp_Bassa_Vah },
-  {  80, PT_SC, ucp_Batak },
-  {  86, PT_SC, ucp_Bengali },
-  {  94, PT_SC, ucp_Bopomofo },
-  { 103, PT_SC, ucp_Brahmi },
-  { 110, PT_SC, ucp_Braille },
-  { 118, PT_SC, ucp_Buginese },
-  { 127, PT_SC, ucp_Buhid },
-  { 133, PT_GC, ucp_C },
-  { 135, PT_SC, ucp_Canadian_Aboriginal },
-  { 155, PT_SC, ucp_Carian },
-  { 162, PT_SC, ucp_Caucasian_Albanian },
-  { 181, PT_PC, ucp_Cc },
-  { 184, PT_PC, ucp_Cf },
-  { 187, PT_SC, ucp_Chakma },
-  { 194, PT_SC, ucp_Cham },
-  { 199, PT_SC, ucp_Cherokee },
-  { 208, PT_PC, ucp_Cn },
-  { 211, PT_PC, ucp_Co },
-  { 214, PT_SC, ucp_Common },
-  { 221, PT_SC, ucp_Coptic },
-  { 228, PT_PC, ucp_Cs },
-  { 231, PT_SC, ucp_Cuneiform },
-  { 241, PT_SC, ucp_Cypriot },
-  { 249, PT_SC, ucp_Cyrillic },
-  { 258, PT_SC, ucp_Deseret },
-  { 266, PT_SC, ucp_Devanagari },
-  { 277, PT_SC, ucp_Duployan },
-  { 286, PT_SC, ucp_Egyptian_Hieroglyphs },
-  { 307, PT_SC, ucp_Elbasan },
-  { 315, PT_SC, ucp_Ethiopic },
-  { 324, PT_SC, ucp_Georgian },
-  { 333, PT_SC, ucp_Glagolitic },
-  { 344, PT_SC, ucp_Gothic },
-  { 351, PT_SC, ucp_Grantha },
-  { 359, PT_SC, ucp_Greek },
-  { 365, PT_SC, ucp_Gujarati },
-  { 374, PT_SC, ucp_Gurmukhi },
-  { 383, PT_SC, ucp_Han },
-  { 387, PT_SC, ucp_Hangul },
-  { 394, PT_SC, ucp_Hanunoo },
-  { 402, PT_SC, ucp_Hatran },
-  { 409, PT_SC, ucp_Hebrew },
-  { 416, PT_SC, ucp_Hiragana },
-  { 425, PT_SC, ucp_Imperial_Aramaic },
-  { 442, PT_SC, ucp_Inherited },
-  { 452, PT_SC, ucp_Inscriptional_Pahlavi },
-  { 474, PT_SC, ucp_Inscriptional_Parthian },
-  { 497, PT_SC, ucp_Javanese },
-  { 506, PT_SC, ucp_Kaithi },
-  { 513, PT_SC, ucp_Kannada },
-  { 521, PT_SC, ucp_Katakana },
-  { 530, PT_SC, ucp_Kayah_Li },
-  { 539, PT_SC, ucp_Kharoshthi },
-  { 550, PT_SC, ucp_Khmer },
-  { 556, PT_SC, ucp_Khojki },
-  { 563, PT_SC, ucp_Khudawadi },
-  { 573, PT_GC, ucp_L },
-  { 575, PT_LAMP, 0 },
-  { 578, PT_SC, ucp_Lao },
-  { 582, PT_SC, ucp_Latin },
-  { 588, PT_SC, ucp_Lepcha },
-  { 595, PT_SC, ucp_Limbu },
-  { 601, PT_SC, ucp_Linear_A },
-  { 610, PT_SC, ucp_Linear_B },
-  { 619, PT_SC, ucp_Lisu },
-  { 624, PT_PC, ucp_Ll },
-  { 627, PT_PC, ucp_Lm },
-  { 630, PT_PC, ucp_Lo },
-  { 633, PT_PC, ucp_Lt },
-  { 636, PT_PC, ucp_Lu },
-  { 639, PT_SC, ucp_Lycian },
-  { 646, PT_SC, ucp_Lydian },
-  { 653, PT_GC, ucp_M },
-  { 655, PT_SC, ucp_Mahajani },
-  { 664, PT_SC, ucp_Malayalam },
-  { 674, PT_SC, ucp_Mandaic },
-  { 682, PT_SC, ucp_Manichaean },
-  { 693, PT_PC, ucp_Mc },
-  { 696, PT_PC, ucp_Me },
-  { 699, PT_SC, ucp_Meetei_Mayek },
-  { 712, PT_SC, ucp_Mende_Kikakui },
-  { 726, PT_SC, ucp_Meroitic_Cursive },
-  { 743, PT_SC, ucp_Meroitic_Hieroglyphs },
-  { 764, PT_SC, ucp_Miao },
-  { 769, PT_PC, ucp_Mn },
-  { 772, PT_SC, ucp_Modi },
-  { 777, PT_SC, ucp_Mongolian },
-  { 787, PT_SC, ucp_Mro },
-  { 791, PT_SC, ucp_Multani },
-  { 799, PT_SC, ucp_Myanmar },
-  { 807, PT_GC, ucp_N },
-  { 809, PT_SC, ucp_Nabataean },
-  { 819, PT_PC, ucp_Nd },
-  { 822, PT_SC, ucp_New_Tai_Lue },
-  { 834, PT_SC, ucp_Nko },
-  { 838, PT_PC, ucp_Nl },
-  { 841, PT_PC, ucp_No },
-  { 844, PT_SC, ucp_Ogham },
-  { 850, PT_SC, ucp_Ol_Chiki },
-  { 859, PT_SC, ucp_Old_Hungarian },
-  { 873, PT_SC, ucp_Old_Italic },
-  { 884, PT_SC, ucp_Old_North_Arabian },
-  { 902, PT_SC, ucp_Old_Permic },
-  { 913, PT_SC, ucp_Old_Persian },
-  { 925, PT_SC, ucp_Old_South_Arabian },
-  { 943, PT_SC, ucp_Old_Turkic },
-  { 954, PT_SC, ucp_Oriya },
-  { 960, PT_SC, ucp_Osmanya },
-  { 968, PT_GC, ucp_P },
-  { 970, PT_SC, ucp_Pahawh_Hmong },
-  { 983, PT_SC, ucp_Palmyrene },
-  { 993, PT_SC, ucp_Pau_Cin_Hau },
-  { 1005, PT_PC, ucp_Pc },
-  { 1008, PT_PC, ucp_Pd },
-  { 1011, PT_PC, ucp_Pe },
-  { 1014, PT_PC, ucp_Pf },
-  { 1017, PT_SC, ucp_Phags_Pa },
-  { 1026, PT_SC, ucp_Phoenician },
-  { 1037, PT_PC, ucp_Pi },
-  { 1040, PT_PC, ucp_Po },
-  { 1043, PT_PC, ucp_Ps },
-  { 1046, PT_SC, ucp_Psalter_Pahlavi },
-  { 1062, PT_SC, ucp_Rejang },
-  { 1069, PT_SC, ucp_Runic },
-  { 1075, PT_GC, ucp_S },
-  { 1077, PT_SC, ucp_Samaritan },
-  { 1087, PT_SC, ucp_Saurashtra },
-  { 1098, PT_PC, ucp_Sc },
-  { 1101, PT_SC, ucp_Sharada },
-  { 1109, PT_SC, ucp_Shavian },
-  { 1117, PT_SC, ucp_Siddham },
-  { 1125, PT_SC, ucp_SignWriting },
-  { 1137, PT_SC, ucp_Sinhala },
-  { 1145, PT_PC, ucp_Sk },
-  { 1148, PT_PC, ucp_Sm },
-  { 1151, PT_PC, ucp_So },
-  { 1154, PT_SC, ucp_Sora_Sompeng },
-  { 1167, PT_SC, ucp_Sundanese },
-  { 1177, PT_SC, ucp_Syloti_Nagri },
-  { 1190, PT_SC, ucp_Syriac },
-  { 1197, PT_SC, ucp_Tagalog },
-  { 1205, PT_SC, ucp_Tagbanwa },
-  { 1214, PT_SC, ucp_Tai_Le },
-  { 1221, PT_SC, ucp_Tai_Tham },
-  { 1230, PT_SC, ucp_Tai_Viet },
-  { 1239, PT_SC, ucp_Takri },
-  { 1245, PT_SC, ucp_Tamil },
-  { 1251, PT_SC, ucp_Telugu },
-  { 1258, PT_SC, ucp_Thaana },
-  { 1265, PT_SC, ucp_Thai },
-  { 1270, PT_SC, ucp_Tibetan },
-  { 1278, PT_SC, ucp_Tifinagh },
-  { 1287, PT_SC, ucp_Tirhuta },
-  { 1295, PT_SC, ucp_Ugaritic },
-  { 1304, PT_SC, ucp_Vai },
-  { 1308, PT_SC, ucp_Warang_Citi },
-  { 1320, PT_ALNUM, 0 },
-  { 1324, PT_PXSPACE, 0 },
-  { 1328, PT_SPACE, 0 },
-  { 1332, PT_UCNC, 0 },
-  { 1336, PT_WORD, 0 },
-  { 1340, PT_SC, ucp_Yi },
-  { 1343, PT_GC, ucp_Z },
-  { 1345, PT_PC, ucp_Zl },
-  { 1348, PT_PC, ucp_Zp },
-  { 1351, PT_PC, ucp_Zs }
+  {   0, PT_SC, ucp_Adlam },
+  {   6, PT_SC, ucp_Ahom },
+  {  11, PT_SC, ucp_Anatolian_Hieroglyphs },
+  {  33, PT_ANY, 0 },
+  {  37, PT_SC, ucp_Arabic },
+  {  44, PT_SC, ucp_Armenian },
+  {  53, PT_SC, ucp_Avestan },
+  {  61, PT_SC, ucp_Balinese },
+  {  70, PT_SC, ucp_Bamum },
+  {  76, PT_SC, ucp_Bassa_Vah },
+  {  86, PT_SC, ucp_Batak },
+  {  92, PT_SC, ucp_Bengali },
+  { 100, PT_SC, ucp_Bhaiksuki },
+  { 110, PT_SC, ucp_Bopomofo },
+  { 119, PT_SC, ucp_Brahmi },
+  { 126, PT_SC, ucp_Braille },
+  { 134, PT_SC, ucp_Buginese },
+  { 143, PT_SC, ucp_Buhid },
+  { 149, PT_GC, ucp_C },
+  { 151, PT_SC, ucp_Canadian_Aboriginal },
+  { 171, PT_SC, ucp_Carian },
+  { 178, PT_SC, ucp_Caucasian_Albanian },
+  { 197, PT_PC, ucp_Cc },
+  { 200, PT_PC, ucp_Cf },
+  { 203, PT_SC, ucp_Chakma },
+  { 210, PT_SC, ucp_Cham },
+  { 215, PT_SC, ucp_Cherokee },
+  { 224, PT_PC, ucp_Cn },
+  { 227, PT_PC, ucp_Co },
+  { 230, PT_SC, ucp_Common },
+  { 237, PT_SC, ucp_Coptic },
+  { 244, PT_PC, ucp_Cs },
+  { 247, PT_SC, ucp_Cuneiform },
+  { 257, PT_SC, ucp_Cypriot },
+  { 265, PT_SC, ucp_Cyrillic },
+  { 274, PT_SC, ucp_Deseret },
+  { 282, PT_SC, ucp_Devanagari },
+  { 293, PT_SC, ucp_Duployan },
+  { 302, PT_SC, ucp_Egyptian_Hieroglyphs },
+  { 323, PT_SC, ucp_Elbasan },
+  { 331, PT_SC, ucp_Ethiopic },
+  { 340, PT_SC, ucp_Georgian },
+  { 349, PT_SC, ucp_Glagolitic },
+  { 360, PT_SC, ucp_Gothic },
+  { 367, PT_SC, ucp_Grantha },
+  { 375, PT_SC, ucp_Greek },
+  { 381, PT_SC, ucp_Gujarati },
+  { 390, PT_SC, ucp_Gurmukhi },
+  { 399, PT_SC, ucp_Han },
+  { 403, PT_SC, ucp_Hangul },
+  { 410, PT_SC, ucp_Hanunoo },
+  { 418, PT_SC, ucp_Hatran },
+  { 425, PT_SC, ucp_Hebrew },
+  { 432, PT_SC, ucp_Hiragana },
+  { 441, PT_SC, ucp_Imperial_Aramaic },
+  { 458, PT_SC, ucp_Inherited },
+  { 468, PT_SC, ucp_Inscriptional_Pahlavi },
+  { 490, PT_SC, ucp_Inscriptional_Parthian },
+  { 513, PT_SC, ucp_Javanese },
+  { 522, PT_SC, ucp_Kaithi },
+  { 529, PT_SC, ucp_Kannada },
+  { 537, PT_SC, ucp_Katakana },
+  { 546, PT_SC, ucp_Kayah_Li },
+  { 555, PT_SC, ucp_Kharoshthi },
+  { 566, PT_SC, ucp_Khmer },
+  { 572, PT_SC, ucp_Khojki },
+  { 579, PT_SC, ucp_Khudawadi },
+  { 589, PT_GC, ucp_L },
+  { 591, PT_LAMP, 0 },
+  { 594, PT_SC, ucp_Lao },
+  { 598, PT_SC, ucp_Latin },
+  { 604, PT_SC, ucp_Lepcha },
+  { 611, PT_SC, ucp_Limbu },
+  { 617, PT_SC, ucp_Linear_A },
+  { 626, PT_SC, ucp_Linear_B },
+  { 635, PT_SC, ucp_Lisu },
+  { 640, PT_PC, ucp_Ll },
+  { 643, PT_PC, ucp_Lm },
+  { 646, PT_PC, ucp_Lo },
+  { 649, PT_PC, ucp_Lt },
+  { 652, PT_PC, ucp_Lu },
+  { 655, PT_SC, ucp_Lycian },
+  { 662, PT_SC, ucp_Lydian },
+  { 669, PT_GC, ucp_M },
+  { 671, PT_SC, ucp_Mahajani },
+  { 680, PT_SC, ucp_Malayalam },
+  { 690, PT_SC, ucp_Mandaic },
+  { 698, PT_SC, ucp_Manichaean },
+  { 709, PT_SC, ucp_Marchen },
+  { 717, PT_SC, ucp_Masaram_Gondi },
+  { 731, PT_PC, ucp_Mc },
+  { 734, PT_PC, ucp_Me },
+  { 737, PT_SC, ucp_Meetei_Mayek },
+  { 750, PT_SC, ucp_Mende_Kikakui },
+  { 764, PT_SC, ucp_Meroitic_Cursive },
+  { 781, PT_SC, ucp_Meroitic_Hieroglyphs },
+  { 802, PT_SC, ucp_Miao },
+  { 807, PT_PC, ucp_Mn },
+  { 810, PT_SC, ucp_Modi },
+  { 815, PT_SC, ucp_Mongolian },
+  { 825, PT_SC, ucp_Mro },
+  { 829, PT_SC, ucp_Multani },
+  { 837, PT_SC, ucp_Myanmar },
+  { 845, PT_GC, ucp_N },
+  { 847, PT_SC, ucp_Nabataean },
+  { 857, PT_PC, ucp_Nd },
+  { 860, PT_SC, ucp_New_Tai_Lue },
+  { 872, PT_SC, ucp_Newa },
+  { 877, PT_SC, ucp_Nko },
+  { 881, PT_PC, ucp_Nl },
+  { 884, PT_PC, ucp_No },
+  { 887, PT_SC, ucp_Nushu },
+  { 893, PT_SC, ucp_Ogham },
+  { 899, PT_SC, ucp_Ol_Chiki },
+  { 908, PT_SC, ucp_Old_Hungarian },
+  { 922, PT_SC, ucp_Old_Italic },
+  { 933, PT_SC, ucp_Old_North_Arabian },
+  { 951, PT_SC, ucp_Old_Permic },
+  { 962, PT_SC, ucp_Old_Persian },
+  { 974, PT_SC, ucp_Old_South_Arabian },
+  { 992, PT_SC, ucp_Old_Turkic },
+  { 1003, PT_SC, ucp_Oriya },
+  { 1009, PT_SC, ucp_Osage },
+  { 1015, PT_SC, ucp_Osmanya },
+  { 1023, PT_GC, ucp_P },
+  { 1025, PT_SC, ucp_Pahawh_Hmong },
+  { 1038, PT_SC, ucp_Palmyrene },
+  { 1048, PT_SC, ucp_Pau_Cin_Hau },
+  { 1060, PT_PC, ucp_Pc },
+  { 1063, PT_PC, ucp_Pd },
+  { 1066, PT_PC, ucp_Pe },
+  { 1069, PT_PC, ucp_Pf },
+  { 1072, PT_SC, ucp_Phags_Pa },
+  { 1081, PT_SC, ucp_Phoenician },
+  { 1092, PT_PC, ucp_Pi },
+  { 1095, PT_PC, ucp_Po },
+  { 1098, PT_PC, ucp_Ps },
+  { 1101, PT_SC, ucp_Psalter_Pahlavi },
+  { 1117, PT_SC, ucp_Rejang },
+  { 1124, PT_SC, ucp_Runic },
+  { 1130, PT_GC, ucp_S },
+  { 1132, PT_SC, ucp_Samaritan },
+  { 1142, PT_SC, ucp_Saurashtra },
+  { 1153, PT_PC, ucp_Sc },
+  { 1156, PT_SC, ucp_Sharada },
+  { 1164, PT_SC, ucp_Shavian },
+  { 1172, PT_SC, ucp_Siddham },
+  { 1180, PT_SC, ucp_SignWriting },
+  { 1192, PT_SC, ucp_Sinhala },
+  { 1200, PT_PC, ucp_Sk },
+  { 1203, PT_PC, ucp_Sm },
+  { 1206, PT_PC, ucp_So },
+  { 1209, PT_SC, ucp_Sora_Sompeng },
+  { 1222, PT_SC, ucp_Soyombo },
+  { 1230, PT_SC, ucp_Sundanese },
+  { 1240, PT_SC, ucp_Syloti_Nagri },
+  { 1253, PT_SC, ucp_Syriac },
+  { 1260, PT_SC, ucp_Tagalog },
+  { 1268, PT_SC, ucp_Tagbanwa },
+  { 1277, PT_SC, ucp_Tai_Le },
+  { 1284, PT_SC, ucp_Tai_Tham },
+  { 1293, PT_SC, ucp_Tai_Viet },
+  { 1302, PT_SC, ucp_Takri },
+  { 1308, PT_SC, ucp_Tamil },
+  { 1314, PT_SC, ucp_Tangut },
+  { 1321, PT_SC, ucp_Telugu },
+  { 1328, PT_SC, ucp_Thaana },
+  { 1335, PT_SC, ucp_Thai },
+  { 1340, PT_SC, ucp_Tibetan },
+  { 1348, PT_SC, ucp_Tifinagh },
+  { 1357, PT_SC, ucp_Tirhuta },
+  { 1365, PT_SC, ucp_Ugaritic },
+  { 1374, PT_SC, ucp_Vai },
+  { 1378, PT_SC, ucp_Warang_Citi },
+  { 1390, PT_ALNUM, 0 },
+  { 1394, PT_PXSPACE, 0 },
+  { 1398, PT_SPACE, 0 },
+  { 1402, PT_UCNC, 0 },
+  { 1406, PT_WORD, 0 },
+  { 1410, PT_SC, ucp_Yi },
+  { 1413, PT_GC, ucp_Z },
+  { 1415, PT_SC, ucp_Zanabazar_Square },
+  { 1432, PT_PC, ucp_Zl },
+  { 1435, PT_PC, ucp_Zp },
+  { 1438, PT_PC, ucp_Zs }
 };
 
 const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
diff --git a/dist2/src/pcre2_ucd.c b/dist2/src/pcre2_ucd.c
index 116f537..ac7649b 100644
--- a/dist2/src/pcre2_ucd.c
+++ b/dist2/src/pcre2_ucd.c
@@ -20,7 +20,7 @@
 
 /* Unicode character database. */
 /* This file was autogenerated by the MultiStage2.py script. */
-/* Total size: 75072 bytes, block size: 128. */
+/* Total size: 80808 bytes, block size: 128. */
 
 /* The tables herein are needed only when UCP support is built,
 and in PCRE2 that happens automatically with UTF support.
@@ -39,7 +39,21 @@
 const uint32_t PRIV(ucd_caseless_sets)[] = {0};
 #else
 
-const char *PRIV(unicode_version) = "8.0.0";
+const char *PRIV(unicode_version) = "10.0.0";
+
+/* If the 32-bit library is run in non-32-bit mode, character values
+greater than 0x10ffff may be encountered. For these we set up a
+special record. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 32
+const ucd_record PRIV(dummy_ucd_record)[] = {{
+  ucp_Common,    /* script */
+  ucp_Cn,        /* type unassigned */
+  ucp_gbOther,   /* grapheme break property */
+  0,             /* case set */
+  0,             /* other case */
+  }};
+#endif
 
 /* When recompiling tables with a new Unicode version, please check the
 types in this structure definition from pcre2_internal.h (the actual
@@ -72,17 +86,25 @@
   0x039a,   0x03ba,   0x03f0,   NOTACHAR,
   0x03a1,   0x03c1,   0x03f1,   NOTACHAR,
   0x0395,   0x03b5,   0x03f5,   NOTACHAR,
+  0x0412,   0x0432,   0x1c80,   NOTACHAR,
+  0x0414,   0x0434,   0x1c81,   NOTACHAR,
+  0x041e,   0x043e,   0x1c82,   NOTACHAR,
+  0x0421,   0x0441,   0x1c83,   NOTACHAR,
+  0x0422,   0x0442,   0x1c84,   0x1c85,   NOTACHAR,
+  0x042a,   0x044a,   0x1c86,   NOTACHAR,
+  0x0462,   0x0463,   0x1c87,   NOTACHAR,
   0x1e60,   0x1e61,   0x1e9b,   NOTACHAR,
   0x03a9,   0x03c9,   0x2126,   NOTACHAR,
   0x004b,   0x006b,   0x212a,   NOTACHAR,
   0x00c5,   0x00e5,   0x212b,   NOTACHAR,
+  0x1c88,   0xa64a,   0xa64b,   NOTACHAR,
 };
 
 /* When #included in pcre2test, we don't need this large table. */
 
 #ifndef PCRE2_PCRE2TEST
 
-const ucd_record PRIV(ucd_records)[] = { /* 5952 bytes, record size 8 */
+const ucd_record PRIV(ucd_records)[] = { /* 6568 bytes, record size 8 */
   {     9,      0,      2,      0,      0, }, /*   0 */
   {     9,      0,      1,      0,      0, }, /*   1 */
   {     9,      0,      0,      0,      0, }, /*   2 */
@@ -95,12 +117,12 @@
   {     9,     17,     12,      0,      0, }, /*   9 */
   {     9,     13,     12,      0,      0, }, /*  10 */
   {    33,      9,     12,      0,     32, }, /*  11 */
-  {    33,      9,     12,     71,     32, }, /*  12 */
+  {    33,      9,     12,    100,     32, }, /*  12 */
   {    33,      9,     12,      1,     32, }, /*  13 */
   {     9,     24,     12,      0,      0, }, /*  14 */
   {     9,     16,     12,      0,      0, }, /*  15 */
   {    33,      5,     12,      0,    -32, }, /*  16 */
-  {    33,      5,     12,     71,    -32, }, /*  17 */
+  {    33,      5,     12,    100,    -32, }, /*  17 */
   {    33,      5,     12,      1,    -32, }, /*  18 */
   {     9,     26,     12,      0,      0, }, /*  19 */
   {    33,      7,     12,      0,      0, }, /*  20 */
@@ -109,9 +131,9 @@
   {     9,     15,     12,      0,      0, }, /*  23 */
   {     9,      5,     12,     26,    775, }, /*  24 */
   {     9,     19,     12,      0,      0, }, /*  25 */
-  {    33,      9,     12,     75,     32, }, /*  26 */
+  {    33,      9,     12,    104,     32, }, /*  26 */
   {    33,      5,     12,      0,   7615, }, /*  27 */
-  {    33,      5,     12,     75,    -32, }, /*  28 */
+  {    33,      5,     12,    104,    -32, }, /*  28 */
   {    33,      5,     12,      0,    121, }, /*  29 */
   {    33,      9,     12,      0,      1, }, /*  30 */
   {    33,      5,     12,      0,     -1, }, /*  31 */
@@ -218,7 +240,7 @@
   {    19,      9,     12,     55,     32, }, /* 132 */
   {    19,      9,     12,     30,     32, }, /* 133 */
   {    19,      9,     12,     43,     32, }, /* 134 */
-  {    19,      9,     12,     67,     32, }, /* 135 */
+  {    19,      9,     12,     96,     32, }, /* 135 */
   {    19,      5,     12,      0,    -38, }, /* 136 */
   {    19,      5,     12,      0,    -37, }, /* 137 */
   {    19,      5,     12,      0,    -32, }, /* 138 */
@@ -233,7 +255,7 @@
   {    19,      5,     12,     30,      1, }, /* 147 */
   {    19,      5,     12,     30,    -32, }, /* 148 */
   {    19,      5,     12,     43,    -32, }, /* 149 */
-  {    19,      5,     12,     67,    -32, }, /* 150 */
+  {    19,      5,     12,     96,    -32, }, /* 150 */
   {    19,      5,     12,      0,    -64, }, /* 151 */
   {    19,      5,     12,      0,    -63, }, /* 152 */
   {    19,      9,     12,      0,      8, }, /* 153 */
@@ -256,577 +278,654 @@
   {    19,      9,     12,      0,   -130, }, /* 170 */
   {    12,      9,     12,      0,     80, }, /* 171 */
   {    12,      9,     12,      0,     32, }, /* 172 */
-  {    12,      5,     12,      0,    -32, }, /* 173 */
-  {    12,      5,     12,      0,    -80, }, /* 174 */
-  {    12,      9,     12,      0,      1, }, /* 175 */
-  {    12,      5,     12,      0,     -1, }, /* 176 */
-  {    12,     26,     12,      0,      0, }, /* 177 */
-  {    12,     12,      3,      0,      0, }, /* 178 */
-  {    12,     11,      3,      0,      0, }, /* 179 */
-  {    12,      9,     12,      0,     15, }, /* 180 */
-  {    12,      5,     12,      0,    -15, }, /* 181 */
-  {     1,      9,     12,      0,     48, }, /* 182 */
-  {     1,      6,     12,      0,      0, }, /* 183 */
-  {     1,     21,     12,      0,      0, }, /* 184 */
-  {     1,      5,     12,      0,    -48, }, /* 185 */
-  {     1,      5,     12,      0,      0, }, /* 186 */
-  {     1,     17,     12,      0,      0, }, /* 187 */
-  {     1,     26,     12,      0,      0, }, /* 188 */
-  {     1,     23,     12,      0,      0, }, /* 189 */
-  {    25,     12,      3,      0,      0, }, /* 190 */
-  {    25,     17,     12,      0,      0, }, /* 191 */
-  {    25,     21,     12,      0,      0, }, /* 192 */
-  {    25,      7,     12,      0,      0, }, /* 193 */
-  {     0,      1,      2,      0,      0, }, /* 194 */
-  {     0,     25,     12,      0,      0, }, /* 195 */
-  {     0,     21,     12,      0,      0, }, /* 196 */
-  {     0,     23,     12,      0,      0, }, /* 197 */
-  {     0,     26,     12,      0,      0, }, /* 198 */
-  {     0,     12,      3,      0,      0, }, /* 199 */
-  {     0,      7,     12,      0,      0, }, /* 200 */
-  {     0,     13,     12,      0,      0, }, /* 201 */
-  {     0,      6,     12,      0,      0, }, /* 202 */
-  {    49,     21,     12,      0,      0, }, /* 203 */
-  {    49,      1,      2,      0,      0, }, /* 204 */
-  {    49,      7,     12,      0,      0, }, /* 205 */
-  {    49,     12,      3,      0,      0, }, /* 206 */
-  {    55,      7,     12,      0,      0, }, /* 207 */
-  {    55,     12,      3,      0,      0, }, /* 208 */
-  {    63,     13,     12,      0,      0, }, /* 209 */
-  {    63,      7,     12,      0,      0, }, /* 210 */
-  {    63,     12,      3,      0,      0, }, /* 211 */
-  {    63,      6,     12,      0,      0, }, /* 212 */
-  {    63,     26,     12,      0,      0, }, /* 213 */
-  {    63,     21,     12,      0,      0, }, /* 214 */
-  {    89,      7,     12,      0,      0, }, /* 215 */
-  {    89,     12,      3,      0,      0, }, /* 216 */
-  {    89,      6,     12,      0,      0, }, /* 217 */
-  {    89,     21,     12,      0,      0, }, /* 218 */
-  {    94,      7,     12,      0,      0, }, /* 219 */
-  {    94,     12,      3,      0,      0, }, /* 220 */
-  {    94,     21,     12,      0,      0, }, /* 221 */
-  {    14,     12,      3,      0,      0, }, /* 222 */
-  {    14,     10,      5,      0,      0, }, /* 223 */
-  {    14,      7,     12,      0,      0, }, /* 224 */
-  {    14,     13,     12,      0,      0, }, /* 225 */
-  {    14,     21,     12,      0,      0, }, /* 226 */
-  {    14,      6,     12,      0,      0, }, /* 227 */
-  {     2,      7,     12,      0,      0, }, /* 228 */
-  {     2,     12,      3,      0,      0, }, /* 229 */
-  {     2,     10,      5,      0,      0, }, /* 230 */
-  {     2,     10,      3,      0,      0, }, /* 231 */
-  {     2,     13,     12,      0,      0, }, /* 232 */
-  {     2,     23,     12,      0,      0, }, /* 233 */
-  {     2,     15,     12,      0,      0, }, /* 234 */
-  {     2,     26,     12,      0,      0, }, /* 235 */
-  {    21,     12,      3,      0,      0, }, /* 236 */
-  {    21,     10,      5,      0,      0, }, /* 237 */
-  {    21,      7,     12,      0,      0, }, /* 238 */
-  {    21,     13,     12,      0,      0, }, /* 239 */
-  {    20,     12,      3,      0,      0, }, /* 240 */
-  {    20,     10,      5,      0,      0, }, /* 241 */
-  {    20,      7,     12,      0,      0, }, /* 242 */
-  {    20,     13,     12,      0,      0, }, /* 243 */
-  {    20,     21,     12,      0,      0, }, /* 244 */
-  {    20,     23,     12,      0,      0, }, /* 245 */
-  {    43,     12,      3,      0,      0, }, /* 246 */
-  {    43,     10,      5,      0,      0, }, /* 247 */
-  {    43,      7,     12,      0,      0, }, /* 248 */
-  {    43,     10,      3,      0,      0, }, /* 249 */
-  {    43,     13,     12,      0,      0, }, /* 250 */
-  {    43,     26,     12,      0,      0, }, /* 251 */
-  {    43,     15,     12,      0,      0, }, /* 252 */
-  {    53,     12,      3,      0,      0, }, /* 253 */
-  {    53,      7,     12,      0,      0, }, /* 254 */
-  {    53,     10,      3,      0,      0, }, /* 255 */
-  {    53,     10,      5,      0,      0, }, /* 256 */
-  {    53,     13,     12,      0,      0, }, /* 257 */
-  {    53,     15,     12,      0,      0, }, /* 258 */
-  {    53,     26,     12,      0,      0, }, /* 259 */
-  {    53,     23,     12,      0,      0, }, /* 260 */
-  {    54,     12,      3,      0,      0, }, /* 261 */
-  {    54,     10,      5,      0,      0, }, /* 262 */
-  {    54,      7,     12,      0,      0, }, /* 263 */
-  {    54,     13,     12,      0,      0, }, /* 264 */
-  {    54,     15,     12,      0,      0, }, /* 265 */
-  {    54,     26,     12,      0,      0, }, /* 266 */
-  {    28,     12,      3,      0,      0, }, /* 267 */
-  {    28,     10,      5,      0,      0, }, /* 268 */
-  {    28,      7,     12,      0,      0, }, /* 269 */
-  {    28,     10,      3,      0,      0, }, /* 270 */
-  {    28,     13,     12,      0,      0, }, /* 271 */
-  {    36,     12,      3,      0,      0, }, /* 272 */
-  {    36,     10,      5,      0,      0, }, /* 273 */
-  {    36,      7,     12,      0,      0, }, /* 274 */
-  {    36,     10,      3,      0,      0, }, /* 275 */
-  {    36,     13,     12,      0,      0, }, /* 276 */
-  {    36,     15,     12,      0,      0, }, /* 277 */
-  {    36,     26,     12,      0,      0, }, /* 278 */
-  {    47,     10,      5,      0,      0, }, /* 279 */
-  {    47,      7,     12,      0,      0, }, /* 280 */
-  {    47,     12,      3,      0,      0, }, /* 281 */
-  {    47,     10,      3,      0,      0, }, /* 282 */
-  {    47,     13,     12,      0,      0, }, /* 283 */
-  {    47,     21,     12,      0,      0, }, /* 284 */
-  {    56,      7,     12,      0,      0, }, /* 285 */
-  {    56,     12,      3,      0,      0, }, /* 286 */
-  {    56,      7,      5,      0,      0, }, /* 287 */
-  {    56,      6,     12,      0,      0, }, /* 288 */
-  {    56,     21,     12,      0,      0, }, /* 289 */
-  {    56,     13,     12,      0,      0, }, /* 290 */
-  {    32,      7,     12,      0,      0, }, /* 291 */
-  {    32,     12,      3,      0,      0, }, /* 292 */
-  {    32,      7,      5,      0,      0, }, /* 293 */
-  {    32,      6,     12,      0,      0, }, /* 294 */
-  {    32,     13,     12,      0,      0, }, /* 295 */
-  {    57,      7,     12,      0,      0, }, /* 296 */
-  {    57,     26,     12,      0,      0, }, /* 297 */
-  {    57,     21,     12,      0,      0, }, /* 298 */
-  {    57,     12,      3,      0,      0, }, /* 299 */
-  {    57,     13,     12,      0,      0, }, /* 300 */
-  {    57,     15,     12,      0,      0, }, /* 301 */
-  {    57,     22,     12,      0,      0, }, /* 302 */
-  {    57,     18,     12,      0,      0, }, /* 303 */
-  {    57,     10,      5,      0,      0, }, /* 304 */
-  {    38,      7,     12,      0,      0, }, /* 305 */
-  {    38,     10,     12,      0,      0, }, /* 306 */
-  {    38,     12,      3,      0,      0, }, /* 307 */
-  {    38,     10,      5,      0,      0, }, /* 308 */
-  {    38,     13,     12,      0,      0, }, /* 309 */
-  {    38,     21,     12,      0,      0, }, /* 310 */
-  {    38,     26,     12,      0,      0, }, /* 311 */
-  {    16,      9,     12,      0,   7264, }, /* 312 */
-  {    16,      7,     12,      0,      0, }, /* 313 */
-  {    16,      6,     12,      0,      0, }, /* 314 */
-  {    23,      7,      6,      0,      0, }, /* 315 */
-  {    23,      7,      7,      0,      0, }, /* 316 */
-  {    23,      7,      8,      0,      0, }, /* 317 */
-  {    15,      7,     12,      0,      0, }, /* 318 */
-  {    15,     12,      3,      0,      0, }, /* 319 */
-  {    15,     21,     12,      0,      0, }, /* 320 */
-  {    15,     15,     12,      0,      0, }, /* 321 */
-  {    15,     26,     12,      0,      0, }, /* 322 */
-  {     8,      9,     12,      0,  38864, }, /* 323 */
-  {     8,      9,     12,      0,      8, }, /* 324 */
-  {     8,      5,     12,      0,     -8, }, /* 325 */
-  {     7,     17,     12,      0,      0, }, /* 326 */
-  {     7,      7,     12,      0,      0, }, /* 327 */
-  {     7,     21,     12,      0,      0, }, /* 328 */
-  {    40,     29,     12,      0,      0, }, /* 329 */
-  {    40,      7,     12,      0,      0, }, /* 330 */
-  {    40,     22,     12,      0,      0, }, /* 331 */
-  {    40,     18,     12,      0,      0, }, /* 332 */
-  {    45,      7,     12,      0,      0, }, /* 333 */
-  {    45,     14,     12,      0,      0, }, /* 334 */
-  {    50,      7,     12,      0,      0, }, /* 335 */
-  {    50,     12,      3,      0,      0, }, /* 336 */
-  {    24,      7,     12,      0,      0, }, /* 337 */
-  {    24,     12,      3,      0,      0, }, /* 338 */
-  {     6,      7,     12,      0,      0, }, /* 339 */
-  {     6,     12,      3,      0,      0, }, /* 340 */
-  {    51,      7,     12,      0,      0, }, /* 341 */
-  {    51,     12,      3,      0,      0, }, /* 342 */
-  {    31,      7,     12,      0,      0, }, /* 343 */
-  {    31,     12,      3,      0,      0, }, /* 344 */
-  {    31,     10,      5,      0,      0, }, /* 345 */
-  {    31,     21,     12,      0,      0, }, /* 346 */
-  {    31,      6,     12,      0,      0, }, /* 347 */
-  {    31,     23,     12,      0,      0, }, /* 348 */
-  {    31,     13,     12,      0,      0, }, /* 349 */
-  {    31,     15,     12,      0,      0, }, /* 350 */
-  {    37,     21,     12,      0,      0, }, /* 351 */
-  {    37,     17,     12,      0,      0, }, /* 352 */
-  {    37,     12,      3,      0,      0, }, /* 353 */
-  {    37,      1,      2,      0,      0, }, /* 354 */
-  {    37,     13,     12,      0,      0, }, /* 355 */
-  {    37,      7,     12,      0,      0, }, /* 356 */
-  {    37,      6,     12,      0,      0, }, /* 357 */
-  {    34,      7,     12,      0,      0, }, /* 358 */
-  {    34,     12,      3,      0,      0, }, /* 359 */
-  {    34,     10,      5,      0,      0, }, /* 360 */
-  {    34,     26,     12,      0,      0, }, /* 361 */
-  {    34,     21,     12,      0,      0, }, /* 362 */
-  {    34,     13,     12,      0,      0, }, /* 363 */
-  {    52,      7,     12,      0,      0, }, /* 364 */
-  {    39,      7,     12,      0,      0, }, /* 365 */
-  {    39,     13,     12,      0,      0, }, /* 366 */
-  {    39,     15,     12,      0,      0, }, /* 367 */
-  {    39,     26,     12,      0,      0, }, /* 368 */
-  {    31,     26,     12,      0,      0, }, /* 369 */
-  {     5,      7,     12,      0,      0, }, /* 370 */
-  {     5,     12,      3,      0,      0, }, /* 371 */
-  {     5,     10,      5,      0,      0, }, /* 372 */
-  {     5,     21,     12,      0,      0, }, /* 373 */
-  {    90,      7,     12,      0,      0, }, /* 374 */
-  {    90,     10,      5,      0,      0, }, /* 375 */
-  {    90,     12,      3,      0,      0, }, /* 376 */
-  {    90,     10,     12,      0,      0, }, /* 377 */
-  {    90,     13,     12,      0,      0, }, /* 378 */
-  {    90,     21,     12,      0,      0, }, /* 379 */
-  {    90,      6,     12,      0,      0, }, /* 380 */
-  {    27,     11,      3,      0,      0, }, /* 381 */
-  {    61,     12,      3,      0,      0, }, /* 382 */
-  {    61,     10,      5,      0,      0, }, /* 383 */
-  {    61,      7,     12,      0,      0, }, /* 384 */
-  {    61,     13,     12,      0,      0, }, /* 385 */
-  {    61,     21,     12,      0,      0, }, /* 386 */
-  {    61,     26,     12,      0,      0, }, /* 387 */
-  {    75,     12,      3,      0,      0, }, /* 388 */
-  {    75,     10,      5,      0,      0, }, /* 389 */
-  {    75,      7,     12,      0,      0, }, /* 390 */
-  {    75,     13,     12,      0,      0, }, /* 391 */
-  {    92,      7,     12,      0,      0, }, /* 392 */
-  {    92,     12,      3,      0,      0, }, /* 393 */
-  {    92,     10,      5,      0,      0, }, /* 394 */
-  {    92,     21,     12,      0,      0, }, /* 395 */
-  {    69,      7,     12,      0,      0, }, /* 396 */
-  {    69,     10,      5,      0,      0, }, /* 397 */
-  {    69,     12,      3,      0,      0, }, /* 398 */
-  {    69,     21,     12,      0,      0, }, /* 399 */
-  {    69,     13,     12,      0,      0, }, /* 400 */
-  {    72,     13,     12,      0,      0, }, /* 401 */
-  {    72,      7,     12,      0,      0, }, /* 402 */
-  {    72,      6,     12,      0,      0, }, /* 403 */
-  {    72,     21,     12,      0,      0, }, /* 404 */
-  {    75,     21,     12,      0,      0, }, /* 405 */
-  {     9,     10,      5,      0,      0, }, /* 406 */
-  {     9,      7,     12,      0,      0, }, /* 407 */
-  {    12,      5,     12,      0,      0, }, /* 408 */
-  {    12,      6,     12,      0,      0, }, /* 409 */
-  {    33,      5,     12,      0,  35332, }, /* 410 */
-  {    33,      5,     12,      0,   3814, }, /* 411 */
-  {    33,      9,     12,     63,      1, }, /* 412 */
-  {    33,      5,     12,     63,     -1, }, /* 413 */
-  {    33,      5,     12,     63,    -58, }, /* 414 */
-  {    33,      9,     12,      0,  -7615, }, /* 415 */
-  {    19,      5,     12,      0,      8, }, /* 416 */
-  {    19,      9,     12,      0,     -8, }, /* 417 */
-  {    19,      5,     12,      0,     74, }, /* 418 */
-  {    19,      5,     12,      0,     86, }, /* 419 */
-  {    19,      5,     12,      0,    100, }, /* 420 */
-  {    19,      5,     12,      0,    128, }, /* 421 */
-  {    19,      5,     12,      0,    112, }, /* 422 */
-  {    19,      5,     12,      0,    126, }, /* 423 */
-  {    19,      8,     12,      0,     -8, }, /* 424 */
-  {    19,      5,     12,      0,      9, }, /* 425 */
-  {    19,      9,     12,      0,    -74, }, /* 426 */
-  {    19,      8,     12,      0,     -9, }, /* 427 */
-  {    19,      5,     12,     21,  -7173, }, /* 428 */
-  {    19,      9,     12,      0,    -86, }, /* 429 */
-  {    19,      9,     12,      0,   -100, }, /* 430 */
-  {    19,      9,     12,      0,   -112, }, /* 431 */
-  {    19,      9,     12,      0,   -128, }, /* 432 */
-  {    19,      9,     12,      0,   -126, }, /* 433 */
-  {    27,      1,      3,      0,      0, }, /* 434 */
-  {     9,     27,      2,      0,      0, }, /* 435 */
-  {     9,     28,      2,      0,      0, }, /* 436 */
-  {     9,      2,      2,      0,      0, }, /* 437 */
-  {     9,      9,     12,      0,      0, }, /* 438 */
-  {     9,      5,     12,      0,      0, }, /* 439 */
-  {    19,      9,     12,     67,  -7517, }, /* 440 */
-  {    33,      9,     12,     71,  -8383, }, /* 441 */
-  {    33,      9,     12,     75,  -8262, }, /* 442 */
-  {    33,      9,     12,      0,     28, }, /* 443 */
-  {    33,      5,     12,      0,    -28, }, /* 444 */
-  {    33,     14,     12,      0,     16, }, /* 445 */
-  {    33,     14,     12,      0,    -16, }, /* 446 */
-  {    33,     14,     12,      0,      0, }, /* 447 */
-  {     9,     26,     12,      0,     26, }, /* 448 */
-  {     9,     26,     12,      0,    -26, }, /* 449 */
-  {     4,     26,     12,      0,      0, }, /* 450 */
-  {    17,      9,     12,      0,     48, }, /* 451 */
-  {    17,      5,     12,      0,    -48, }, /* 452 */
-  {    33,      9,     12,      0, -10743, }, /* 453 */
-  {    33,      9,     12,      0,  -3814, }, /* 454 */
-  {    33,      9,     12,      0, -10727, }, /* 455 */
-  {    33,      5,     12,      0, -10795, }, /* 456 */
-  {    33,      5,     12,      0, -10792, }, /* 457 */
-  {    33,      9,     12,      0, -10780, }, /* 458 */
-  {    33,      9,     12,      0, -10749, }, /* 459 */
-  {    33,      9,     12,      0, -10783, }, /* 460 */
-  {    33,      9,     12,      0, -10782, }, /* 461 */
-  {    33,      9,     12,      0, -10815, }, /* 462 */
-  {    10,      5,     12,      0,      0, }, /* 463 */
-  {    10,     26,     12,      0,      0, }, /* 464 */
-  {    10,     12,      3,      0,      0, }, /* 465 */
-  {    10,     21,     12,      0,      0, }, /* 466 */
-  {    10,     15,     12,      0,      0, }, /* 467 */
-  {    16,      5,     12,      0,  -7264, }, /* 468 */
-  {    58,      7,     12,      0,      0, }, /* 469 */
-  {    58,      6,     12,      0,      0, }, /* 470 */
-  {    58,     21,     12,      0,      0, }, /* 471 */
-  {    58,     12,      3,      0,      0, }, /* 472 */
-  {    22,     26,     12,      0,      0, }, /* 473 */
-  {    22,      6,     12,      0,      0, }, /* 474 */
-  {    22,     14,     12,      0,      0, }, /* 475 */
-  {    23,     10,      3,      0,      0, }, /* 476 */
-  {    26,      7,     12,      0,      0, }, /* 477 */
-  {    26,      6,     12,      0,      0, }, /* 478 */
-  {    29,      7,     12,      0,      0, }, /* 479 */
-  {    29,      6,     12,      0,      0, }, /* 480 */
-  {     3,      7,     12,      0,      0, }, /* 481 */
-  {    23,      7,     12,      0,      0, }, /* 482 */
-  {    23,     26,     12,      0,      0, }, /* 483 */
-  {    29,     26,     12,      0,      0, }, /* 484 */
-  {    22,      7,     12,      0,      0, }, /* 485 */
-  {    60,      7,     12,      0,      0, }, /* 486 */
-  {    60,      6,     12,      0,      0, }, /* 487 */
-  {    60,     26,     12,      0,      0, }, /* 488 */
-  {    85,      7,     12,      0,      0, }, /* 489 */
-  {    85,      6,     12,      0,      0, }, /* 490 */
-  {    85,     21,     12,      0,      0, }, /* 491 */
-  {    76,      7,     12,      0,      0, }, /* 492 */
-  {    76,      6,     12,      0,      0, }, /* 493 */
-  {    76,     21,     12,      0,      0, }, /* 494 */
-  {    76,     13,     12,      0,      0, }, /* 495 */
-  {    12,      7,     12,      0,      0, }, /* 496 */
-  {    12,     21,     12,      0,      0, }, /* 497 */
-  {    78,      7,     12,      0,      0, }, /* 498 */
-  {    78,     14,     12,      0,      0, }, /* 499 */
-  {    78,     12,      3,      0,      0, }, /* 500 */
-  {    78,     21,     12,      0,      0, }, /* 501 */
-  {    33,      9,     12,      0, -35332, }, /* 502 */
-  {    33,      9,     12,      0, -42280, }, /* 503 */
-  {    33,      9,     12,      0, -42308, }, /* 504 */
-  {    33,      9,     12,      0, -42319, }, /* 505 */
-  {    33,      9,     12,      0, -42315, }, /* 506 */
-  {    33,      9,     12,      0, -42305, }, /* 507 */
-  {    33,      9,     12,      0, -42258, }, /* 508 */
-  {    33,      9,     12,      0, -42282, }, /* 509 */
-  {    33,      9,     12,      0, -42261, }, /* 510 */
-  {    33,      9,     12,      0,    928, }, /* 511 */
-  {    48,      7,     12,      0,      0, }, /* 512 */
-  {    48,     12,      3,      0,      0, }, /* 513 */
-  {    48,     10,      5,      0,      0, }, /* 514 */
-  {    48,     26,     12,      0,      0, }, /* 515 */
-  {    64,      7,     12,      0,      0, }, /* 516 */
-  {    64,     21,     12,      0,      0, }, /* 517 */
-  {    74,     10,      5,      0,      0, }, /* 518 */
-  {    74,      7,     12,      0,      0, }, /* 519 */
-  {    74,     12,      3,      0,      0, }, /* 520 */
-  {    74,     21,     12,      0,      0, }, /* 521 */
-  {    74,     13,     12,      0,      0, }, /* 522 */
-  {    68,     13,     12,      0,      0, }, /* 523 */
-  {    68,      7,     12,      0,      0, }, /* 524 */
-  {    68,     12,      3,      0,      0, }, /* 525 */
-  {    68,     21,     12,      0,      0, }, /* 526 */
-  {    73,      7,     12,      0,      0, }, /* 527 */
-  {    73,     12,      3,      0,      0, }, /* 528 */
-  {    73,     10,      5,      0,      0, }, /* 529 */
-  {    73,     21,     12,      0,      0, }, /* 530 */
-  {    83,     12,      3,      0,      0, }, /* 531 */
-  {    83,     10,      5,      0,      0, }, /* 532 */
-  {    83,      7,     12,      0,      0, }, /* 533 */
-  {    83,     21,     12,      0,      0, }, /* 534 */
-  {    83,     13,     12,      0,      0, }, /* 535 */
-  {    38,      6,     12,      0,      0, }, /* 536 */
-  {    67,      7,     12,      0,      0, }, /* 537 */
-  {    67,     12,      3,      0,      0, }, /* 538 */
-  {    67,     10,      5,      0,      0, }, /* 539 */
-  {    67,     13,     12,      0,      0, }, /* 540 */
-  {    67,     21,     12,      0,      0, }, /* 541 */
-  {    91,      7,     12,      0,      0, }, /* 542 */
-  {    91,     12,      3,      0,      0, }, /* 543 */
-  {    91,      6,     12,      0,      0, }, /* 544 */
-  {    91,     21,     12,      0,      0, }, /* 545 */
-  {    86,      7,     12,      0,      0, }, /* 546 */
-  {    86,     10,      5,      0,      0, }, /* 547 */
-  {    86,     12,      3,      0,      0, }, /* 548 */
-  {    86,     21,     12,      0,      0, }, /* 549 */
-  {    86,      6,     12,      0,      0, }, /* 550 */
-  {    33,      5,     12,      0,   -928, }, /* 551 */
-  {     8,      5,     12,      0, -38864, }, /* 552 */
-  {    86,     13,     12,      0,      0, }, /* 553 */
-  {    23,      7,      9,      0,      0, }, /* 554 */
-  {    23,      7,     10,      0,      0, }, /* 555 */
-  {     9,      4,      2,      0,      0, }, /* 556 */
-  {     9,      3,     12,      0,      0, }, /* 557 */
-  {    25,     25,     12,      0,      0, }, /* 558 */
-  {     0,     24,     12,      0,      0, }, /* 559 */
-  {     9,      6,      3,      0,      0, }, /* 560 */
-  {    35,      7,     12,      0,      0, }, /* 561 */
-  {    19,     14,     12,      0,      0, }, /* 562 */
-  {    19,     15,     12,      0,      0, }, /* 563 */
-  {    19,     26,     12,      0,      0, }, /* 564 */
-  {    70,      7,     12,      0,      0, }, /* 565 */
-  {    66,      7,     12,      0,      0, }, /* 566 */
-  {    41,      7,     12,      0,      0, }, /* 567 */
-  {    41,     15,     12,      0,      0, }, /* 568 */
-  {    18,      7,     12,      0,      0, }, /* 569 */
-  {    18,     14,     12,      0,      0, }, /* 570 */
-  {   117,      7,     12,      0,      0, }, /* 571 */
-  {   117,     12,      3,      0,      0, }, /* 572 */
-  {    59,      7,     12,      0,      0, }, /* 573 */
-  {    59,     21,     12,      0,      0, }, /* 574 */
-  {    42,      7,     12,      0,      0, }, /* 575 */
-  {    42,     21,     12,      0,      0, }, /* 576 */
-  {    42,     14,     12,      0,      0, }, /* 577 */
-  {    13,      9,     12,      0,     40, }, /* 578 */
-  {    13,      5,     12,      0,    -40, }, /* 579 */
-  {    46,      7,     12,      0,      0, }, /* 580 */
-  {    44,      7,     12,      0,      0, }, /* 581 */
-  {    44,     13,     12,      0,      0, }, /* 582 */
-  {   105,      7,     12,      0,      0, }, /* 583 */
-  {   103,      7,     12,      0,      0, }, /* 584 */
-  {   103,     21,     12,      0,      0, }, /* 585 */
-  {   109,      7,     12,      0,      0, }, /* 586 */
-  {    11,      7,     12,      0,      0, }, /* 587 */
-  {    80,      7,     12,      0,      0, }, /* 588 */
-  {    80,     21,     12,      0,      0, }, /* 589 */
-  {    80,     15,     12,      0,      0, }, /* 590 */
-  {   119,      7,     12,      0,      0, }, /* 591 */
-  {   119,     26,     12,      0,      0, }, /* 592 */
-  {   119,     15,     12,      0,      0, }, /* 593 */
-  {   115,      7,     12,      0,      0, }, /* 594 */
-  {   115,     15,     12,      0,      0, }, /* 595 */
-  {   127,      7,     12,      0,      0, }, /* 596 */
-  {   127,     15,     12,      0,      0, }, /* 597 */
-  {    65,      7,     12,      0,      0, }, /* 598 */
-  {    65,     15,     12,      0,      0, }, /* 599 */
-  {    65,     21,     12,      0,      0, }, /* 600 */
-  {    71,      7,     12,      0,      0, }, /* 601 */
-  {    71,     21,     12,      0,      0, }, /* 602 */
-  {    97,      7,     12,      0,      0, }, /* 603 */
-  {    96,      7,     12,      0,      0, }, /* 604 */
-  {    96,     15,     12,      0,      0, }, /* 605 */
-  {    30,      7,     12,      0,      0, }, /* 606 */
-  {    30,     12,      3,      0,      0, }, /* 607 */
-  {    30,     15,     12,      0,      0, }, /* 608 */
-  {    30,     21,     12,      0,      0, }, /* 609 */
-  {    87,      7,     12,      0,      0, }, /* 610 */
-  {    87,     15,     12,      0,      0, }, /* 611 */
-  {    87,     21,     12,      0,      0, }, /* 612 */
-  {   116,      7,     12,      0,      0, }, /* 613 */
-  {   116,     15,     12,      0,      0, }, /* 614 */
-  {   111,      7,     12,      0,      0, }, /* 615 */
-  {   111,     26,     12,      0,      0, }, /* 616 */
-  {   111,     12,      3,      0,      0, }, /* 617 */
-  {   111,     15,     12,      0,      0, }, /* 618 */
-  {   111,     21,     12,      0,      0, }, /* 619 */
-  {    77,      7,     12,      0,      0, }, /* 620 */
-  {    77,     21,     12,      0,      0, }, /* 621 */
-  {    82,      7,     12,      0,      0, }, /* 622 */
-  {    82,     15,     12,      0,      0, }, /* 623 */
-  {    81,      7,     12,      0,      0, }, /* 624 */
-  {    81,     15,     12,      0,      0, }, /* 625 */
-  {   120,      7,     12,      0,      0, }, /* 626 */
-  {   120,     21,     12,      0,      0, }, /* 627 */
-  {   120,     15,     12,      0,      0, }, /* 628 */
-  {    88,      7,     12,      0,      0, }, /* 629 */
-  {   129,      9,     12,      0,     64, }, /* 630 */
-  {   129,      5,     12,      0,    -64, }, /* 631 */
-  {   129,     15,     12,      0,      0, }, /* 632 */
-  {     0,     15,     12,      0,      0, }, /* 633 */
-  {    93,     10,      5,      0,      0, }, /* 634 */
-  {    93,     12,      3,      0,      0, }, /* 635 */
-  {    93,      7,     12,      0,      0, }, /* 636 */
-  {    93,     21,     12,      0,      0, }, /* 637 */
-  {    93,     15,     12,      0,      0, }, /* 638 */
-  {    93,     13,     12,      0,      0, }, /* 639 */
-  {    84,     12,      3,      0,      0, }, /* 640 */
-  {    84,     10,      5,      0,      0, }, /* 641 */
-  {    84,      7,     12,      0,      0, }, /* 642 */
-  {    84,     21,     12,      0,      0, }, /* 643 */
-  {    84,      1,      2,      0,      0, }, /* 644 */
-  {   100,      7,     12,      0,      0, }, /* 645 */
-  {   100,     13,     12,      0,      0, }, /* 646 */
-  {    95,     12,      3,      0,      0, }, /* 647 */
-  {    95,      7,     12,      0,      0, }, /* 648 */
-  {    95,     10,      5,      0,      0, }, /* 649 */
-  {    95,     13,     12,      0,      0, }, /* 650 */
-  {    95,     21,     12,      0,      0, }, /* 651 */
-  {   110,      7,     12,      0,      0, }, /* 652 */
-  {   110,     12,      3,      0,      0, }, /* 653 */
-  {   110,     21,     12,      0,      0, }, /* 654 */
-  {    99,     12,      3,      0,      0, }, /* 655 */
-  {    99,     10,      5,      0,      0, }, /* 656 */
-  {    99,      7,     12,      0,      0, }, /* 657 */
-  {    99,     21,     12,      0,      0, }, /* 658 */
-  {    99,     13,     12,      0,      0, }, /* 659 */
-  {    47,     15,     12,      0,      0, }, /* 660 */
-  {   107,      7,     12,      0,      0, }, /* 661 */
-  {   107,     10,      5,      0,      0, }, /* 662 */
-  {   107,     12,      3,      0,      0, }, /* 663 */
-  {   107,     21,     12,      0,      0, }, /* 664 */
-  {   128,      7,     12,      0,      0, }, /* 665 */
-  {   128,     21,     12,      0,      0, }, /* 666 */
-  {   108,      7,     12,      0,      0, }, /* 667 */
-  {   108,     12,      3,      0,      0, }, /* 668 */
-  {   108,     10,      5,      0,      0, }, /* 669 */
-  {   108,     13,     12,      0,      0, }, /* 670 */
-  {   106,     12,      3,      0,      0, }, /* 671 */
-  {   106,     10,      5,      0,      0, }, /* 672 */
-  {   106,      7,     12,      0,      0, }, /* 673 */
-  {   106,     10,      3,      0,      0, }, /* 674 */
-  {   123,      7,     12,      0,      0, }, /* 675 */
-  {   123,     10,      3,      0,      0, }, /* 676 */
-  {   123,     10,      5,      0,      0, }, /* 677 */
-  {   123,     12,      3,      0,      0, }, /* 678 */
-  {   123,     21,     12,      0,      0, }, /* 679 */
-  {   123,     13,     12,      0,      0, }, /* 680 */
-  {   122,      7,     12,      0,      0, }, /* 681 */
-  {   122,     10,      3,      0,      0, }, /* 682 */
-  {   122,     10,      5,      0,      0, }, /* 683 */
-  {   122,     12,      3,      0,      0, }, /* 684 */
-  {   122,     21,     12,      0,      0, }, /* 685 */
-  {   113,      7,     12,      0,      0, }, /* 686 */
-  {   113,     10,      5,      0,      0, }, /* 687 */
-  {   113,     12,      3,      0,      0, }, /* 688 */
-  {   113,     21,     12,      0,      0, }, /* 689 */
-  {   113,     13,     12,      0,      0, }, /* 690 */
-  {   101,      7,     12,      0,      0, }, /* 691 */
-  {   101,     12,      3,      0,      0, }, /* 692 */
-  {   101,     10,      5,      0,      0, }, /* 693 */
-  {   101,     13,     12,      0,      0, }, /* 694 */
-  {   125,      7,     12,      0,      0, }, /* 695 */
-  {   125,     12,      3,      0,      0, }, /* 696 */
-  {   125,     10,      5,      0,      0, }, /* 697 */
-  {   125,     13,     12,      0,      0, }, /* 698 */
-  {   125,     15,     12,      0,      0, }, /* 699 */
-  {   125,     21,     12,      0,      0, }, /* 700 */
-  {   125,     26,     12,      0,      0, }, /* 701 */
-  {   124,      9,     12,      0,     32, }, /* 702 */
-  {   124,      5,     12,      0,    -32, }, /* 703 */
-  {   124,     13,     12,      0,      0, }, /* 704 */
-  {   124,     15,     12,      0,      0, }, /* 705 */
-  {   124,      7,     12,      0,      0, }, /* 706 */
-  {   121,      7,     12,      0,      0, }, /* 707 */
-  {    62,      7,     12,      0,      0, }, /* 708 */
-  {    62,     14,     12,      0,      0, }, /* 709 */
-  {    62,     21,     12,      0,      0, }, /* 710 */
-  {    79,      7,     12,      0,      0, }, /* 711 */
-  {   126,      7,     12,      0,      0, }, /* 712 */
-  {   114,      7,     12,      0,      0, }, /* 713 */
-  {   114,     13,     12,      0,      0, }, /* 714 */
-  {   114,     21,     12,      0,      0, }, /* 715 */
-  {   102,      7,     12,      0,      0, }, /* 716 */
-  {   102,     12,      3,      0,      0, }, /* 717 */
-  {   102,     21,     12,      0,      0, }, /* 718 */
-  {   118,      7,     12,      0,      0, }, /* 719 */
-  {   118,     12,      3,      0,      0, }, /* 720 */
-  {   118,     21,     12,      0,      0, }, /* 721 */
-  {   118,     26,     12,      0,      0, }, /* 722 */
-  {   118,      6,     12,      0,      0, }, /* 723 */
-  {   118,     13,     12,      0,      0, }, /* 724 */
-  {   118,     15,     12,      0,      0, }, /* 725 */
-  {    98,      7,     12,      0,      0, }, /* 726 */
-  {    98,     10,      5,      0,      0, }, /* 727 */
-  {    98,     12,      3,      0,      0, }, /* 728 */
-  {    98,      6,     12,      0,      0, }, /* 729 */
-  {   104,      7,     12,      0,      0, }, /* 730 */
-  {   104,     26,     12,      0,      0, }, /* 731 */
-  {   104,     12,      3,      0,      0, }, /* 732 */
-  {   104,     21,     12,      0,      0, }, /* 733 */
-  {     9,     10,      3,      0,      0, }, /* 734 */
-  {    19,     12,      3,      0,      0, }, /* 735 */
-  {   130,     26,     12,      0,      0, }, /* 736 */
-  {   130,     12,      3,      0,      0, }, /* 737 */
-  {   130,     21,     12,      0,      0, }, /* 738 */
-  {   112,      7,     12,      0,      0, }, /* 739 */
-  {   112,     15,     12,      0,      0, }, /* 740 */
-  {   112,     12,      3,      0,      0, }, /* 741 */
-  {     9,     26,     11,      0,      0, }, /* 742 */
-  {    26,     26,     12,      0,      0, }, /* 743 */
+  {    12,      9,     12,     63,     32, }, /* 173 */
+  {    12,      9,     12,     67,     32, }, /* 174 */
+  {    12,      9,     12,     71,     32, }, /* 175 */
+  {    12,      9,     12,     75,     32, }, /* 176 */
+  {    12,      9,     12,     79,     32, }, /* 177 */
+  {    12,      9,     12,     84,     32, }, /* 178 */
+  {    12,      5,     12,      0,    -32, }, /* 179 */
+  {    12,      5,     12,     63,    -32, }, /* 180 */
+  {    12,      5,     12,     67,    -32, }, /* 181 */
+  {    12,      5,     12,     71,    -32, }, /* 182 */
+  {    12,      5,     12,     75,    -32, }, /* 183 */
+  {    12,      5,     12,     79,    -32, }, /* 184 */
+  {    12,      5,     12,     84,    -32, }, /* 185 */
+  {    12,      5,     12,      0,    -80, }, /* 186 */
+  {    12,      9,     12,      0,      1, }, /* 187 */
+  {    12,      5,     12,      0,     -1, }, /* 188 */
+  {    12,      9,     12,     88,      1, }, /* 189 */
+  {    12,      5,     12,     88,     -1, }, /* 190 */
+  {    12,     26,     12,      0,      0, }, /* 191 */
+  {    12,     12,      3,      0,      0, }, /* 192 */
+  {    12,     11,      3,      0,      0, }, /* 193 */
+  {    12,      9,     12,      0,     15, }, /* 194 */
+  {    12,      5,     12,      0,    -15, }, /* 195 */
+  {     1,      9,     12,      0,     48, }, /* 196 */
+  {     1,      6,     12,      0,      0, }, /* 197 */
+  {     1,     21,     12,      0,      0, }, /* 198 */
+  {     1,      5,     12,      0,    -48, }, /* 199 */
+  {     1,      5,     12,      0,      0, }, /* 200 */
+  {     1,     17,     12,      0,      0, }, /* 201 */
+  {     1,     26,     12,      0,      0, }, /* 202 */
+  {     1,     23,     12,      0,      0, }, /* 203 */
+  {    25,     12,      3,      0,      0, }, /* 204 */
+  {    25,     17,     12,      0,      0, }, /* 205 */
+  {    25,     21,     12,      0,      0, }, /* 206 */
+  {    25,      7,     12,      0,      0, }, /* 207 */
+  {     0,      1,      4,      0,      0, }, /* 208 */
+  {     9,      1,      4,      0,      0, }, /* 209 */
+  {     0,     25,     12,      0,      0, }, /* 210 */
+  {     0,     21,     12,      0,      0, }, /* 211 */
+  {     0,     23,     12,      0,      0, }, /* 212 */
+  {     0,     26,     12,      0,      0, }, /* 213 */
+  {     0,     12,      3,      0,      0, }, /* 214 */
+  {     0,      1,      2,      0,      0, }, /* 215 */
+  {     0,      7,     12,      0,      0, }, /* 216 */
+  {     0,     13,     12,      0,      0, }, /* 217 */
+  {     0,      6,     12,      0,      0, }, /* 218 */
+  {    49,     21,     12,      0,      0, }, /* 219 */
+  {    49,      1,      4,      0,      0, }, /* 220 */
+  {    49,      7,     12,      0,      0, }, /* 221 */
+  {    49,     12,      3,      0,      0, }, /* 222 */
+  {    55,      7,     12,      0,      0, }, /* 223 */
+  {    55,     12,      3,      0,      0, }, /* 224 */
+  {    63,     13,     12,      0,      0, }, /* 225 */
+  {    63,      7,     12,      0,      0, }, /* 226 */
+  {    63,     12,      3,      0,      0, }, /* 227 */
+  {    63,      6,     12,      0,      0, }, /* 228 */
+  {    63,     26,     12,      0,      0, }, /* 229 */
+  {    63,     21,     12,      0,      0, }, /* 230 */
+  {    89,      7,     12,      0,      0, }, /* 231 */
+  {    89,     12,      3,      0,      0, }, /* 232 */
+  {    89,      6,     12,      0,      0, }, /* 233 */
+  {    89,     21,     12,      0,      0, }, /* 234 */
+  {    94,      7,     12,      0,      0, }, /* 235 */
+  {    94,     12,      3,      0,      0, }, /* 236 */
+  {    94,     21,     12,      0,      0, }, /* 237 */
+  {    14,     12,      3,      0,      0, }, /* 238 */
+  {    14,     10,      5,      0,      0, }, /* 239 */
+  {    14,      7,     12,      0,      0, }, /* 240 */
+  {    14,     13,     12,      0,      0, }, /* 241 */
+  {    14,     21,     12,      0,      0, }, /* 242 */
+  {    14,      6,     12,      0,      0, }, /* 243 */
+  {     2,      7,     12,      0,      0, }, /* 244 */
+  {     2,     12,      3,      0,      0, }, /* 245 */
+  {     2,     10,      5,      0,      0, }, /* 246 */
+  {     2,     10,      3,      0,      0, }, /* 247 */
+  {     2,     13,     12,      0,      0, }, /* 248 */
+  {     2,     23,     12,      0,      0, }, /* 249 */
+  {     2,     15,     12,      0,      0, }, /* 250 */
+  {     2,     26,     12,      0,      0, }, /* 251 */
+  {     2,     21,     12,      0,      0, }, /* 252 */
+  {    21,     12,      3,      0,      0, }, /* 253 */
+  {    21,     10,      5,      0,      0, }, /* 254 */
+  {    21,      7,     12,      0,      0, }, /* 255 */
+  {    21,     13,     12,      0,      0, }, /* 256 */
+  {    20,     12,      3,      0,      0, }, /* 257 */
+  {    20,     10,      5,      0,      0, }, /* 258 */
+  {    20,      7,     12,      0,      0, }, /* 259 */
+  {    20,     13,     12,      0,      0, }, /* 260 */
+  {    20,     21,     12,      0,      0, }, /* 261 */
+  {    20,     23,     12,      0,      0, }, /* 262 */
+  {    43,     12,      3,      0,      0, }, /* 263 */
+  {    43,     10,      5,      0,      0, }, /* 264 */
+  {    43,      7,     12,      0,      0, }, /* 265 */
+  {    43,     10,      3,      0,      0, }, /* 266 */
+  {    43,     13,     12,      0,      0, }, /* 267 */
+  {    43,     26,     12,      0,      0, }, /* 268 */
+  {    43,     15,     12,      0,      0, }, /* 269 */
+  {    53,     12,      3,      0,      0, }, /* 270 */
+  {    53,      7,     12,      0,      0, }, /* 271 */
+  {    53,     10,      3,      0,      0, }, /* 272 */
+  {    53,     10,      5,      0,      0, }, /* 273 */
+  {    53,     13,     12,      0,      0, }, /* 274 */
+  {    53,     15,     12,      0,      0, }, /* 275 */
+  {    53,     26,     12,      0,      0, }, /* 276 */
+  {    53,     23,     12,      0,      0, }, /* 277 */
+  {    54,     12,      3,      0,      0, }, /* 278 */
+  {    54,     10,      5,      0,      0, }, /* 279 */
+  {    54,      7,     12,      0,      0, }, /* 280 */
+  {    54,     13,     12,      0,      0, }, /* 281 */
+  {    54,     15,     12,      0,      0, }, /* 282 */
+  {    54,     26,     12,      0,      0, }, /* 283 */
+  {    28,      7,     12,      0,      0, }, /* 284 */
+  {    28,     12,      3,      0,      0, }, /* 285 */
+  {    28,     10,      5,      0,      0, }, /* 286 */
+  {    28,     10,      3,      0,      0, }, /* 287 */
+  {    28,     13,     12,      0,      0, }, /* 288 */
+  {    36,     12,      3,      0,      0, }, /* 289 */
+  {    36,     10,      5,      0,      0, }, /* 290 */
+  {    36,      7,     12,      0,      0, }, /* 291 */
+  {    36,     10,      3,      0,      0, }, /* 292 */
+  {    36,      7,      4,      0,      0, }, /* 293 */
+  {    36,     26,     12,      0,      0, }, /* 294 */
+  {    36,     15,     12,      0,      0, }, /* 295 */
+  {    36,     13,     12,      0,      0, }, /* 296 */
+  {    47,     10,      5,      0,      0, }, /* 297 */
+  {    47,      7,     12,      0,      0, }, /* 298 */
+  {    47,     12,      3,      0,      0, }, /* 299 */
+  {    47,     10,      3,      0,      0, }, /* 300 */
+  {    47,     13,     12,      0,      0, }, /* 301 */
+  {    47,     21,     12,      0,      0, }, /* 302 */
+  {    56,      7,     12,      0,      0, }, /* 303 */
+  {    56,     12,      3,      0,      0, }, /* 304 */
+  {    56,      7,      5,      0,      0, }, /* 305 */
+  {    56,      6,     12,      0,      0, }, /* 306 */
+  {    56,     21,     12,      0,      0, }, /* 307 */
+  {    56,     13,     12,      0,      0, }, /* 308 */
+  {    32,      7,     12,      0,      0, }, /* 309 */
+  {    32,     12,      3,      0,      0, }, /* 310 */
+  {    32,      7,      5,      0,      0, }, /* 311 */
+  {    32,      6,     12,      0,      0, }, /* 312 */
+  {    32,     13,     12,      0,      0, }, /* 313 */
+  {    57,      7,     12,      0,      0, }, /* 314 */
+  {    57,     26,     12,      0,      0, }, /* 315 */
+  {    57,     21,     12,      0,      0, }, /* 316 */
+  {    57,     12,      3,      0,      0, }, /* 317 */
+  {    57,     13,     12,      0,      0, }, /* 318 */
+  {    57,     15,     12,      0,      0, }, /* 319 */
+  {    57,     22,     12,      0,      0, }, /* 320 */
+  {    57,     18,     12,      0,      0, }, /* 321 */
+  {    57,     10,      5,      0,      0, }, /* 322 */
+  {    38,      7,     12,      0,      0, }, /* 323 */
+  {    38,     10,     12,      0,      0, }, /* 324 */
+  {    38,     12,      3,      0,      0, }, /* 325 */
+  {    38,     10,      5,      0,      0, }, /* 326 */
+  {    38,     13,     12,      0,      0, }, /* 327 */
+  {    38,     21,     12,      0,      0, }, /* 328 */
+  {    38,     26,     12,      0,      0, }, /* 329 */
+  {    16,      9,     12,      0,   7264, }, /* 330 */
+  {    16,      7,     12,      0,      0, }, /* 331 */
+  {    16,      6,     12,      0,      0, }, /* 332 */
+  {    23,      7,      6,      0,      0, }, /* 333 */
+  {    23,      7,      7,      0,      0, }, /* 334 */
+  {    23,      7,      8,      0,      0, }, /* 335 */
+  {    15,      7,     12,      0,      0, }, /* 336 */
+  {    15,     12,      3,      0,      0, }, /* 337 */
+  {    15,     21,     12,      0,      0, }, /* 338 */
+  {    15,     15,     12,      0,      0, }, /* 339 */
+  {    15,     26,     12,      0,      0, }, /* 340 */
+  {     8,      9,     12,      0,  38864, }, /* 341 */
+  {     8,      9,     12,      0,      8, }, /* 342 */
+  {     8,      5,     12,      0,     -8, }, /* 343 */
+  {     7,     17,     12,      0,      0, }, /* 344 */
+  {     7,      7,     12,      0,      0, }, /* 345 */
+  {     7,     21,     12,      0,      0, }, /* 346 */
+  {    40,     29,     12,      0,      0, }, /* 347 */
+  {    40,      7,     12,      0,      0, }, /* 348 */
+  {    40,     22,     12,      0,      0, }, /* 349 */
+  {    40,     18,     12,      0,      0, }, /* 350 */
+  {    45,      7,     12,      0,      0, }, /* 351 */
+  {    45,     14,     12,      0,      0, }, /* 352 */
+  {    50,      7,     12,      0,      0, }, /* 353 */
+  {    50,     12,      3,      0,      0, }, /* 354 */
+  {    24,      7,     12,      0,      0, }, /* 355 */
+  {    24,     12,      3,      0,      0, }, /* 356 */
+  {     6,      7,     12,      0,      0, }, /* 357 */
+  {     6,     12,      3,      0,      0, }, /* 358 */
+  {    51,      7,     12,      0,      0, }, /* 359 */
+  {    51,     12,      3,      0,      0, }, /* 360 */
+  {    31,      7,     12,      0,      0, }, /* 361 */
+  {    31,     12,      3,      0,      0, }, /* 362 */
+  {    31,     10,      5,      0,      0, }, /* 363 */
+  {    31,     21,     12,      0,      0, }, /* 364 */
+  {    31,      6,     12,      0,      0, }, /* 365 */
+  {    31,     23,     12,      0,      0, }, /* 366 */
+  {    31,     13,     12,      0,      0, }, /* 367 */
+  {    31,     15,     12,      0,      0, }, /* 368 */
+  {    37,     21,     12,      0,      0, }, /* 369 */
+  {    37,     17,     12,      0,      0, }, /* 370 */
+  {    37,     12,      3,      0,      0, }, /* 371 */
+  {    37,      1,      2,      0,      0, }, /* 372 */
+  {    37,     13,     12,      0,      0, }, /* 373 */
+  {    37,      7,     12,      0,      0, }, /* 374 */
+  {    37,      6,     12,      0,      0, }, /* 375 */
+  {    34,      7,     12,      0,      0, }, /* 376 */
+  {    34,     12,      3,      0,      0, }, /* 377 */
+  {    34,     10,      5,      0,      0, }, /* 378 */
+  {    34,     26,     12,      0,      0, }, /* 379 */
+  {    34,     21,     12,      0,      0, }, /* 380 */
+  {    34,     13,     12,      0,      0, }, /* 381 */
+  {    52,      7,     12,      0,      0, }, /* 382 */
+  {    39,      7,     12,      0,      0, }, /* 383 */
+  {    39,     13,     12,      0,      0, }, /* 384 */
+  {    39,     15,     12,      0,      0, }, /* 385 */
+  {    39,     26,     12,      0,      0, }, /* 386 */
+  {    31,     26,     12,      0,      0, }, /* 387 */
+  {     5,      7,     12,      0,      0, }, /* 388 */
+  {     5,     12,      3,      0,      0, }, /* 389 */
+  {     5,     10,      5,      0,      0, }, /* 390 */
+  {     5,     21,     12,      0,      0, }, /* 391 */
+  {    90,      7,     12,      0,      0, }, /* 392 */
+  {    90,     10,      5,      0,      0, }, /* 393 */
+  {    90,     12,      3,      0,      0, }, /* 394 */
+  {    90,     10,     12,      0,      0, }, /* 395 */
+  {    90,     13,     12,      0,      0, }, /* 396 */
+  {    90,     21,     12,      0,      0, }, /* 397 */
+  {    90,      6,     12,      0,      0, }, /* 398 */
+  {    27,     11,      3,      0,      0, }, /* 399 */
+  {    61,     12,      3,      0,      0, }, /* 400 */
+  {    61,     10,      5,      0,      0, }, /* 401 */
+  {    61,      7,     12,      0,      0, }, /* 402 */
+  {    61,     13,     12,      0,      0, }, /* 403 */
+  {    61,     21,     12,      0,      0, }, /* 404 */
+  {    61,     26,     12,      0,      0, }, /* 405 */
+  {    75,     12,      3,      0,      0, }, /* 406 */
+  {    75,     10,      5,      0,      0, }, /* 407 */
+  {    75,      7,     12,      0,      0, }, /* 408 */
+  {    75,     13,     12,      0,      0, }, /* 409 */
+  {    92,      7,     12,      0,      0, }, /* 410 */
+  {    92,     12,      3,      0,      0, }, /* 411 */
+  {    92,     10,      5,      0,      0, }, /* 412 */
+  {    92,     21,     12,      0,      0, }, /* 413 */
+  {    69,      7,     12,      0,      0, }, /* 414 */
+  {    69,     10,      5,      0,      0, }, /* 415 */
+  {    69,     12,      3,      0,      0, }, /* 416 */
+  {    69,     21,     12,      0,      0, }, /* 417 */
+  {    69,     13,     12,      0,      0, }, /* 418 */
+  {    72,     13,     12,      0,      0, }, /* 419 */
+  {    72,      7,     12,      0,      0, }, /* 420 */
+  {    72,      6,     12,      0,      0, }, /* 421 */
+  {    72,     21,     12,      0,      0, }, /* 422 */
+  {    12,      5,     12,     63,  -6222, }, /* 423 */
+  {    12,      5,     12,     67,  -6221, }, /* 424 */
+  {    12,      5,     12,     71,  -6212, }, /* 425 */
+  {    12,      5,     12,     75,  -6210, }, /* 426 */
+  {    12,      5,     12,     79,  -6210, }, /* 427 */
+  {    12,      5,     12,     79,  -6211, }, /* 428 */
+  {    12,      5,     12,     84,  -6204, }, /* 429 */
+  {    12,      5,     12,     88,  -6180, }, /* 430 */
+  {    12,      5,     12,    108,  35267, }, /* 431 */
+  {    75,     21,     12,      0,      0, }, /* 432 */
+  {     9,     10,      5,      0,      0, }, /* 433 */
+  {     9,      7,     12,      0,      0, }, /* 434 */
+  {    12,      5,     12,      0,      0, }, /* 435 */
+  {    12,      6,     12,      0,      0, }, /* 436 */
+  {    33,      5,     12,      0,  35332, }, /* 437 */
+  {    33,      5,     12,      0,   3814, }, /* 438 */
+  {    33,      9,     12,     92,      1, }, /* 439 */
+  {    33,      5,     12,     92,     -1, }, /* 440 */
+  {    33,      5,     12,     92,    -58, }, /* 441 */
+  {    33,      9,     12,      0,  -7615, }, /* 442 */
+  {    19,      5,     12,      0,      8, }, /* 443 */
+  {    19,      9,     12,      0,     -8, }, /* 444 */
+  {    19,      5,     12,      0,     74, }, /* 445 */
+  {    19,      5,     12,      0,     86, }, /* 446 */
+  {    19,      5,     12,      0,    100, }, /* 447 */
+  {    19,      5,     12,      0,    128, }, /* 448 */
+  {    19,      5,     12,      0,    112, }, /* 449 */
+  {    19,      5,     12,      0,    126, }, /* 450 */
+  {    19,      8,     12,      0,     -8, }, /* 451 */
+  {    19,      5,     12,      0,      9, }, /* 452 */
+  {    19,      9,     12,      0,    -74, }, /* 453 */
+  {    19,      8,     12,      0,     -9, }, /* 454 */
+  {    19,      5,     12,     21,  -7173, }, /* 455 */
+  {    19,      9,     12,      0,    -86, }, /* 456 */
+  {    19,      9,     12,      0,   -100, }, /* 457 */
+  {    19,      9,     12,      0,   -112, }, /* 458 */
+  {    19,      9,     12,      0,   -128, }, /* 459 */
+  {    19,      9,     12,      0,   -126, }, /* 460 */
+  {    27,      1,      3,      0,      0, }, /* 461 */
+  {    27,      1,     16,      0,      0, }, /* 462 */
+  {     9,     27,      2,      0,      0, }, /* 463 */
+  {     9,     28,      2,      0,      0, }, /* 464 */
+  {     9,      2,      2,      0,      0, }, /* 465 */
+  {     9,      9,     12,      0,      0, }, /* 466 */
+  {     9,      5,     12,      0,      0, }, /* 467 */
+  {    19,      9,     12,     96,  -7517, }, /* 468 */
+  {    33,      9,     12,    100,  -8383, }, /* 469 */
+  {    33,      9,     12,    104,  -8262, }, /* 470 */
+  {    33,      9,     12,      0,     28, }, /* 471 */
+  {    33,      5,     12,      0,    -28, }, /* 472 */
+  {    33,     14,     12,      0,     16, }, /* 473 */
+  {    33,     14,     12,      0,    -16, }, /* 474 */
+  {    33,     14,     12,      0,      0, }, /* 475 */
+  {     9,     26,     12,      0,     26, }, /* 476 */
+  {     9,     26,     12,      0,    -26, }, /* 477 */
+  {     9,     26,     13,      0,      0, }, /* 478 */
+  {     9,     26,     17,      0,      0, }, /* 479 */
+  {     4,     26,     12,      0,      0, }, /* 480 */
+  {    17,      9,     12,      0,     48, }, /* 481 */
+  {    17,      5,     12,      0,    -48, }, /* 482 */
+  {    33,      9,     12,      0, -10743, }, /* 483 */
+  {    33,      9,     12,      0,  -3814, }, /* 484 */
+  {    33,      9,     12,      0, -10727, }, /* 485 */
+  {    33,      5,     12,      0, -10795, }, /* 486 */
+  {    33,      5,     12,      0, -10792, }, /* 487 */
+  {    33,      9,     12,      0, -10780, }, /* 488 */
+  {    33,      9,     12,      0, -10749, }, /* 489 */
+  {    33,      9,     12,      0, -10783, }, /* 490 */
+  {    33,      9,     12,      0, -10782, }, /* 491 */
+  {    33,      9,     12,      0, -10815, }, /* 492 */
+  {    10,      5,     12,      0,      0, }, /* 493 */
+  {    10,     26,     12,      0,      0, }, /* 494 */
+  {    10,     12,      3,      0,      0, }, /* 495 */
+  {    10,     21,     12,      0,      0, }, /* 496 */
+  {    10,     15,     12,      0,      0, }, /* 497 */
+  {    16,      5,     12,      0,  -7264, }, /* 498 */
+  {    58,      7,     12,      0,      0, }, /* 499 */
+  {    58,      6,     12,      0,      0, }, /* 500 */
+  {    58,     21,     12,      0,      0, }, /* 501 */
+  {    58,     12,      3,      0,      0, }, /* 502 */
+  {    22,     26,     12,      0,      0, }, /* 503 */
+  {    22,      6,     12,      0,      0, }, /* 504 */
+  {    22,     14,     12,      0,      0, }, /* 505 */
+  {    23,     10,      3,      0,      0, }, /* 506 */
+  {    26,      7,     12,      0,      0, }, /* 507 */
+  {    26,      6,     12,      0,      0, }, /* 508 */
+  {    29,      7,     12,      0,      0, }, /* 509 */
+  {    29,      6,     12,      0,      0, }, /* 510 */
+  {     3,      7,     12,      0,      0, }, /* 511 */
+  {    23,      7,     12,      0,      0, }, /* 512 */
+  {    23,     26,     12,      0,      0, }, /* 513 */
+  {    29,     26,     12,      0,      0, }, /* 514 */
+  {    22,      7,     12,      0,      0, }, /* 515 */
+  {    60,      7,     12,      0,      0, }, /* 516 */
+  {    60,      6,     12,      0,      0, }, /* 517 */
+  {    60,     26,     12,      0,      0, }, /* 518 */
+  {    85,      7,     12,      0,      0, }, /* 519 */
+  {    85,      6,     12,      0,      0, }, /* 520 */
+  {    85,     21,     12,      0,      0, }, /* 521 */
+  {    76,      7,     12,      0,      0, }, /* 522 */
+  {    76,      6,     12,      0,      0, }, /* 523 */
+  {    76,     21,     12,      0,      0, }, /* 524 */
+  {    76,     13,     12,      0,      0, }, /* 525 */
+  {    12,      9,     12,    108,      1, }, /* 526 */
+  {    12,      5,     12,    108, -35267, }, /* 527 */
+  {    12,      7,     12,      0,      0, }, /* 528 */
+  {    12,     21,     12,      0,      0, }, /* 529 */
+  {    78,      7,     12,      0,      0, }, /* 530 */
+  {    78,     14,     12,      0,      0, }, /* 531 */
+  {    78,     12,      3,      0,      0, }, /* 532 */
+  {    78,     21,     12,      0,      0, }, /* 533 */
+  {    33,      9,     12,      0, -35332, }, /* 534 */
+  {    33,      9,     12,      0, -42280, }, /* 535 */
+  {    33,      9,     12,      0, -42308, }, /* 536 */
+  {    33,      9,     12,      0, -42319, }, /* 537 */
+  {    33,      9,     12,      0, -42315, }, /* 538 */
+  {    33,      9,     12,      0, -42305, }, /* 539 */
+  {    33,      9,     12,      0, -42258, }, /* 540 */
+  {    33,      9,     12,      0, -42282, }, /* 541 */
+  {    33,      9,     12,      0, -42261, }, /* 542 */
+  {    33,      9,     12,      0,    928, }, /* 543 */
+  {    48,      7,     12,      0,      0, }, /* 544 */
+  {    48,     12,      3,      0,      0, }, /* 545 */
+  {    48,     10,      5,      0,      0, }, /* 546 */
+  {    48,     26,     12,      0,      0, }, /* 547 */
+  {    64,      7,     12,      0,      0, }, /* 548 */
+  {    64,     21,     12,      0,      0, }, /* 549 */
+  {    74,     10,      5,      0,      0, }, /* 550 */
+  {    74,      7,     12,      0,      0, }, /* 551 */
+  {    74,     12,      3,      0,      0, }, /* 552 */
+  {    74,     21,     12,      0,      0, }, /* 553 */
+  {    74,     13,     12,      0,      0, }, /* 554 */
+  {    68,     13,     12,      0,      0, }, /* 555 */
+  {    68,      7,     12,      0,      0, }, /* 556 */
+  {    68,     12,      3,      0,      0, }, /* 557 */
+  {    68,     21,     12,      0,      0, }, /* 558 */
+  {    73,      7,     12,      0,      0, }, /* 559 */
+  {    73,     12,      3,      0,      0, }, /* 560 */
+  {    73,     10,      5,      0,      0, }, /* 561 */
+  {    73,     21,     12,      0,      0, }, /* 562 */
+  {    83,     12,      3,      0,      0, }, /* 563 */
+  {    83,     10,      5,      0,      0, }, /* 564 */
+  {    83,      7,     12,      0,      0, }, /* 565 */
+  {    83,     21,     12,      0,      0, }, /* 566 */
+  {    83,     13,     12,      0,      0, }, /* 567 */
+  {    38,      6,     12,      0,      0, }, /* 568 */
+  {    67,      7,     12,      0,      0, }, /* 569 */
+  {    67,     12,      3,      0,      0, }, /* 570 */
+  {    67,     10,      5,      0,      0, }, /* 571 */
+  {    67,     13,     12,      0,      0, }, /* 572 */
+  {    67,     21,     12,      0,      0, }, /* 573 */
+  {    91,      7,     12,      0,      0, }, /* 574 */
+  {    91,     12,      3,      0,      0, }, /* 575 */
+  {    91,      6,     12,      0,      0, }, /* 576 */
+  {    91,     21,     12,      0,      0, }, /* 577 */
+  {    86,      7,     12,      0,      0, }, /* 578 */
+  {    86,     10,      5,      0,      0, }, /* 579 */
+  {    86,     12,      3,      0,      0, }, /* 580 */
+  {    86,     21,     12,      0,      0, }, /* 581 */
+  {    86,      6,     12,      0,      0, }, /* 582 */
+  {    33,      5,     12,      0,   -928, }, /* 583 */
+  {     8,      5,     12,      0, -38864, }, /* 584 */
+  {    86,     13,     12,      0,      0, }, /* 585 */
+  {    23,      7,      9,      0,      0, }, /* 586 */
+  {    23,      7,     10,      0,      0, }, /* 587 */
+  {     9,      4,      2,      0,      0, }, /* 588 */
+  {     9,      3,     12,      0,      0, }, /* 589 */
+  {    25,     25,     12,      0,      0, }, /* 590 */
+  {     0,     24,     12,      0,      0, }, /* 591 */
+  {     9,      6,      3,      0,      0, }, /* 592 */
+  {    35,      7,     12,      0,      0, }, /* 593 */
+  {    19,     14,     12,      0,      0, }, /* 594 */
+  {    19,     15,     12,      0,      0, }, /* 595 */
+  {    19,     26,     12,      0,      0, }, /* 596 */
+  {    70,      7,     12,      0,      0, }, /* 597 */
+  {    66,      7,     12,      0,      0, }, /* 598 */
+  {    41,      7,     12,      0,      0, }, /* 599 */
+  {    41,     15,     12,      0,      0, }, /* 600 */
+  {    18,      7,     12,      0,      0, }, /* 601 */
+  {    18,     14,     12,      0,      0, }, /* 602 */
+  {   117,      7,     12,      0,      0, }, /* 603 */
+  {   117,     12,      3,      0,      0, }, /* 604 */
+  {    59,      7,     12,      0,      0, }, /* 605 */
+  {    59,     21,     12,      0,      0, }, /* 606 */
+  {    42,      7,     12,      0,      0, }, /* 607 */
+  {    42,     21,     12,      0,      0, }, /* 608 */
+  {    42,     14,     12,      0,      0, }, /* 609 */
+  {    13,      9,     12,      0,     40, }, /* 610 */
+  {    13,      5,     12,      0,    -40, }, /* 611 */
+  {    46,      7,     12,      0,      0, }, /* 612 */
+  {    44,      7,     12,      0,      0, }, /* 613 */
+  {    44,     13,     12,      0,      0, }, /* 614 */
+  {   135,      9,     12,      0,     40, }, /* 615 */
+  {   135,      5,     12,      0,    -40, }, /* 616 */
+  {   105,      7,     12,      0,      0, }, /* 617 */
+  {   103,      7,     12,      0,      0, }, /* 618 */
+  {   103,     21,     12,      0,      0, }, /* 619 */
+  {   109,      7,     12,      0,      0, }, /* 620 */
+  {    11,      7,     12,      0,      0, }, /* 621 */
+  {    80,      7,     12,      0,      0, }, /* 622 */
+  {    80,     21,     12,      0,      0, }, /* 623 */
+  {    80,     15,     12,      0,      0, }, /* 624 */
+  {   119,      7,     12,      0,      0, }, /* 625 */
+  {   119,     26,     12,      0,      0, }, /* 626 */
+  {   119,     15,     12,      0,      0, }, /* 627 */
+  {   115,      7,     12,      0,      0, }, /* 628 */
+  {   115,     15,     12,      0,      0, }, /* 629 */
+  {   127,      7,     12,      0,      0, }, /* 630 */
+  {   127,     15,     12,      0,      0, }, /* 631 */
+  {    65,      7,     12,      0,      0, }, /* 632 */
+  {    65,     15,     12,      0,      0, }, /* 633 */
+  {    65,     21,     12,      0,      0, }, /* 634 */
+  {    71,      7,     12,      0,      0, }, /* 635 */
+  {    71,     21,     12,      0,      0, }, /* 636 */
+  {    97,      7,     12,      0,      0, }, /* 637 */
+  {    96,      7,     12,      0,      0, }, /* 638 */
+  {    96,     15,     12,      0,      0, }, /* 639 */
+  {    30,      7,     12,      0,      0, }, /* 640 */
+  {    30,     12,      3,      0,      0, }, /* 641 */
+  {    30,     15,     12,      0,      0, }, /* 642 */
+  {    30,     21,     12,      0,      0, }, /* 643 */
+  {    87,      7,     12,      0,      0, }, /* 644 */
+  {    87,     15,     12,      0,      0, }, /* 645 */
+  {    87,     21,     12,      0,      0, }, /* 646 */
+  {   116,      7,     12,      0,      0, }, /* 647 */
+  {   116,     15,     12,      0,      0, }, /* 648 */
+  {   111,      7,     12,      0,      0, }, /* 649 */
+  {   111,     26,     12,      0,      0, }, /* 650 */
+  {   111,     12,      3,      0,      0, }, /* 651 */
+  {   111,     15,     12,      0,      0, }, /* 652 */
+  {   111,     21,     12,      0,      0, }, /* 653 */
+  {    77,      7,     12,      0,      0, }, /* 654 */
+  {    77,     21,     12,      0,      0, }, /* 655 */
+  {    82,      7,     12,      0,      0, }, /* 656 */
+  {    82,     15,     12,      0,      0, }, /* 657 */
+  {    81,      7,     12,      0,      0, }, /* 658 */
+  {    81,     15,     12,      0,      0, }, /* 659 */
+  {   120,      7,     12,      0,      0, }, /* 660 */
+  {   120,     21,     12,      0,      0, }, /* 661 */
+  {   120,     15,     12,      0,      0, }, /* 662 */
+  {    88,      7,     12,      0,      0, }, /* 663 */
+  {   129,      9,     12,      0,     64, }, /* 664 */
+  {   129,      5,     12,      0,    -64, }, /* 665 */
+  {   129,     15,     12,      0,      0, }, /* 666 */
+  {     0,     15,     12,      0,      0, }, /* 667 */
+  {    93,     10,      5,      0,      0, }, /* 668 */
+  {    93,     12,      3,      0,      0, }, /* 669 */
+  {    93,      7,     12,      0,      0, }, /* 670 */
+  {    93,     21,     12,      0,      0, }, /* 671 */
+  {    93,     15,     12,      0,      0, }, /* 672 */
+  {    93,     13,     12,      0,      0, }, /* 673 */
+  {    84,     12,      3,      0,      0, }, /* 674 */
+  {    84,     10,      5,      0,      0, }, /* 675 */
+  {    84,      7,     12,      0,      0, }, /* 676 */
+  {    84,     21,     12,      0,      0, }, /* 677 */
+  {    84,      1,      4,      0,      0, }, /* 678 */
+  {   100,      7,     12,      0,      0, }, /* 679 */
+  {   100,     13,     12,      0,      0, }, /* 680 */
+  {    95,     12,      3,      0,      0, }, /* 681 */
+  {    95,      7,     12,      0,      0, }, /* 682 */
+  {    95,     10,      5,      0,      0, }, /* 683 */
+  {    95,     13,     12,      0,      0, }, /* 684 */
+  {    95,     21,     12,      0,      0, }, /* 685 */
+  {   110,      7,     12,      0,      0, }, /* 686 */
+  {   110,     12,      3,      0,      0, }, /* 687 */
+  {   110,     21,     12,      0,      0, }, /* 688 */
+  {    99,     12,      3,      0,      0, }, /* 689 */
+  {    99,     10,      5,      0,      0, }, /* 690 */
+  {    99,      7,     12,      0,      0, }, /* 691 */
+  {    99,      7,      4,      0,      0, }, /* 692 */
+  {    99,     21,     12,      0,      0, }, /* 693 */
+  {    99,     13,     12,      0,      0, }, /* 694 */
+  {    47,     15,     12,      0,      0, }, /* 695 */
+  {   107,      7,     12,      0,      0, }, /* 696 */
+  {   107,     10,      5,      0,      0, }, /* 697 */
+  {   107,     12,      3,      0,      0, }, /* 698 */
+  {   107,     21,     12,      0,      0, }, /* 699 */
+  {   128,      7,     12,      0,      0, }, /* 700 */
+  {   128,     21,     12,      0,      0, }, /* 701 */
+  {   108,      7,     12,      0,      0, }, /* 702 */
+  {   108,     12,      3,      0,      0, }, /* 703 */
+  {   108,     10,      5,      0,      0, }, /* 704 */
+  {   108,     13,     12,      0,      0, }, /* 705 */
+  {   106,     12,      3,      0,      0, }, /* 706 */
+  {   106,     10,      5,      0,      0, }, /* 707 */
+  {   106,      7,     12,      0,      0, }, /* 708 */
+  {   106,     10,      3,      0,      0, }, /* 709 */
+  {   134,      7,     12,      0,      0, }, /* 710 */
+  {   134,     10,      5,      0,      0, }, /* 711 */
+  {   134,     12,      3,      0,      0, }, /* 712 */
+  {   134,     21,     12,      0,      0, }, /* 713 */
+  {   134,     13,     12,      0,      0, }, /* 714 */
+  {   123,      7,     12,      0,      0, }, /* 715 */
+  {   123,     10,      3,      0,      0, }, /* 716 */
+  {   123,     10,      5,      0,      0, }, /* 717 */
+  {   123,     12,      3,      0,      0, }, /* 718 */
+  {   123,     21,     12,      0,      0, }, /* 719 */
+  {   123,     13,     12,      0,      0, }, /* 720 */
+  {   122,      7,     12,      0,      0, }, /* 721 */
+  {   122,     10,      3,      0,      0, }, /* 722 */
+  {   122,     10,      5,      0,      0, }, /* 723 */
+  {   122,     12,      3,      0,      0, }, /* 724 */
+  {   122,     21,     12,      0,      0, }, /* 725 */
+  {   113,      7,     12,      0,      0, }, /* 726 */
+  {   113,     10,      5,      0,      0, }, /* 727 */
+  {   113,     12,      3,      0,      0, }, /* 728 */
+  {   113,     21,     12,      0,      0, }, /* 729 */
+  {   113,     13,     12,      0,      0, }, /* 730 */
+  {   101,      7,     12,      0,      0, }, /* 731 */
+  {   101,     12,      3,      0,      0, }, /* 732 */
+  {   101,     10,      5,      0,      0, }, /* 733 */
+  {   101,     13,     12,      0,      0, }, /* 734 */
+  {   125,      7,     12,      0,      0, }, /* 735 */
+  {   125,     12,      3,      0,      0, }, /* 736 */
+  {   125,     10,      5,      0,      0, }, /* 737 */
+  {   125,     13,     12,      0,      0, }, /* 738 */
+  {   125,     15,     12,      0,      0, }, /* 739 */
+  {   125,     21,     12,      0,      0, }, /* 740 */
+  {   125,     26,     12,      0,      0, }, /* 741 */
+  {   124,      9,     12,      0,     32, }, /* 742 */
+  {   124,      5,     12,      0,    -32, }, /* 743 */
+  {   124,     13,     12,      0,      0, }, /* 744 */
+  {   124,     15,     12,      0,      0, }, /* 745 */
+  {   124,      7,     12,      0,      0, }, /* 746 */
+  {   140,      7,     12,      0,      0, }, /* 747 */
+  {   140,     12,      3,      0,      0, }, /* 748 */
+  {   140,     10,      5,      0,      0, }, /* 749 */
+  {   140,      7,      4,      0,      0, }, /* 750 */
+  {   140,     21,     12,      0,      0, }, /* 751 */
+  {   139,      7,     12,      0,      0, }, /* 752 */
+  {   139,     12,      3,      0,      0, }, /* 753 */
+  {   139,     10,      5,      0,      0, }, /* 754 */
+  {   139,      7,      4,      0,      0, }, /* 755 */
+  {   139,     21,     12,      0,      0, }, /* 756 */
+  {   121,      7,     12,      0,      0, }, /* 757 */
+  {   132,      7,     12,      0,      0, }, /* 758 */
+  {   132,     10,      5,      0,      0, }, /* 759 */
+  {   132,     12,      3,      0,      0, }, /* 760 */
+  {   132,     21,     12,      0,      0, }, /* 761 */
+  {   132,     13,     12,      0,      0, }, /* 762 */
+  {   132,     15,     12,      0,      0, }, /* 763 */
+  {   133,     21,     12,      0,      0, }, /* 764 */
+  {   133,      7,     12,      0,      0, }, /* 765 */
+  {   133,     12,      3,      0,      0, }, /* 766 */
+  {   133,     10,      5,      0,      0, }, /* 767 */
+  {   137,      7,     12,      0,      0, }, /* 768 */
+  {   137,     12,      3,      0,      0, }, /* 769 */
+  {   137,      7,      4,      0,      0, }, /* 770 */
+  {   137,     13,     12,      0,      0, }, /* 771 */
+  {    62,      7,     12,      0,      0, }, /* 772 */
+  {    62,     14,     12,      0,      0, }, /* 773 */
+  {    62,     21,     12,      0,      0, }, /* 774 */
+  {    79,      7,     12,      0,      0, }, /* 775 */
+  {   126,      7,     12,      0,      0, }, /* 776 */
+  {   114,      7,     12,      0,      0, }, /* 777 */
+  {   114,     13,     12,      0,      0, }, /* 778 */
+  {   114,     21,     12,      0,      0, }, /* 779 */
+  {   102,      7,     12,      0,      0, }, /* 780 */
+  {   102,     12,      3,      0,      0, }, /* 781 */
+  {   102,     21,     12,      0,      0, }, /* 782 */
+  {   118,      7,     12,      0,      0, }, /* 783 */
+  {   118,     12,      3,      0,      0, }, /* 784 */
+  {   118,     21,     12,      0,      0, }, /* 785 */
+  {   118,     26,     12,      0,      0, }, /* 786 */
+  {   118,      6,     12,      0,      0, }, /* 787 */
+  {   118,     13,     12,      0,      0, }, /* 788 */
+  {   118,     15,     12,      0,      0, }, /* 789 */
+  {    98,      7,     12,      0,      0, }, /* 790 */
+  {    98,     10,      5,      0,      0, }, /* 791 */
+  {    98,     12,      3,      0,      0, }, /* 792 */
+  {    98,      6,     12,      0,      0, }, /* 793 */
+  {   136,      6,     12,      0,      0, }, /* 794 */
+  {   138,      6,     12,      0,      0, }, /* 795 */
+  {   136,      7,     12,      0,      0, }, /* 796 */
+  {   138,      7,     12,      0,      0, }, /* 797 */
+  {   104,      7,     12,      0,      0, }, /* 798 */
+  {   104,     26,     12,      0,      0, }, /* 799 */
+  {   104,     12,      3,      0,      0, }, /* 800 */
+  {   104,     21,     12,      0,      0, }, /* 801 */
+  {     9,     10,      3,      0,      0, }, /* 802 */
+  {    19,     12,      3,      0,      0, }, /* 803 */
+  {   130,     26,     12,      0,      0, }, /* 804 */
+  {   130,     12,      3,      0,      0, }, /* 805 */
+  {   130,     21,     12,      0,      0, }, /* 806 */
+  {    17,     12,      3,      0,      0, }, /* 807 */
+  {   112,      7,     12,      0,      0, }, /* 808 */
+  {   112,     15,     12,      0,      0, }, /* 809 */
+  {   112,     12,      3,      0,      0, }, /* 810 */
+  {   131,      9,     12,      0,     34, }, /* 811 */
+  {   131,      5,     12,      0,    -34, }, /* 812 */
+  {   131,     12,      3,      0,      0, }, /* 813 */
+  {   131,     13,     12,      0,      0, }, /* 814 */
+  {   131,     21,     12,      0,      0, }, /* 815 */
+  {     9,     26,     11,      0,      0, }, /* 816 */
+  {    26,     26,     12,      0,      0, }, /* 817 */
+  {     9,     24,     14,      0,      0, }, /* 818 */
+  {     9,     26,     15,      0,      0, }, /* 819 */
+  {     9,      1,      3,      0,      0, }, /* 820 */
 };
 
 const uint8_t PRIV(ucd_stage1)[] = { /* 8704 bytes */
@@ -834,549 +933,549 @@
  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */
  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 41, 42, 43, 44, 45, /* U+1000 */
  46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, /* U+1800 */
- 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 71, 72, 73, 71, 74, 75, /* U+2000 */
- 76, 76, 66, 77, 66, 66, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, /* U+2800 */
- 88, 89, 90, 91, 92, 93, 94, 71, 95, 95, 95, 95, 95, 95, 95, 95, /* U+3000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+3800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+4000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 95, 95, 95, 95, /* U+4800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+5000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+5800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+6000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+6800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+7000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+7800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+8000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+8800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+9000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 97, /* U+9800 */
- 98, 99, 99, 99, 99, 99, 99, 99, 99,100,101,101,102,103,104,105, /* U+A000 */
-106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,114, /* U+A800 */
-115,116,117,118,119,120,114,115,116,117,118,119,120,114,115,116, /* U+B000 */
-117,118,119,120,114,115,116,117,118,119,120,114,115,116,117,118, /* U+B800 */
-119,120,114,115,116,117,118,119,120,114,115,116,117,118,119,120, /* U+C000 */
-114,115,116,117,118,119,120,114,115,116,117,118,119,120,114,115, /* U+C800 */
-116,117,118,119,120,114,115,116,117,118,119,120,114,115,116,121, /* U+D000 */
-122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, /* U+D800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+E000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+E800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F000 */
-123,123, 95, 95,124,125,126,127,128,128,129,130,131,132,133,134, /* U+F800 */
-135,136,137,138,139,140,141,142,143,144,145,139,146,146,147,139, /* U+10000 */
-148,149,150,151,152,153,154,155,156,157,139,139,158,139,139,139, /* U+10800 */
-159,160,161,162,163,164,165,139,139,166,139,167,168,169,170,139, /* U+11000 */
-139,171,139,139,139,172,139,139,139,139,139,139,139,139,139,139, /* U+11800 */
-173,173,173,173,173,173,173,174,175,173,176,139,139,139,139,139, /* U+12000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+12800 */
-177,177,177,177,177,177,177,177,178,139,139,139,139,139,139,139, /* U+13000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+13800 */
-139,139,139,139,139,139,139,139,179,179,179,179,180,139,139,139, /* U+14000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+14800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+15000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+15800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+16000 */
-181,181,181,181,182,183,184,185,139,139,139,139,139,139,186,187, /* U+16800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+17000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+17800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+18000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+18800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+19000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+19800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1A800 */
-188,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1B000 */
-139,139,139,139,139,139,139,139,189,190,139,139,139,139,139,139, /* U+1B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1C800 */
- 71,191,192,193,194,139,195,139,196,197,198,199,200,201,202,203, /* U+1D000 */
-204,204,204,204,205,206,139,139,139,139,139,139,139,139,139,139, /* U+1D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1E000 */
-207,208,139,139,139,139,139,139,139,139,139,139,209,210,139,139, /* U+1E800 */
-211,212,213,214,215,139, 71,216, 71, 71,217,218, 71,219,220,221, /* U+1F000 */
-222,223,224,225,139,139,139,139,139,139,139,139,139,139,139,139, /* U+1F800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+20000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+20800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+21000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+21800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+22000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+22800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+23000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+23800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+24000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+24800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+25000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+25800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+26000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+26800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+27000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+27800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+28000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+28800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+29000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+29800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,226, 95, 95, /* U+2A000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+2A800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,227, 95, /* U+2B000 */
-228, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+2B800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+2C000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,229,139,139, /* U+2C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+2F000 */
- 95, 95, 95, 95,230,139,139,139,139,139,139,139,139,139,139,139, /* U+2F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+30000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+30800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+31000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+31800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+32000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+32800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+33000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+33800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+34000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+34800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+35000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+35800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+36000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+36800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+37000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+37800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+38000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+38800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+39000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+39800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3A800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3B000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3F000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+3F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+40000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+40800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+41000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+41800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+42000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+42800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+43000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+43800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+44000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+44800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+45000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+45800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+46000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+46800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+47000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+47800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+48000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+48800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+49000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+49800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4A800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4B000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4F000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+4F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+50000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+50800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+51000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+51800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+52000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+52800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+53000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+53800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+54000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+54800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+55000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+55800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+56000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+56800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+57000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+57800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+58000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+58800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+59000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+59800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5A800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5B000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5F000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+5F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+60000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+60800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+61000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+61800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+62000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+62800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+63000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+63800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+64000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+64800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+65000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+65800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+66000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+66800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+67000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+67800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+68000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+68800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+69000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+69800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6A800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6B000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6F000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+6F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+70000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+70800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+71000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+71800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+72000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+72800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+73000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+73800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+74000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+74800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+75000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+75800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+76000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+76800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+77000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+77800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+78000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+78800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+79000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+79800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7A800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7B000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7F000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+7F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+80000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+80800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+81000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+81800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+82000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+82800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+83000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+83800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+84000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+84800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+85000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+85800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+86000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+86800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+87000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+87800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+88000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+88800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+89000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+89800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8A800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8B000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8F000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+8F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+90000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+90800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+91000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+91800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+92000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+92800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+93000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+93800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+94000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+94800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+95000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+95800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+96000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+96800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+97000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+97800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+98000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+98800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+99000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+99800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9A000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9A800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9B000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9B800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9C000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9C800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9D000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9D800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9E000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9E800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9F000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+9F800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A0000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A0800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A1000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A1800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A2000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A2800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A3000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A3800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A4000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A4800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A5000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A5800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A6000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A6800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A7000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A7800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A8000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A8800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A9000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+A9800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AA000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AA800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AB000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AB800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AC000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AC800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AD000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AD800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AE000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AE800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AF000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+AF800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B0000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B0800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B1000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B1800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B2000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B2800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B3000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B3800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B4000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B4800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B5000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B5800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B6000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B6800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B7000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B7800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B8000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B8800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B9000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+B9800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BA000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BA800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BB000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BB800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BC000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BC800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BD000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BD800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BE000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BE800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BF000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+BF800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C0000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C0800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C1000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C1800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C2000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C2800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C3000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C3800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C4000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C4800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C5000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C5800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C6000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C6800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C7000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C7800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C8000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C8800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C9000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+C9800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CA000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CA800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CB000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CB800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CC000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CC800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CD000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CD800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CE000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CE800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CF000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+CF800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D0000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D0800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D1000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D1800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D2000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D2800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D3000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D3800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D4000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D4800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D5000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D5800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D6000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D6800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D7000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D7800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D8000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D8800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D9000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+D9800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DA000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DA800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DB000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DB800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DC000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DC800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DD000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DD800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DE000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DE800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DF000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+DF800 */
-231,232,233,234,232,232,232,232,232,232,232,232,232,232,232,232, /* U+E0000 */
-232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, /* U+E0800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E1000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E1800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E2000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E2800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E3000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E3800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E4000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E4800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E5000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E5800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E6000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E6800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E7000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E7800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E8000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E8800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E9000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+E9800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EA000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EA800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EB000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EB800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EC000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EC800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+ED000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+ED800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EE000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EE800 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EF000 */
-139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, /* U+EF800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F0000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F0800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F1000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F1800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F2000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F2800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F3000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F3800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F4000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F4800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F5000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F5800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F6000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F6800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F7000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F7800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F8000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F8800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F9000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F9800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FA000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FA800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FB000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FB800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FC000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FC800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FD000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FD800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FE000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FE800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FF000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,235, /* U+FF800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+100000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+100800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+101000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+101800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+102000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+102800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+103000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+103800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+104000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+104800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+105000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+105800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+106000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+106800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+107000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+107800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+108000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+108800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+109000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+109800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10A000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10A800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10B000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10B800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10C000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10C800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10D000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10D800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10E000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10E800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10F000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,235, /* U+10F800 */
+ 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, /* U+2000 */
+ 77, 77, 66, 78, 66, 66, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, /* U+2800 */
+ 89, 90, 91, 92, 93, 94, 95, 71, 96, 96, 96, 96, 96, 96, 96, 96, /* U+3000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+3800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+4000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 96, 96, 96, 96, /* U+4800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+5000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+5800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+6000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+6800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+7000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+7800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+8000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+8800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+9000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 98, /* U+9800 */
+ 99,100,100,100,100,100,100,100,100,101,102,102,103,104,105,106, /* U+A000 */
+107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,115, /* U+A800 */
+116,117,118,119,120,121,115,116,117,118,119,120,121,115,116,117, /* U+B000 */
+118,119,120,121,115,116,117,118,119,120,121,115,116,117,118,119, /* U+B800 */
+120,121,115,116,117,118,119,120,121,115,116,117,118,119,120,121, /* U+C000 */
+115,116,117,118,119,120,121,115,116,117,118,119,120,121,115,116, /* U+C800 */
+117,118,119,120,121,115,116,117,118,119,120,121,115,116,117,122, /* U+D000 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+D800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+E000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+E800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F000 */
+124,124, 96, 96,125,126,127,128,129,129,130,131,132,133,134,135, /* U+F800 */
+136,137,138,139,140,141,142,143,144,145,146,140,147,147,148,140, /* U+10000 */
+149,150,151,152,153,154,155,156,157,158,140,140,159,140,140,140, /* U+10800 */
+160,161,162,163,164,165,166,140,167,168,140,169,170,171,172,140, /* U+11000 */
+140,173,140,140,174,175,140,140,176,177,178,140,140,140,140,140, /* U+11800 */
+179,179,179,179,179,179,179,180,181,179,182,140,140,140,140,140, /* U+12000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+12800 */
+183,183,183,183,183,183,183,183,184,140,140,140,140,140,140,140, /* U+13000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+13800 */
+140,140,140,140,140,140,140,140,185,185,185,185,186,140,140,140, /* U+14000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+14800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+15000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+15800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+16000 */
+187,187,187,187,188,189,190,191,140,140,140,140,140,140,192,193, /* U+16800 */
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, /* U+17000 */
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, /* U+17800 */
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,195, /* U+18000 */
+194,194,194,194,194,196,140,140,140,140,140,140,140,140,140,140, /* U+18800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+19000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+19800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+1A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+1A800 */
+197,198,199,200,200,201,140,140,140,140,140,140,140,140,140,140, /* U+1B000 */
+140,140,140,140,140,140,140,140,202,203,140,140,140,140,140,140, /* U+1B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+1C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+1C800 */
+ 71,204,205,206,207,140,208,140,209,210,211,212,213,214,215,216, /* U+1D000 */
+217,217,217,217,218,219,140,140,140,140,140,140,140,140,140,140, /* U+1D800 */
+220,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+1E000 */
+221,222,223,140,140,140,140,140,140,140,140,140,224,225,140,140, /* U+1E800 */
+226,227,228,229,230,140,231,232,233,234,235,236,237,238,239,240, /* U+1F000 */
+241,242,243,244,140,140,140,140,140,140,140,140,140,140,140,140, /* U+1F800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+20000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+20800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+21000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+21800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+22000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+22800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+23000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+23800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+24000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+24800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+25000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+25800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+26000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+26800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+27000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+27800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+28000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+28800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+29000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+29800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,245, 96, 96, /* U+2A000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+2A800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,246, 96, /* U+2B000 */
+247, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+2B800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+2C000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,248, 96, 96, /* U+2C800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+2D000 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+2D800 */
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, /* U+2E000 */
+ 96, 96, 96, 96, 96, 96, 96,249,140,140,140,140,140,140,140,140, /* U+2E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+2F000 */
+ 96, 96, 96, 96,250,140,140,140,140,140,140,140,140,140,140,140, /* U+2F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+30000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+30800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+31000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+31800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+32000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+32800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+33000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+33800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+34000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+34800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+35000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+35800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+36000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+36800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+37000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+37800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+38000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+38800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+39000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+39800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3A800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3B000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3C800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3D000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3D800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3E000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3F000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+3F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+40000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+40800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+41000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+41800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+42000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+42800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+43000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+43800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+44000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+44800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+45000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+45800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+46000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+46800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+47000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+47800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+48000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+48800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+49000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+49800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4A800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4B000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4C800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4D000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4D800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4E000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4F000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+4F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+50000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+50800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+51000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+51800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+52000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+52800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+53000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+53800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+54000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+54800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+55000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+55800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+56000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+56800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+57000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+57800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+58000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+58800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+59000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+59800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5A800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5B000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5C800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5D000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5D800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5E000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5F000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+5F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+60000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+60800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+61000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+61800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+62000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+62800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+63000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+63800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+64000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+64800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+65000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+65800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+66000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+66800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+67000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+67800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+68000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+68800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+69000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+69800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6A800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6B000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6C800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6D000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6D800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6E000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6F000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+6F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+70000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+70800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+71000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+71800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+72000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+72800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+73000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+73800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+74000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+74800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+75000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+75800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+76000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+76800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+77000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+77800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+78000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+78800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+79000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+79800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7A800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7B000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7C800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7D000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7D800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7E000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7F000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+7F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+80000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+80800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+81000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+81800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+82000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+82800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+83000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+83800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+84000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+84800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+85000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+85800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+86000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+86800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+87000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+87800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+88000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+88800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+89000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+89800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8A800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8B000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8C800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8D000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8D800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8E000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8F000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+8F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+90000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+90800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+91000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+91800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+92000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+92800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+93000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+93800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+94000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+94800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+95000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+95800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+96000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+96800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+97000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+97800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+98000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+98800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+99000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+99800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9A000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9A800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9B000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9B800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9C000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9C800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9D000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9D800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9E000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9E800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9F000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+9F800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A0000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A0800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A1000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A1800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A2000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A2800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A3000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A3800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A4000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A4800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A5000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A5800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A6000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A6800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A7000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A7800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A8000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A8800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A9000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+A9800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AA000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AA800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AB000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AB800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AC000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AC800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AD000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AD800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AE000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AE800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AF000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+AF800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B0000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B0800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B1000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B1800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B2000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B2800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B3000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B3800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B4000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B4800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B5000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B5800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B6000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B6800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B7000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B7800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B8000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B8800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B9000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+B9800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BA000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BA800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BB000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BB800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BC000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BC800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BD000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BD800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BE000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BE800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BF000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+BF800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C0000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C0800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C1000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C1800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C2000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C2800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C3000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C3800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C4000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C4800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C5000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C5800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C6000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C6800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C7000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C7800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C8000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C8800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C9000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+C9800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CA000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CA800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CB000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CB800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CC000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CC800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CD000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CD800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CE000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CE800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CF000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+CF800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D0000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D0800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D1000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D1800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D2000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D2800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D3000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D3800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D4000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D4800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D5000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D5800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D6000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D6800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D7000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D7800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D8000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D8800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D9000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+D9800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DA000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DA800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DB000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DB800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DC000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DC800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DD000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DD800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DE000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DE800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DF000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+DF800 */
+251,252,253,254,252,252,252,252,252,252,252,252,252,252,252,252, /* U+E0000 */
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, /* U+E0800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E1000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E1800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E2000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E2800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E3000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E3800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E4000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E4800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E5000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E5800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E6000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E6800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E7000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E7800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E8000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E8800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E9000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+E9800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EA000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EA800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EB000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EB800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EC000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EC800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+ED000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+ED800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EE000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EE800 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EF000 */
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, /* U+EF800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F0000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F0800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F1000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F1800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F2000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F2800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F3000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F3800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F4000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F4800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F5000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F5800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F6000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F6800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F7000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F7800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F8000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F8800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F9000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+F9800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FA000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FA800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FB000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FB800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FC000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FC800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FD000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FD800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FE000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FE800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+FF000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,255, /* U+FF800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+100000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+100800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+101000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+101800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+102000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+102800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+103000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+103800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+104000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+104800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+105000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+105800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+106000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+106800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+107000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+107800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+108000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+108800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+109000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+109800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10A000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10A800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10B000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10B800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10C000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10C800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10D000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10D800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10E000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10E800 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+10F000 */
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,255, /* U+10F800 */
 };
 
-const uint16_t PRIV(ucd_stage2)[] = { /* 60416 bytes, block = 128 */
+const uint16_t PRIV(ucd_stage2)[] = { /* 65536 bytes, block = 128 */
 /* block 0 */
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  2,  0,  0,
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
@@ -1424,7 +1523,7 @@
  30, 31, 30, 31, 33, 33, 33, 33, 33, 33, 71, 30, 31, 72, 73, 74,
  74, 30, 31, 75, 76, 77, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  78, 79, 80, 81, 82, 33, 83, 83, 33, 84, 33, 85, 86, 33, 33, 33,
- 83, 87, 33, 88, 33, 89, 90, 33, 91, 92, 33, 93, 94, 33, 33, 92,
+ 83, 87, 33, 88, 33, 89, 90, 33, 91, 92, 90, 93, 94, 33, 33, 92,
  33, 95, 96, 33, 33, 97, 33, 33, 33, 33, 33, 33, 33, 98, 33, 33,
 
 /* block 5 */
@@ -1459,493 +1558,493 @@
 
 /* block 8 */
 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
-172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
-172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
-173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
-173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
-174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+172,172,173,172,174,172,172,172,172,172,172,172,172,172,175,172,
+172,176,177,172,172,172,172,172,172,172,178,172,172,172,172,172,
+179,179,180,179,181,179,179,179,179,179,179,179,179,179,182,179,
+179,183,184,179,179,179,179,179,179,179,185,179,179,179,179,179,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+187,188,189,190,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
 
 /* block 9 */
-175,176,177,178,178,110,110,178,179,179,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-180,175,176,175,176,175,176,175,176,175,176,175,176,175,176,181,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
+187,188,191,192,192,110,110,192,193,193,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+194,187,188,187,188,187,188,187,188,187,188,187,188,187,188,195,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
 
 /* block 10 */
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-115,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-182,182,182,182,182,182,182,115,115,183,184,184,184,184,184,184,
-115,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
-185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+115,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,115,115,197,198,198,198,198,198,198,
+115,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
 
 /* block 11 */
-185,185,185,185,185,185,185,186,115,  4,187,115,115,188,188,189,
-115,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
-190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
-190,190,190,190,190,190,190,190,190,190,190,190,190,190,191,190,
-192,190,190,192,190,190,192,190,115,115,115,115,115,115,115,115,
-193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
-193,193,193,193,193,193,193,193,193,193,193,115,115,115,115,115,
-193,193,193,192,192,115,115,115,115,115,115,115,115,115,115,115,
+199,199,199,199,199,199,199,200,115,  4,201,115,115,202,202,203,
+115,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,205,204,
+206,204,204,206,204,204,206,204,115,115,115,115,115,115,115,115,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,115,115,115,115,115,
+207,207,207,206,206,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 12 */
-194,194,194,194,194, 22,195,195,195,196,196,197,  4,196,198,198,
-199,199,199,199,199,199,199,199,199,199,199,  4, 22,115,196,  4,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-108,200,200,200,200,200,200,200,200,200,200,110,110,110,110,110,
-110,110,110,110,110,110,199,199,199,199,199,199,199,199,199,199,
-201,201,201,201,201,201,201,201,201,201,196,196,196,196,200,200,
-110,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+208,208,208,208,208,209,210,210,210,211,211,212,  4,211,213,213,
+214,214,214,214,214,214,214,214,214,214,214,  4,215,115,211,  4,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+108,216,216,216,216,216,216,216,216,216,216,110,110,110,110,110,
+110,110,110,110,110,110,214,214,214,214,214,214,214,214,214,214,
+217,217,217,217,217,217,217,217,217,217,211,211,211,211,216,216,
+110,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
 
 /* block 13 */
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,196,200,199,199,199,199,199,199,199, 22,198,199,
-199,199,199,199,199,202,202,199,199,198,199,199,199,199,200,200,
-201,201,201,201,201,201,201,201,201,201,200,200,200,198,198,200,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,211,216,214,214,214,214,214,214,214,209,213,214,
+214,214,214,214,214,218,218,214,214,213,214,214,214,214,216,216,
+217,217,217,217,217,217,217,217,217,217,216,216,216,213,213,216,
 
 /* block 14 */
-203,203,203,203,203,203,203,203,203,203,203,203,203,203,115,204,
-205,206,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
-205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
-206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
-206,206,206,206,206,206,206,206,206,206,206,115,115,205,205,205,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,115,220,
+221,222,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,115,115,221,221,221,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
 
 /* block 15 */
-207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
-207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
-207,207,207,207,207,207,208,208,208,208,208,208,208,208,208,208,
-208,207,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-209,209,209,209,209,209,209,209,209,209,210,210,210,210,210,210,
-210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
-210,210,210,210,210,210,210,210,210,210,210,211,211,211,211,211,
-211,211,211,211,212,212,213,214,214,214,212,115,115,115,115,115,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,224,224,224,224,224,224,224,224,224,224,
+224,223,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+225,225,225,225,225,225,225,225,225,225,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,227,227,227,227,227,
+227,227,227,227,228,228,229,230,230,230,228,115,115,115,115,115,
 
 /* block 16 */
-215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
-215,215,215,215,215,215,216,216,216,216,217,216,216,216,216,216,
-216,216,216,216,217,216,216,216,217,216,216,216,216,216,115,115,
-218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,115,
-219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
-219,219,219,219,219,219,219,219,219,220,220,220,115,115,221,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,232,232,232,232,233,232,232,232,232,232,
+232,232,232,232,233,232,232,232,233,232,232,232,232,232,115,115,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,115,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,236,236,236,115,115,237,115,
+221,221,221,221,221,221,221,221,221,221,221,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 17 */
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,115,115,115,115,115,115,115,115,115,115,115,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,115,216,216,216,216,216,216,216,216,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,199,199,199,199,199,199,199,199,199,199,199,199,199,
-199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+115,115,115,115,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,209,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
 
 /* block 18 */
-222,222,222,223,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,222,223,222,224,223,223,
-223,222,222,222,222,222,222,222,222,223,223,223,223,222,223,223,
-224,110,110,222,222,222,222,222,224,224,224,224,224,224,224,224,
-224,224,222,222,  4,  4,225,225,225,225,225,225,225,225,225,225,
-226,227,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+238,238,238,239,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,238,239,238,240,239,239,
+239,238,238,238,238,238,238,238,238,239,239,239,239,238,239,239,
+240,110,110,238,238,238,238,238,240,240,240,240,240,240,240,240,
+240,240,238,238,  4,  4,241,241,241,241,241,241,241,241,241,241,
+242,243,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
 
 /* block 19 */
-228,229,230,230,115,228,228,228,228,228,228,228,228,115,115,228,
-228,115,115,228,228,228,228,228,228,228,228,228,228,228,228,228,
-228,228,228,228,228,228,228,228,228,115,228,228,228,228,228,228,
-228,115,228,115,115,115,228,228,228,228,115,115,229,228,231,230,
-230,229,229,229,229,115,115,230,230,115,115,230,230,229,228,115,
-115,115,115,115,115,115,115,231,115,115,115,115,228,228,115,228,
-228,228,229,229,115,115,232,232,232,232,232,232,232,232,232,232,
-228,228,233,233,234,234,234,234,234,234,235,233,115,115,115,115,
+244,245,246,246,115,244,244,244,244,244,244,244,244,115,115,244,
+244,115,115,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,115,244,244,244,244,244,244,
+244,115,244,115,115,115,244,244,244,244,115,115,245,244,247,246,
+246,245,245,245,245,115,115,246,246,115,115,246,246,245,244,115,
+115,115,115,115,115,115,115,247,115,115,115,115,244,244,115,244,
+244,244,245,245,115,115,248,248,248,248,248,248,248,248,248,248,
+244,244,249,249,250,250,250,250,250,250,251,249,244,252,115,115,
 
 /* block 20 */
-115,236,236,237,115,238,238,238,238,238,238,115,115,115,115,238,
-238,115,115,238,238,238,238,238,238,238,238,238,238,238,238,238,
-238,238,238,238,238,238,238,238,238,115,238,238,238,238,238,238,
-238,115,238,238,115,238,238,115,238,238,115,115,236,115,237,237,
-237,236,236,115,115,115,115,236,236,115,115,236,236,236,115,115,
-115,236,115,115,115,115,115,115,115,238,238,238,238,115,238,115,
-115,115,115,115,115,115,239,239,239,239,239,239,239,239,239,239,
-236,236,238,238,238,236,115,115,115,115,115,115,115,115,115,115,
+115,253,253,254,115,255,255,255,255,255,255,115,115,115,115,255,
+255,115,115,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,115,255,255,255,255,255,255,
+255,115,255,255,115,255,255,115,255,255,115,115,253,115,254,254,
+254,253,253,115,115,115,115,253,253,115,115,253,253,253,115,115,
+115,253,115,115,115,115,115,115,115,255,255,255,255,115,255,115,
+115,115,115,115,115,115,256,256,256,256,256,256,256,256,256,256,
+253,253,255,255,255,253,115,115,115,115,115,115,115,115,115,115,
 
 /* block 21 */
-115,240,240,241,115,242,242,242,242,242,242,242,242,242,115,242,
-242,242,115,242,242,242,242,242,242,242,242,242,242,242,242,242,
-242,242,242,242,242,242,242,242,242,115,242,242,242,242,242,242,
-242,115,242,242,115,242,242,242,242,242,115,115,240,242,241,241,
-241,240,240,240,240,240,115,240,240,241,115,241,241,240,115,115,
-242,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-242,242,240,240,115,115,243,243,243,243,243,243,243,243,243,243,
-244,245,115,115,115,115,115,115,115,242,115,115,115,115,115,115,
+115,257,257,258,115,259,259,259,259,259,259,259,259,259,115,259,
+259,259,115,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,115,259,259,259,259,259,259,
+259,115,259,259,115,259,259,259,259,259,115,115,257,259,258,258,
+258,257,257,257,257,257,115,257,257,258,115,258,258,257,115,115,
+259,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+259,259,257,257,115,115,260,260,260,260,260,260,260,260,260,260,
+261,262,115,115,115,115,115,115,115,259,257,257,257,257,257,257,
 
 /* block 22 */
-115,246,247,247,115,248,248,248,248,248,248,248,248,115,115,248,
-248,115,115,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,115,248,248,248,248,248,248,
-248,115,248,248,115,248,248,248,248,248,115,115,246,248,249,246,
-247,246,246,246,246,115,115,247,247,115,115,247,247,246,115,115,
-115,115,115,115,115,115,246,249,115,115,115,115,248,248,115,248,
-248,248,246,246,115,115,250,250,250,250,250,250,250,250,250,250,
-251,248,252,252,252,252,252,252,115,115,115,115,115,115,115,115,
+115,263,264,264,115,265,265,265,265,265,265,265,265,115,115,265,
+265,115,115,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,115,265,265,265,265,265,265,
+265,115,265,265,115,265,265,265,265,265,115,115,263,265,266,263,
+264,263,263,263,263,115,115,264,264,115,115,264,264,263,115,115,
+115,115,115,115,115,115,263,266,115,115,115,115,265,265,115,265,
+265,265,263,263,115,115,267,267,267,267,267,267,267,267,267,267,
+268,265,269,269,269,269,269,269,115,115,115,115,115,115,115,115,
 
 /* block 23 */
-115,115,253,254,115,254,254,254,254,254,254,115,115,115,254,254,
-254,115,254,254,254,254,115,115,115,254,254,115,254,115,254,254,
-115,115,115,254,254,115,115,115,254,254,254,115,115,115,254,254,
-254,254,254,254,254,254,254,254,254,254,115,115,115,115,255,256,
-253,256,256,115,115,115,256,256,256,115,256,256,256,253,115,115,
-254,115,115,115,115,115,115,255,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,257,257,257,257,257,257,257,257,257,257,
-258,258,258,259,259,259,259,259,259,260,259,115,115,115,115,115,
+115,115,270,271,115,271,271,271,271,271,271,115,115,115,271,271,
+271,115,271,271,271,271,115,115,115,271,271,115,271,115,271,271,
+115,115,115,271,271,115,115,115,271,271,271,115,115,115,271,271,
+271,271,271,271,271,271,271,271,271,271,115,115,115,115,272,273,
+270,273,273,115,115,115,273,273,273,115,273,273,273,270,115,115,
+271,115,115,115,115,115,115,272,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,274,274,274,274,274,274,274,274,274,274,
+275,275,275,276,276,276,276,276,276,277,276,115,115,115,115,115,
 
 /* block 24 */
-261,262,262,262,115,263,263,263,263,263,263,263,263,115,263,263,
-263,115,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
-263,263,263,263,263,263,263,263,263,115,263,263,263,263,263,263,
-263,263,263,263,263,263,263,263,263,263,115,115,115,263,261,261,
-261,262,262,262,262,115,261,261,261,115,261,261,261,261,115,115,
-115,115,115,115,115,261,261,115,263,263,263,115,115,115,115,115,
-263,263,261,261,115,115,264,264,264,264,264,264,264,264,264,264,
-115,115,115,115,115,115,115,115,265,265,265,265,265,265,265,266,
+278,279,279,279,115,280,280,280,280,280,280,280,280,115,280,280,
+280,115,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
+280,280,280,280,280,280,280,280,280,115,280,280,280,280,280,280,
+280,280,280,280,280,280,280,280,280,280,115,115,115,280,278,278,
+278,279,279,279,279,115,278,278,278,115,278,278,278,278,115,115,
+115,115,115,115,115,278,278,115,280,280,280,115,115,115,115,115,
+280,280,278,278,115,115,281,281,281,281,281,281,281,281,281,281,
+115,115,115,115,115,115,115,115,282,282,282,282,282,282,282,283,
 
 /* block 25 */
-115,267,268,268,115,269,269,269,269,269,269,269,269,115,269,269,
-269,115,269,269,269,269,269,269,269,269,269,269,269,269,269,269,
-269,269,269,269,269,269,269,269,269,115,269,269,269,269,269,269,
-269,269,269,269,115,269,269,269,269,269,115,115,267,269,268,267,
-268,268,270,268,268,115,267,268,268,115,268,268,267,267,115,115,
-115,115,115,115,115,270,270,115,115,115,115,115,115,115,269,115,
-269,269,267,267,115,115,271,271,271,271,271,271,271,271,271,271,
-115,269,269,115,115,115,115,115,115,115,115,115,115,115,115,115,
+284,285,286,286,115,284,284,284,284,284,284,284,284,115,284,284,
+284,115,284,284,284,284,284,284,284,284,284,284,284,284,284,284,
+284,284,284,284,284,284,284,284,284,115,284,284,284,284,284,284,
+284,284,284,284,115,284,284,284,284,284,115,115,285,284,286,285,
+286,286,287,286,286,115,285,286,286,115,286,286,285,285,115,115,
+115,115,115,115,115,287,287,115,115,115,115,115,115,115,284,115,
+284,284,285,285,115,115,288,288,288,288,288,288,288,288,288,288,
+115,284,284,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 26 */
-115,272,273,273,115,274,274,274,274,274,274,274,274,115,274,274,
-274,115,274,274,274,274,274,274,274,274,274,274,274,274,274,274,
-274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,274,
-274,274,274,274,274,274,274,274,274,274,274,115,115,274,275,273,
-273,272,272,272,272,115,273,273,273,115,273,273,273,272,274,115,
-115,115,115,115,115,115,115,275,115,115,115,115,115,115,115,274,
-274,274,272,272,115,115,276,276,276,276,276,276,276,276,276,276,
-277,277,277,277,277,277,115,115,115,278,274,274,274,274,274,274,
+289,289,290,290,115,291,291,291,291,291,291,291,291,115,291,291,
+291,115,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,291,291,291,291,291,291,291,291,291,291,289,289,291,292,290,
+290,289,289,289,289,115,290,290,290,115,290,290,290,289,293,294,
+115,115,115,115,291,291,291,292,295,295,295,295,295,295,295,291,
+291,291,289,289,115,115,296,296,296,296,296,296,296,296,296,296,
+295,295,295,295,295,295,295,295,295,294,291,291,291,291,291,291,
 
 /* block 27 */
-115,115,279,279,115,280,280,280,280,280,280,280,280,280,280,280,
-280,280,280,280,280,280,280,115,115,115,280,280,280,280,280,280,
-280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
-280,280,115,280,280,280,280,280,280,280,280,280,115,280,115,115,
-280,280,280,280,280,280,280,115,115,115,281,115,115,115,115,282,
-279,279,281,281,281,115,281,115,279,279,279,279,279,279,279,282,
-115,115,115,115,115,115,283,283,283,283,283,283,283,283,283,283,
-115,115,279,279,284,115,115,115,115,115,115,115,115,115,115,115,
+115,115,297,297,115,298,298,298,298,298,298,298,298,298,298,298,
+298,298,298,298,298,298,298,115,115,115,298,298,298,298,298,298,
+298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,
+298,298,115,298,298,298,298,298,298,298,298,298,115,298,115,115,
+298,298,298,298,298,298,298,115,115,115,299,115,115,115,115,300,
+297,297,299,299,299,115,299,115,297,297,297,297,297,297,297,300,
+115,115,115,115,115,115,301,301,301,301,301,301,301,301,301,301,
+115,115,297,297,302,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 28 */
-115,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,286,285,287,286,286,286,286,286,286,286,115,115,115,115,  5,
-285,285,285,285,285,285,288,286,286,286,286,286,286,286,286,289,
-290,290,290,290,290,290,290,290,290,290,289,289,115,115,115,115,
+115,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
+303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
+303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
+303,304,303,305,304,304,304,304,304,304,304,115,115,115,115,  5,
+303,303,303,303,303,303,306,304,304,304,304,304,304,304,304,307,
+308,308,308,308,308,308,308,308,308,308,307,307,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 29 */
-115,291,291,115,291,115,115,291,291,115,291,115,115,291,115,115,
-115,115,115,115,291,291,291,291,115,291,291,291,291,291,291,291,
-115,291,291,291,115,291,115,291,115,115,291,291,115,291,291,291,
-291,292,291,293,292,292,292,292,292,292,115,292,292,291,115,115,
-291,291,291,291,291,115,294,115,292,292,292,292,292,292,115,115,
-295,295,295,295,295,295,295,295,295,295,115,115,291,291,291,291,
+115,309,309,115,309,115,115,309,309,115,309,115,115,309,115,115,
+115,115,115,115,309,309,309,309,115,309,309,309,309,309,309,309,
+115,309,309,309,115,309,115,309,115,115,309,309,115,309,309,309,
+309,310,309,311,310,310,310,310,310,310,115,310,310,309,115,115,
+309,309,309,309,309,115,312,115,310,310,310,310,310,310,115,115,
+313,313,313,313,313,313,313,313,313,313,115,115,309,309,309,309,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 30 */
-296,297,297,297,298,298,298,298,298,298,298,298,298,298,298,298,
-298,298,298,297,298,297,297,297,299,299,297,297,297,297,297,297,
-300,300,300,300,300,300,300,300,300,300,301,301,301,301,301,301,
-301,301,301,301,297,299,297,299,297,299,302,303,302,303,304,304,
-296,296,296,296,296,296,296,296,115,296,296,296,296,296,296,296,
-296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,
-296,296,296,296,296,296,296,296,296,296,296,296,296,115,115,115,
-115,299,299,299,299,299,299,299,299,299,299,299,299,299,299,304,
+314,315,315,315,316,316,316,316,316,316,316,316,316,316,316,316,
+316,316,316,315,316,315,315,315,317,317,315,315,315,315,315,315,
+318,318,318,318,318,318,318,318,318,318,319,319,319,319,319,319,
+319,319,319,319,315,317,315,317,315,317,320,321,320,321,322,322,
+314,314,314,314,314,314,314,314,115,314,314,314,314,314,314,314,
+314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,314,
+314,314,314,314,314,314,314,314,314,314,314,314,314,115,115,115,
+115,317,317,317,317,317,317,317,317,317,317,317,317,317,317,322,
 
 /* block 31 */
-299,299,299,299,299,298,299,299,296,296,296,296,296,299,299,299,
-299,299,299,299,299,299,299,299,115,299,299,299,299,299,299,299,
-299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
-299,299,299,299,299,299,299,299,299,299,299,299,299,115,297,297,
-297,297,297,297,297,297,299,297,297,297,297,297,297,115,297,297,
-298,298,298,298,298, 19, 19, 19, 19,298,298,115,115,115,115,115,
+317,317,317,317,317,316,317,317,314,314,314,314,314,317,317,317,
+317,317,317,317,317,317,317,317,115,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+317,317,317,317,317,317,317,317,317,317,317,317,317,115,315,315,
+315,315,315,315,315,315,317,315,315,315,315,315,315,115,315,315,
+316,316,316,316,316, 19, 19, 19, 19,316,316,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 32 */
-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,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,305,305,306,306,307,307,307,
-307,308,307,307,307,307,307,307,306,307,307,308,308,307,307,305,
-309,309,309,309,309,309,309,309,309,309,310,310,310,310,310,310,
-305,305,305,305,305,305,308,308,307,307,305,305,305,305,307,307,
-307,305,306,306,306,305,305,306,306,306,306,306,306,306,305,305,
-305,307,307,307,307,305,305,305,305,305,305,305,305,305,305,305,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+323,323,323,323,323,323,323,323,323,323,323,324,324,325,325,325,
+325,326,325,325,325,325,325,325,324,325,325,326,326,325,325,323,
+327,327,327,327,327,327,327,327,327,327,328,328,328,328,328,328,
+323,323,323,323,323,323,326,326,325,325,323,323,323,323,325,325,
+325,323,324,324,324,323,323,324,324,324,324,324,324,324,323,323,
+323,325,325,325,325,323,323,323,323,323,323,323,323,323,323,323,
 
 /* block 33 */
-305,305,307,306,308,307,307,306,306,306,306,306,306,307,305,306,
-309,309,309,309,309,309,309,309,309,309,306,306,306,307,311,311,
-312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,
-312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,
-312,312,312,312,312,312,115,312,115,115,115,115,115,312,115,115,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,  4,314,313,313,313,
+323,323,325,324,326,325,325,324,324,324,324,324,324,325,323,324,
+327,327,327,327,327,327,327,327,327,327,324,324,324,325,329,329,
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,330,330,115,330,115,115,115,115,115,330,115,115,
+331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
+331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
+331,331,331,331,331,331,331,331,331,331,331,  4,332,331,331,331,
 
 /* block 34 */
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
-316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,
+334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,
 
 /* block 35 */
-316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
-316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
-316,316,316,316,316,316,316,316,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
+334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,
+334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,
+334,334,334,334,334,334,334,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,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,
 
 /* block 36 */
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,115,318,318,318,318,115,115,
-318,318,318,318,318,318,318,115,318,115,318,318,318,318,115,115,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,115,336,336,336,336,115,115,
+336,336,336,336,336,336,336,115,336,115,336,336,336,336,115,115,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
 
 /* block 37 */
-318,318,318,318,318,318,318,318,318,115,318,318,318,318,115,115,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,115,318,318,318,318,115,115,318,318,318,318,318,318,318,115,
-318,115,318,318,318,318,115,115,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+336,336,336,336,336,336,336,336,336,115,336,336,336,336,115,115,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,115,336,336,336,336,115,115,336,336,336,336,336,336,336,115,
+336,115,336,336,336,336,115,115,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,115,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
 
 /* block 38 */
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,115,318,318,318,318,115,115,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,115,115,319,319,319,
-320,320,320,320,320,320,320,320,320,321,321,321,321,321,321,321,
-321,321,321,321,321,321,321,321,321,321,321,321,321,115,115,115,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,115,336,336,336,336,115,115,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,115,115,337,337,337,
+338,338,338,338,338,338,338,338,338,339,339,339,339,339,339,339,
+339,339,339,339,339,339,339,339,339,339,339,339,339,115,115,115,
 
 /* block 39 */
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-322,322,322,322,322,322,322,322,322,322,115,115,115,115,115,115,
-323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-324,324,324,324,324,324,115,115,325,325,325,325,325,325,115,115,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+340,340,340,340,340,340,340,340,340,340,115,115,115,115,115,115,
+341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
+341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
+341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
+341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
+341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
+342,342,342,342,342,342,115,115,343,343,343,343,343,343,115,115,
 
 /* block 40 */
-326,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+344,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
 
 /* block 41 */
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
 
 /* block 42 */
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,328,328,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,346,346,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
 
 /* block 43 */
-329,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
-330,330,330,330,330,330,330,330,330,330,330,331,332,115,115,115,
-333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
-333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
-333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
-333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
-333,333,333,333,333,333,333,333,333,333,333,  4,  4,  4,334,334,
-334,333,333,333,333,333,333,333,333,115,115,115,115,115,115,115,
+347,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,
+348,348,348,348,348,348,348,348,348,348,348,349,350,115,115,115,
+351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,
+351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,
+351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,
+351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,
+351,351,351,351,351,351,351,351,351,351,351,  4,  4,  4,352,352,
+352,351,351,351,351,351,351,351,351,115,115,115,115,115,115,115,
 
 /* block 44 */
-335,335,335,335,335,335,335,335,335,335,335,335,335,115,335,335,
-335,335,336,336,336,115,115,115,115,115,115,115,115,115,115,115,
-337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,
-337,337,338,338,338,  4,  4,115,115,115,115,115,115,115,115,115,
-339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
-339,339,340,340,115,115,115,115,115,115,115,115,115,115,115,115,
-341,341,341,341,341,341,341,341,341,341,341,341,341,115,341,341,
-341,115,342,342,115,115,115,115,115,115,115,115,115,115,115,115,
+353,353,353,353,353,353,353,353,353,353,353,353,353,115,353,353,
+353,353,354,354,354,115,115,115,115,115,115,115,115,115,115,115,
+355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
+355,355,356,356,356,  4,  4,115,115,115,115,115,115,115,115,115,
+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
+357,357,358,358,115,115,115,115,115,115,115,115,115,115,115,115,
+359,359,359,359,359,359,359,359,359,359,359,359,359,115,359,359,
+359,115,360,360,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 45 */
-343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
-343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
-343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
-343,343,343,343,344,344,345,344,344,344,344,344,344,344,345,345,
-345,345,345,345,345,345,344,345,345,344,344,344,344,344,344,344,
-344,344,344,344,346,346,346,347,346,346,346,348,343,344,115,115,
-349,349,349,349,349,349,349,349,349,349,115,115,115,115,115,115,
-350,350,350,350,350,350,350,350,350,350,115,115,115,115,115,115,
+361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,
+361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,
+361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,
+361,361,361,361,362,362,363,362,362,362,362,362,362,362,363,363,
+363,363,363,363,363,363,362,363,363,362,362,362,362,362,362,362,
+362,362,362,362,364,364,364,365,364,364,364,366,361,362,115,115,
+367,367,367,367,367,367,367,367,367,367,115,115,115,115,115,115,
+368,368,368,368,368,368,368,368,368,368,115,115,115,115,115,115,
 
 /* block 46 */
-351,351,  4,  4,351,  4,352,351,351,351,351,353,353,353,354,115,
-355,355,355,355,355,355,355,355,355,355,115,115,115,115,115,115,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,357,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,115,115,115,115,115,115,115,115,
+369,369,  4,  4,369,  4,370,369,369,369,369,371,371,371,372,115,
+373,373,373,373,373,373,373,373,373,373,115,115,115,115,115,115,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,375,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,115,115,115,115,115,115,115,115,
 
 /* block 47 */
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,356,353,356,115,115,115,115,115,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,327,327,327,327,115,115,115,115,115,115,115,115,115,115,
+374,374,374,374,374,371,371,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,371,374,115,115,115,115,115,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,115,115,115,115,115,115,115,115,115,115,
 
 /* block 48 */
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,115,
-359,359,359,360,360,360,360,359,359,360,360,360,115,115,115,115,
-360,360,359,360,360,360,360,360,360,359,359,359,115,115,115,115,
-361,115,115,115,362,362,363,363,363,363,363,363,363,363,363,363,
-364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
-364,364,364,364,364,364,364,364,364,364,364,364,364,364,115,115,
-364,364,364,364,364,115,115,115,115,115,115,115,115,115,115,115,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,115,
+377,377,377,378,378,378,378,377,377,378,378,378,115,115,115,115,
+378,378,377,378,378,378,378,378,378,377,377,377,115,115,115,115,
+379,115,115,115,380,380,381,381,381,381,381,381,381,381,381,381,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,115,115,
+382,382,382,382,382,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 49 */
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-365,365,365,365,365,365,365,365,365,365,365,365,115,115,115,115,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-365,365,365,365,365,365,365,365,365,365,115,115,115,115,115,115,
-366,366,366,366,366,366,366,366,366,366,367,115,115,115,368,368,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,115,115,115,115,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,115,115,115,115,115,115,
+384,384,384,384,384,384,384,384,384,384,385,115,115,115,386,386,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
 
 /* block 50 */
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,371,371,372,372,371,115,115,373,373,
-374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
-374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
-374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
-374,374,374,374,374,375,376,375,376,376,376,376,376,376,376,115,
-376,377,376,377,377,376,376,376,376,376,376,376,376,375,375,375,
-375,375,375,376,376,376,376,376,376,376,376,376,376,115,115,376,
+388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,
+388,388,388,388,388,388,388,389,389,390,390,389,115,115,391,391,
+392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
+392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
+392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
+392,392,392,392,392,393,394,393,394,394,394,394,394,394,394,115,
+394,395,394,395,395,394,394,394,394,394,394,394,394,393,393,393,
+393,393,393,394,394,394,394,394,394,394,394,394,394,115,115,394,
 
 /* block 51 */
-378,378,378,378,378,378,378,378,378,378,115,115,115,115,115,115,
-378,378,378,378,378,378,378,378,378,378,115,115,115,115,115,115,
-379,379,379,379,379,379,379,380,379,379,379,379,379,379,115,115,
-110,110,110,110,110,110,110,110,110,110,110,110,110,110,381,115,
+396,396,396,396,396,396,396,396,396,396,115,115,115,115,115,115,
+396,396,396,396,396,396,396,396,396,396,115,115,115,115,115,115,
+397,397,397,397,397,397,397,398,397,397,397,397,397,397,115,115,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,399,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 52 */
-382,382,382,382,383,384,384,384,384,384,384,384,384,384,384,384,
-384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
-384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
-384,384,384,384,382,383,382,382,382,382,382,383,382,383,383,383,
-383,383,382,383,383,384,384,384,384,384,384,384,115,115,115,115,
-385,385,385,385,385,385,385,385,385,385,386,386,386,386,386,386,
-386,387,387,387,387,387,387,387,387,387,387,382,382,382,382,382,
-382,382,382,382,387,387,387,387,387,387,387,387,387,115,115,115,
+400,400,400,400,401,402,402,402,402,402,402,402,402,402,402,402,
+402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
+402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
+402,402,402,402,400,401,400,400,400,400,400,401,400,401,401,401,
+401,401,400,401,401,402,402,402,402,402,402,402,115,115,115,115,
+403,403,403,403,403,403,403,403,403,403,404,404,404,404,404,404,
+404,405,405,405,405,405,405,405,405,405,405,400,400,400,400,400,
+400,400,400,400,405,405,405,405,405,405,405,405,405,115,115,115,
 
 /* block 53 */
-388,388,389,390,390,390,390,390,390,390,390,390,390,390,390,390,
-390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,
-390,389,388,388,388,388,389,389,388,388,389,388,388,388,390,390,
-391,391,391,391,391,391,391,391,391,391,390,390,390,390,390,390,
-392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
-392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,
-392,392,392,392,392,392,393,394,393,393,394,394,394,393,394,393,
-393,393,394,394,115,115,115,115,115,115,115,115,395,395,395,395,
+406,406,407,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,407,406,406,406,406,407,407,406,406,407,406,406,406,408,408,
+409,409,409,409,409,409,409,409,409,409,408,408,408,408,408,408,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,411,412,411,411,412,412,412,411,412,411,
+411,411,412,412,115,115,115,115,115,115,115,115,413,413,413,413,
 
 /* block 54 */
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,397,397,397,397,397,397,397,397,398,398,398,398,
-398,398,398,398,397,397,398,398,115,115,115,399,399,399,399,399,
-400,400,400,400,400,400,400,400,400,400,115,115,115,396,396,396,
-401,401,401,401,401,401,401,401,401,401,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,403,403,403,403,403,403,404,404,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,415,415,415,415,415,415,415,415,416,416,416,416,
+416,416,416,416,415,415,416,416,115,115,115,417,417,417,417,417,
+418,418,418,418,418,418,418,418,418,418,115,115,115,414,414,414,
+419,419,419,419,419,419,419,419,419,419,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,421,421,421,421,421,421,422,422,
 
 /* block 55 */
+423,424,425,426,427,428,429,430,431,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-405,405,405,405,405,405,405,405,115,115,115,115,115,115,115,115,
+432,432,432,432,432,432,432,432,115,115,115,115,115,115,115,115,
 110,110,110,  4,110,110,110,110,110,110,110,110,110,110,110,110,
-110,406,110,110,110,110,110,110,110,407,407,407,407,110,407,407,
-407,407,406,406,110,407,407,115,110,110,115,115,115,115,115,115,
+110,433,110,110,110,110,110,110,110,434,434,434,434,110,434,434,
+434,434,433,433,110,434,434,433,110,110,115,115,115,115,115,115,
 
 /* block 56 */
  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33,123,123,123,123,123,408,107,107,107,107,
+ 33, 33, 33, 33, 33, 33,123,123,123,123,123,435,107,107,107,107,
 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
 107,107,107,107,107,107,107,107,107,107,107,107,107,116,116,116,
 116,116,107,107,107,107,116,116,116,116,116, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33,409,410, 33, 33, 33,411, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33,436,437, 33, 33, 33,438, 33, 33,
 
 /* block 57 */
  33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
@@ -1955,7 +2054,7 @@
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
-110,110,110,110,110,110,115,115,115,115,115,115,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,115,110,110,110,110,110,
 
 /* block 58 */
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
@@ -1964,12 +2063,12 @@
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
-412,413, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
+439,440, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
 
 /* block 59 */
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 33, 33, 33, 33, 33,414, 33, 33,415, 33,
+ 30, 31, 30, 31, 30, 31, 33, 33, 33, 33, 33,441, 33, 33,442, 33,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
@@ -1978,57 +2077,57 @@
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
 
 /* block 60 */
-416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
-416,416,416,416,416,416,115,115,417,417,417,417,417,417,115,115,
-416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
-416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
-416,416,416,416,416,416,115,115,417,417,417,417,417,417,115,115,
-123,416,123,416,123,416,123,416,115,417,115,417,115,417,115,417,
-416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,
-418,418,419,419,419,419,420,420,421,421,422,422,423,423,115,115,
+443,443,443,443,443,443,443,443,444,444,444,444,444,444,444,444,
+443,443,443,443,443,443,115,115,444,444,444,444,444,444,115,115,
+443,443,443,443,443,443,443,443,444,444,444,444,444,444,444,444,
+443,443,443,443,443,443,443,443,444,444,444,444,444,444,444,444,
+443,443,443,443,443,443,115,115,444,444,444,444,444,444,115,115,
+123,443,123,443,123,443,123,443,115,444,115,444,115,444,115,444,
+443,443,443,443,443,443,443,443,444,444,444,444,444,444,444,444,
+445,445,446,446,446,446,447,447,448,448,449,449,450,450,115,115,
 
 /* block 61 */
-416,416,416,416,416,416,416,416,424,424,424,424,424,424,424,424,
-416,416,416,416,416,416,416,416,424,424,424,424,424,424,424,424,
-416,416,416,416,416,416,416,416,424,424,424,424,424,424,424,424,
-416,416,123,425,123,115,123,123,417,417,426,426,427,114,428,114,
-114,114,123,425,123,115,123,123,429,429,429,429,427,114,114,114,
-416,416,123,123,115,115,123,123,417,417,430,430,115,114,114,114,
-416,416,123,123,123,164,123,123,417,417,431,431,169,114,114,114,
-115,115,123,425,123,115,123,123,432,432,433,433,427,114,114,115,
+443,443,443,443,443,443,443,443,451,451,451,451,451,451,451,451,
+443,443,443,443,443,443,443,443,451,451,451,451,451,451,451,451,
+443,443,443,443,443,443,443,443,451,451,451,451,451,451,451,451,
+443,443,123,452,123,115,123,123,444,444,453,453,454,114,455,114,
+114,114,123,452,123,115,123,123,456,456,456,456,454,114,114,114,
+443,443,123,123,115,115,123,123,444,444,457,457,115,114,114,114,
+443,443,123,123,123,164,123,123,444,444,458,458,169,114,114,114,
+115,115,123,452,123,115,123,123,459,459,460,460,454,114,114,115,
 
 /* block 62 */
-  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3, 22,434,434, 22, 22,
+  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3, 22,461,462, 22, 22,
   9,  9,  9,  9,  9,  9,  4,  4, 21, 25,  6, 21, 21, 25,  6, 21,
-  4,  4,  4,  4,  4,  4,  4,  4,435,436, 22, 22, 22, 22, 22,  3,
+  4,  4,  4,  4,  4,  4,  4,  4,463,464, 22, 22, 22, 22, 22,  3,
   4,  4,  4,  4,  4,  4,  4,  4,  4, 21, 25,  4,  4,  4,  4, 15,
  15,  4,  4,  4,  8,  6,  7,  4,  4,  4,  4,  4,  4,  4,  4,  4,
   4,  4,  8,  4, 15,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  3,
- 22, 22, 22, 22, 22,437, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22,465, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
  23,107,115,115, 23, 23, 23, 23, 23, 23,  8,  8,  8,  6,  7,107,
 
 /* block 63 */
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  8,  8,  8,  6,  7,115,
 107,107,107,107,107,107,107,107,107,107,107,107,107,115,115,115,
   5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
-  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,115,
+  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-110,110,110,110,110,110,110,110,110,110,110,110,110,381,381,381,
-381,110,381,381,381,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,399,399,399,
+399,110,399,399,399,110,110,110,110,110,110,110,110,110,110,110,
 110,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 64 */
- 19, 19,438, 19, 19, 19, 19,438, 19, 19,439,438,438,438,439,439,
-438,438,438,439, 19,438, 19, 19,  8,438,438,438,438,438, 19, 19,
- 19, 19, 19, 19,438, 19,440, 19,438, 19,441,442,438,438, 19,439,
-438,438,443,438,439,407,407,407,407,439, 19, 19,439,439,438,438,
-  8,  8,  8,  8,  8,438,439,439,439,439, 19,  8, 19, 19,444, 19,
+ 19, 19,466, 19, 19, 19, 19,466, 19, 19,467,466,466,466,467,467,
+466,466,466,467, 19,466, 19, 19,  8,466,466,466,466,466, 19, 19,
+ 19, 19, 19, 19,466, 19,468, 19,466, 19,469,470,466,466, 19,467,
+466,466,471,466,467,434,434,434,434,467, 19, 19,467,467,466,466,
+  8,  8,  8,  8,  8,466,467,467,467,467, 19,  8, 19, 19,472, 19,
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,
-446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,
+473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
 
 /* block 65 */
-447,447,447, 30, 31,447,447,447,447, 23, 19, 19,115,115,115,115,
+475,475,475, 30, 31,475,475,475,475, 23, 19, 19,115,115,115,115,
   8,  8,  8,  8,  8, 19, 19, 19, 19, 19,  8,  8, 19, 19, 19, 19,
   8, 19, 19,  8, 19, 19,  8, 19, 19, 19, 19, 19, 19, 19,  8, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -2065,7 +2164,7 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  8,  8,  8,  8,
   8,  8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
 /* block 69 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -2081,10 +2180,10 @@
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19,448,448,448,448,448,448,448,448,448,448,
-448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,
-449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,
-449,449,449,449,449,449,449,449,449,449, 23, 23, 23, 23, 23, 23,
+ 19, 19, 19, 19, 19, 19,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,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
+477,477,477,477,477,477,477,477,477,477, 23, 23, 23, 23, 23, 23,
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
 
 /* block 71 */
@@ -2109,25 +2208,35 @@
 
 /* block 73 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,478, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+479, 19,479, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  8,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
 /* block 74 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19,479,479, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,  6,  7,  6,  7,  6,  7,  6,  7,
-  6,  7,  6,  7,  6,  7, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19,478, 19, 19, 19, 19, 19, 19,
 
 /* block 75 */
+ 19, 19, 19, 19, 19, 19, 19, 19,479, 19,478,478,478,478, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,479, 19, 19, 19,  6,  7,  6,  7,  6,  7,  6,  7,
+  6,  7,  6,  7,  6,  7, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+
+/* block 76 */
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  23, 23, 23, 23, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -2137,17 +2246,17 @@
   8,  8,  8,  8,  8,  8,  6,  7,  6,  7,  6,  7,  6,  7,  6,  7,
   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
 
-/* block 76 */
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
-
 /* block 77 */
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+
+/* block 78 */
   8,  8,  8,  6,  7,  6,  7,  6,  7,  6,  7,  6,  7,  6,  7,  6,
   7,  6,  7,  6,  7,  6,  7,  6,  7,  8,  8,  8,  8,  8,  8,  8,
   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
@@ -2157,7 +2266,7 @@
   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  6,  7,  8,  8,
 
-/* block 78 */
+/* block 79 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -2167,257 +2276,257 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19,115,115, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
-/* block 79 */
+/* block 80 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19,115,115, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19,115, 19, 19, 19, 19, 19, 19,
- 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115, 19, 19, 19, 19,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 80 */
-451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
-451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
-451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,115,
-452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,
-452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,
-452,452,452,452,452,452,452,452,452,452,452,452,452,452,452,115,
- 30, 31,453,454,455,456,457, 30, 31, 30, 31, 30, 31,458,459,460,
-461, 33, 30, 31, 33, 30, 31, 33, 33, 33, 33, 33,107,107,462,462,
-
 /* block 81 */
-160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
-160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
-160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
-160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
-160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
-160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
-160,161,160,161,463,464,464,464,464,464,464,160,161,160,161,465,
-465,465,160,161,115,115,115,115,115,466,466,466,466,467,466,466,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,115,
+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,482,482,482,482,482,482,482,115,
+ 30, 31,483,484,485,486,487, 30, 31, 30, 31, 30, 31,488,489,490,
+491, 33, 30, 31, 33, 30, 31, 33, 33, 33, 33, 33,107,107,492,492,
 
 /* block 82 */
-468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,
-468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,
-468,468,468,468,468,468,115,468,115,115,115,115,115,468,115,115,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,115,115,115,115,115,115,115,470,
-471,115,115,115,115,115,115,115,115,115,115,115,115,115,115,472,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,160,161,160,161,160,161,160,161,160,161,160,161,
+160,161,160,161,493,494,494,494,494,494,494,160,161,160,161,495,
+495,495,160,161,115,115,115,115,115,496,496,496,496,497,496,496,
 
 /* block 83 */
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,115,115,115,115,115,115,115,115,115,
-318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
-318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
-318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
-318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
-178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
-178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+498,498,498,498,498,498,115,498,115,115,115,115,115,498,115,115,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,115,115,115,115,115,115,115,500,
+501,115,115,115,115,115,115,115,115,115,115,115,115,115,115,502,
 
 /* block 84 */
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,115,115,115,115,115,115,115,115,115,
+336,336,336,336,336,336,336,115,336,336,336,336,336,336,336,115,
+336,336,336,336,336,336,336,115,336,336,336,336,336,336,336,115,
+336,336,336,336,336,336,336,115,336,336,336,336,336,336,336,115,
+336,336,336,336,336,336,336,115,336,336,336,336,336,336,336,115,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+
+/* block 85 */
   4,  4, 21, 25, 21, 25,  4,  4,  4, 21, 25,  4, 21, 25,  4,  4,
   4,  4,  4,  4,  4,  4,  4,  9,  4,  4,  9,  4, 21, 25,  4,  4,
  21, 25,  6,  7,  6,  7,  6,  7,  6,  7,  4,  4,  4,  4,  4,108,
   4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  9,  9,  4,  4,  4,  4,
-  9,  4,  6,115,115,115,115,115,115,115,115,115,115,115,115,115,
+  9,  4,  6,  4,  4,  4,  4,  4,  4,  4,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 85 */
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,115,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,115,115,115,115,115,115,115,115,115,115,115,115,
-
 /* block 86 */
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
+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,115,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,503,503,503,503,503,503,503,503,503,503,
+503,503,503,503,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 87 */
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,115,115,115,115,115,115,115,115,115,115,
+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,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,
+
+/* block 88 */
+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,503,503,503,503,503,
+503,503,503,503,503,503,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
 
-/* block 88 */
-  3,  4,  4,  4, 19,474,407,475,  6,  7,  6,  7,  6,  7,  6,  7,
-  6,  7, 19, 19,  6,  7,  6,  7,  6,  7,  6,  7,  9,  6,  7,  7,
- 19,475,475,475,475,475,475,475,475,475,110,110,110,110,476,476,
-  9,108,108,108,108,108, 19, 19,475,475,475,474,407,  4, 19, 19,
-115,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
-477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
-477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
-477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
-
 /* block 89 */
-477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
-477,477,477,477,477,477,477,115,115,110,110, 14, 14,478,478,477,
-  9,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,  4,108,480,480,479,
+  3,  4,  4,  4, 19,504,434,505,  6,  7,  6,  7,  6,  7,  6,  7,
+  6,  7, 19, 19,  6,  7,  6,  7,  6,  7,  6,  7,  9,  6,  7,  7,
+ 19,505,505,505,505,505,505,505,505,505,110,110,110,110,506,506,
+  9,108,108,108,108,108, 19, 19,505,505,505,504,434,  4, 19, 19,
+115,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
 
 /* block 90 */
-115,115,115,115,115,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,115,115,
-115,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,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,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,115,115,110,110, 14, 14,508,508,507,
+  9,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
+509,509,509,509,509,509,509,509,509,509,509,  4,108,510,510,509,
 
 /* block 91 */
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,115,
+115,115,115,115,115,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,115,
+115,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+
+/* block 92 */
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,115,
  19, 19, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,481,481,481,481,115,115,115,115,115,
+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,115,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
-479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
 
-/* block 92 */
-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,115,
+/* block 93 */
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,115,
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 23, 23, 23, 23, 23, 23, 23, 23,
  19, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-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, 19,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 19,
 
-/* block 93 */
+/* block 94 */
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-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,115,
-
-/* block 94 */
-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,484,484,484,484,484,484,484,
-484,484,484,484,484,484,484,484, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,115,
 
 /* block 95 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
 /* block 96 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,115,115,115,115,115,115,115,115,115,115,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
 
 /* block 97 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
 /* block 98 */
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,487,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 99 */
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
-486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,517,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
 
 /* block 100 */
-486,486,486,486,486,486,486,486,486,486,486,486,486,115,115,115,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,115,115,115,115,115,115,115,115,115,
-489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
-489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
-489,489,489,489,489,489,489,489,490,490,490,490,490,490,491,491,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
+516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
 
 /* block 101 */
-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,
-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,
+516,516,516,516,516,516,516,516,516,516,516,516,516,115,115,115,
+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,518,518,518,518,518,518,518,518,518,518,518,518,518,
+518,518,518,518,518,518,518,115,115,115,115,115,115,115,115,115,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,520,520,520,520,520,520,521,521,
 
 /* block 102 */
-492,492,492,492,492,492,492,492,492,492,492,492,493,494,494,494,
-492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
-495,495,495,495,495,495,495,495,495,495,492,492,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,496,178,
-179,179,179,497,178,178,178,178,178,178,178,178,178,178,497,409,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
 
 /* block 103 */
-175,176,175,176,175,176,175,176,175,176,175,176,175,176,175,176,
-175,176,175,176,175,176,175,176,175,176,175,176,409,409,178,178,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,499,499,499,499,499,499,499,499,499,499,
-500,500,501,501,501,501,501,501,115,115,115,115,115,115,115,115,
+522,522,522,522,522,522,522,522,522,522,522,522,523,524,524,524,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+525,525,525,525,525,525,525,525,525,525,522,522,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+187,188,187,188,187,188,187,188,187,188,526,527,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,528,192,
+193,193,193,529,192,192,192,192,192,192,192,192,192,192,529,436,
 
 /* block 104 */
+187,188,187,188,187,188,187,188,187,188,187,188,187,188,187,188,
+187,188,187,188,187,188,187,188,187,188,187,188,436,436,192,192,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,531,531,531,531,531,531,531,531,531,531,
+532,532,533,533,533,533,533,533,115,115,115,115,115,115,115,115,
+
+/* block 105 */
  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
  14, 14, 14, 14, 14, 14, 14,108,108,108,108,108,108,108,108,108,
  14, 14, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
@@ -2425,349 +2534,349 @@
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
  30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
-107, 33, 33, 33, 33, 33, 33, 33, 33, 30, 31, 30, 31,502, 30, 31,
+107, 33, 33, 33, 33, 33, 33, 33, 33, 30, 31, 30, 31,534, 30, 31,
 
-/* block 105 */
- 30, 31, 30, 31, 30, 31, 30, 31,108, 14, 14, 30, 31,503, 33, 20,
+/* block 106 */
+ 30, 31, 30, 31, 30, 31, 30, 31,108, 14, 14, 30, 31,535, 33, 20,
  30, 31, 30, 31, 33, 33, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,504,505,506,507,115,115,
-508,509,510,511, 30, 31, 30, 31,115,115,115,115,115,115,115,115,
+ 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,536,537,538,539,536,115,
+540,541,542,543, 30, 31, 30, 31,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115, 20,107,107, 33, 20, 20, 20, 20, 20,
 
-/* block 106 */
-512,512,513,512,512,512,513,512,512,512,512,513,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,514,514,513,513,514,515,515,515,515,115,115,115,115,
- 23, 23, 23, 23, 23, 23, 19, 19,  5, 19,115,115,115,115,115,115,
-516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
-516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
-516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
-516,516,516,516,517,517,517,517,115,115,115,115,115,115,115,115,
-
 /* block 107 */
-518,518,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
-519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
-519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
-519,519,519,519,518,518,518,518,518,518,518,518,518,518,518,518,
-518,518,518,518,520,115,115,115,115,115,115,115,115,115,521,521,
-522,522,522,522,522,522,522,522,522,522,115,115,115,115,115,115,
-222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
-222,222,224,224,224,224,224,224,226,226,226,224,226,224,115,115,
+544,544,545,544,544,544,545,544,544,544,544,545,544,544,544,544,
+544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
+544,544,544,546,546,545,545,546,547,547,547,547,115,115,115,115,
+ 23, 23, 23, 23, 23, 23, 19, 19,  5, 19,115,115,115,115,115,115,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,549,549,549,549,115,115,115,115,115,115,115,115,
 
 /* block 108 */
-523,523,523,523,523,523,523,523,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,525,525,525,525,525,525,525,525,  4,526,
-527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,
-527,527,527,527,527,527,527,528,528,528,528,528,528,528,528,528,
-528,528,529,529,115,115,115,115,115,115,115,115,115,115,115,530,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,115,115,115,
+550,550,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
+551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
+551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
+551,551,551,551,550,550,550,550,550,550,550,550,550,550,550,550,
+550,550,550,550,552,552,115,115,115,115,115,115,115,115,553,553,
+554,554,554,554,554,554,554,554,554,554,115,115,115,115,115,115,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,240,240,240,240,240,240,242,242,242,240,242,240,115,115,
 
 /* block 109 */
-531,531,531,532,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,531,532,532,531,531,531,531,532,532,531,532,532,532,
-532,534,534,534,534,534,534,534,534,534,534,534,534,534,115,108,
-535,535,535,535,535,535,535,535,535,535,115,115,115,115,534,534,
-305,305,305,305,305,307,536,305,305,305,305,305,305,305,305,305,
-309,309,309,309,309,309,309,309,309,309,305,305,305,305,305,115,
+555,555,555,555,555,555,555,555,555,555,556,556,556,556,556,556,
+556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+556,556,556,556,556,556,557,557,557,557,557,557,557,557,  4,558,
+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,560,560,560,560,560,560,560,
+560,560,561,561,115,115,115,115,115,115,115,115,115,115,115,562,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,115,115,115,
 
 /* block 110 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,538,538,538,538,538,538,539,
-539,538,538,539,539,538,538,115,115,115,115,115,115,115,115,115,
-537,537,537,538,537,537,537,537,537,537,537,537,538,539,115,115,
-540,540,540,540,540,540,540,540,540,540,115,115,541,541,541,541,
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-536,305,305,305,305,305,305,311,311,311,305,306,307,306,305,305,
+563,563,563,564,565,565,565,565,565,565,565,565,565,565,565,565,
+565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,
+565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,
+565,565,565,563,564,564,563,563,563,563,564,564,563,564,564,564,
+564,566,566,566,566,566,566,566,566,566,566,566,566,566,115,108,
+567,567,567,567,567,567,567,567,567,567,115,115,115,115,566,566,
+323,323,323,323,323,325,568,323,323,323,323,323,323,323,323,323,
+327,327,327,327,327,327,327,327,327,327,323,323,323,323,323,115,
 
 /* block 111 */
-542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
-542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
-542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
-543,542,543,543,543,542,542,543,543,542,542,542,542,542,543,543,
-542,543,542,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,542,542,544,545,545,
-546,546,546,546,546,546,546,546,546,546,546,547,548,548,547,547,
-549,549,546,550,550,547,548,115,115,115,115,115,115,115,115,115,
+569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+569,569,569,569,569,569,569,569,569,570,570,570,570,570,570,571,
+571,570,570,571,571,570,570,115,115,115,115,115,115,115,115,115,
+569,569,569,570,569,569,569,569,569,569,569,569,570,571,115,115,
+572,572,572,572,572,572,572,572,572,572,115,115,573,573,573,573,
+323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
+568,323,323,323,323,323,323,329,329,329,323,324,325,324,323,323,
 
 /* block 112 */
-115,318,318,318,318,318,318,115,115,318,318,318,318,318,318,115,
-115,318,318,318,318,318,318,115,115,115,115,115,115,115,115,115,
-318,318,318,318,318,318,318,115,318,318,318,318,318,318,318,115,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33,551, 33, 33, 33, 33, 33, 33, 33, 14,107,107,107,107,
- 33, 33, 33, 33, 33,123,115,115,115,115,115,115,115,115,115,115,
-552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
+574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
+574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
+575,574,575,575,575,574,574,575,575,574,574,574,574,574,575,575,
+574,575,574,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,574,574,576,577,577,
+578,578,578,578,578,578,578,578,578,578,578,579,580,580,579,579,
+581,581,578,582,582,579,580,115,115,115,115,115,115,115,115,115,
 
 /* block 113 */
-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,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,547,547,548,547,547,548,547,547,549,547,548,115,115,
-553,553,553,553,553,553,553,553,553,553,115,115,115,115,115,115,
+115,336,336,336,336,336,336,115,115,336,336,336,336,336,336,115,
+115,336,336,336,336,336,336,115,115,115,115,115,115,115,115,115,
+336,336,336,336,336,336,336,115,336,336,336,336,336,336,336,115,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33,583, 33, 33, 33, 33, 33, 33, 33, 14,107,107,107,107,
+ 33, 33, 33, 33, 33,123,115,115,115,115,115,115,115,115,115,115,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
 
 /* block 114 */
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,579,579,580,579,579,580,579,579,581,579,580,115,115,
+585,585,585,585,585,585,585,585,585,585,115,115,115,115,115,115,
 
 /* block 115 */
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
 
 /* block 116 */
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
 
 /* block 117 */
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
 
 /* block 118 */
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
 
 /* block 119 */
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
 
 /* block 120 */
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-554,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,554,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,554,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
 
 /* block 121 */
-555,555,555,555,555,555,555,555,554,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,115,115,115,115,115,115,115,115,115,115,115,115,
-316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,
-316,316,316,316,316,316,316,115,115,115,115,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,115,115,115,115,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+586,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,586,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,586,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
 
 /* block 122 */
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
-556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,
+587,587,587,587,587,587,587,587,586,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,115,115,115,115,115,115,115,115,115,115,115,115,
+334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,
+334,334,334,334,334,334,334,115,115,115,115,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,115,115,115,115,
 
 /* block 123 */
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+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,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,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,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,588,588,588,588,588,588,588,588,
 
 /* block 124 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,115,115,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
 
 /* block 125 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,115,115,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
 
 /* block 126 */
- 33, 33, 33, 33, 33, 33, 33,115,115,115,115,115,115,115,115,115,
-115,115,115,186,186,186,186,186,115,115,115,115,115,193,190,193,
-193,193,193,193,193,193,193,193,193,558,193,193,193,193,193,193,
-193,193,193,193,193,193,193,115,193,193,193,193,193,115,193,115,
-193,193,115,193,193,115,193,193,193,193,193,193,193,193,193,193,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 127 */
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
-559,559,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+ 33, 33, 33, 33, 33, 33, 33,115,115,115,115,115,115,115,115,115,
+115,115,115,200,200,200,200,200,115,115,115,115,115,207,204,207,
+207,207,207,207,207,207,207,207,207,590,207,207,207,207,207,207,
+207,207,207,207,207,207,207,115,207,207,207,207,207,115,207,115,
+207,207,115,207,207,115,207,207,207,207,207,207,207,207,207,207,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
 
 /* block 128 */
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
+591,591,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
 
 /* block 129 */
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,  7,  6,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
 
 /* block 130 */
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-115,115,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,115,115,115,115,115,115,115,115,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,  7,  6,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-200,200,200,200,200,200,200,200,200,200,200,200,197,198,115,115,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
 
 /* block 131 */
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+115,115,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+216,216,216,216,216,216,216,216,216,216,216,216,212,213,115,115,
+
+/* block 132 */
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
   4,  4,  4,  4,  4,  4,  4,  6,  7,  4,115,115,115,115,115,115,
-110,110,110,110,110,110,110,110,110,110,110,110,110,110,178,178,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,192,192,
   4,  9,  9, 15, 15,  6,  7,  6,  7,  6,  7,  6,  7,  6,  7,  6,
   7,  6,  7,  6,  7,  4,  4,  6,  7,  4,  4,  4,  4, 15, 15, 15,
   4,  4,  4,115,  4,  4,  4,  4,  9,  6,  7,  6,  7,  6,  7,  4,
   4,  4,  8,  9,  8,  8,  8,115,  4,  5,  4,  4,115,115,115,115,
-200,200,200,200,200,115,200,200,200,200,200,200,200,200,200,200,
-
-/* block 132 */
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,115,115, 22,
+216,216,216,216,216,115,216,216,216,216,216,216,216,216,216,216,
 
 /* block 133 */
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,115,115, 22,
+
+/* block 134 */
 115,  4,  4,  4,  5,  4,  4,  4,  6,  7,  4,  8,  4,  9,  4,  4,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  4,  4,  8,  8,  8,  4,
   4, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  6,  4,  7, 14, 15,
  14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  6,  8,  7,  8,  6,
-  7,  4,  6,  7,  4,  4,479,479,479,479,479,479,479,479,479,479,
-108,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
-
-/* block 134 */
-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,560,560,
-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,115,
-115,115,482,482,482,482,482,482,115,115,482,482,482,482,482,482,
-115,115,482,482,482,482,482,482,115,115,482,482,482,115,115,115,
-  5,  5,  8, 14, 19,  5,  5,115, 19,  8,  8,  8,  8, 19, 19,115,
-437,437,437,437,437,437,437,437,437, 22, 22, 22, 19, 19,115,115,
+  7,  4,  6,  7,  4,  4,509,509,509,509,509,509,509,509,509,509,
+108,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
 
 /* block 135 */
-561,561,561,561,561,561,561,561,561,561,561,561,115,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,115,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,115,561,561,115,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,115,115,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
+509,509,509,509,509,509,509,509,509,509,509,509,509,509,592,592,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,115,
+115,115,512,512,512,512,512,512,115,115,512,512,512,512,512,512,
+115,115,512,512,512,512,512,512,115,115,512,512,512,115,115,115,
+  5,  5,  8, 14, 19,  5,  5,115, 19,  8,  8,  8,  8, 19, 19,115,
+465,465,465,465,465,465,465,465,465, 22, 22, 22, 19, 19,115,115,
 
 /* block 136 */
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,115,115,115,115,115,
+593,593,593,593,593,593,593,593,593,593,593,593,115,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,115,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,115,593,593,115,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,115,115,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 137 */
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,115,115,115,115,115,
+
+/* block 138 */
   4,  4,  4,115,115,115,115, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  23, 23, 23, 23,115,115,115, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
-562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
-562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
-562,562,562,562,562,563,563,563,563,564,564,564,564,564,564,564,
+594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,
+594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,
+594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,
+594,594,594,594,594,595,595,595,595,596,596,596,596,596,596,596,
 
-/* block 138 */
-564,564,564,564,564,564,564,564,564,564,563,563,564,115,115,115,
+/* block 139 */
+596,596,596,596,596,596,596,596,596,596,595,595,596,596,596,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
-564,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+596,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,110,115,115,
 
-/* block 139 */
+/* block 140 */
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
@@ -2777,509 +2886,629 @@
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 140 */
-565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,565,
-565,565,565,565,565,565,565,565,565,565,565,565,565,115,115,115,
-566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
-566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
-566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
-566,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+/* block 141 */
+597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
+597,597,597,597,597,597,597,597,597,597,597,597,597,115,115,115,
+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,598,598,598,598,598,598,598,598,598,598,598,598,
+598,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 110, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,115,115,115,115,
 
-/* block 141 */
-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,568,568,115,115,115,115,115,115,115,115,115,115,115,115,
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
-569,570,569,569,569,569,569,569,569,569,570,115,115,115,115,115,
-571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
-571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
-571,571,571,571,571,571,572,572,572,572,572,115,115,115,115,115,
-
 /* block 142 */
-573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
-573,573,573,573,573,573,573,573,573,573,573,573,573,573,115,574,
-575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,
-575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,
-575,575,575,575,115,115,115,115,575,575,575,575,575,575,575,575,
-576,577,577,577,577,577,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,
+599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,
+600,600,600,600,115,115,115,115,115,115,115,115,115,599,599,599,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,602,601,601,601,601,601,601,601,601,602,115,115,115,115,115,
+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,604,604,604,604,604,115,115,115,115,115,
 
 /* block 143 */
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,579,579,579,579,579,579,579,579,
-579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,
-579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,579,
-580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
-580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
-580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
+605,605,605,605,605,605,605,605,605,605,605,605,605,605,115,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,607,607,
+607,607,607,607,115,115,115,115,607,607,607,607,607,607,607,607,
+608,609,609,609,609,609,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 144 */
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,115,115,
-582,582,582,582,582,582,582,582,582,582,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,
+610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,
+610,610,610,610,610,610,610,610,611,611,611,611,611,611,611,611,
+611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,
+611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,
+612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
+612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
+612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
 
 /* block 145 */
-583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
-583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
-583,583,583,583,583,583,583,583,115,115,115,115,115,115,115,115,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,115,115,115,115,115,115,115,115,115,115,115,585,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+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,115,115,
+614,614,614,614,614,614,614,614,614,614,115,115,115,115,115,115,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,115,115,115,115,616,616,616,616,616,616,616,616,
+616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
+616,616,616,616,616,616,616,616,616,616,616,616,115,115,115,115,
 
 /* block 146 */
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
+617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
+617,617,617,617,617,617,617,617,115,115,115,115,115,115,115,115,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,115,115,115,115,115,115,115,115,115,115,115,619,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 147 */
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,115,115,115,115,115,115,115,115,115,
-586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,115,115,115,115,115,115,115,115,115,115,
-586,586,586,586,586,586,586,586,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+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,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,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,
 
 /* block 148 */
-587,587,587,587,587,587,115,115,587,115,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,115,587,587,115,115,115,587,115,115,587,
-588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,
-588,588,588,588,588,588,115,589,590,590,590,590,590,590,590,590,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,592,592,593,593,593,593,593,593,593,
+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,620,620,620,620,620,
+620,620,620,620,620,620,620,115,115,115,115,115,115,115,115,115,
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
+620,620,620,620,620,620,115,115,115,115,115,115,115,115,115,115,
+620,620,620,620,620,620,620,620,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 149 */
-594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,
-594,594,594,594,594,594,594,594,594,594,594,594,594,594,594,115,
-115,115,115,115,115,115,115,595,595,595,595,595,595,595,595,595,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
-596,596,596,115,596,596,115,115,115,115,115,597,597,597,597,597,
+621,621,621,621,621,621,115,115,621,115,621,621,621,621,621,621,
+621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
+621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
+621,621,621,621,621,621,115,621,621,115,115,115,621,115,115,621,
+622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,
+622,622,622,622,622,622,115,623,624,624,624,624,624,624,624,624,
+625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,
+625,625,625,625,625,625,625,626,626,627,627,627,627,627,627,627,
 
 /* block 150 */
-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,115,115,115,600,
-601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
-601,601,601,601,601,601,601,601,601,601,115,115,115,115,115,602,
+628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,
+628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,115,
+115,115,115,115,115,115,115,629,629,629,629,629,629,629,629,629,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,115,630,630,115,115,115,115,115,631,631,631,631,631,
 
 /* block 151 */
-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,
-604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,
-604,604,604,604,604,604,604,604,115,115,115,115,605,605,604,604,
-605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
-115,115,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
-605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
-605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,
+632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,
+632,632,632,632,632,632,633,633,633,633,633,633,115,115,115,634,
+635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,635,
+635,635,635,635,635,635,635,635,635,635,115,115,115,115,115,636,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 152 */
-606,607,607,607,115,607,607,115,115,115,115,115,607,607,607,607,
-606,606,606,606,115,606,606,606,115,606,606,606,606,606,606,606,
-606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,
-606,606,606,606,115,115,115,115,607,607,607,115,115,115,115,607,
-608,608,608,608,608,608,608,608,115,115,115,115,115,115,115,115,
-609,609,609,609,609,609,609,609,609,115,115,115,115,115,115,115,
-610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,610,
-610,610,610,610,610,610,610,610,610,610,610,610,610,611,611,612,
+637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,
+637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,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,115,115,115,115,639,639,638,638,
+639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,
+115,115,639,639,639,639,639,639,639,639,639,639,639,639,639,639,
+639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,
+639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,
 
 /* block 153 */
-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,614,614,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-615,615,615,615,615,615,615,615,616,615,615,615,615,615,615,615,
-615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
-615,615,615,615,615,617,617,115,115,115,115,618,618,618,618,618,
-619,619,619,619,619,619,619,115,115,115,115,115,115,115,115,115,
+640,641,641,641,115,641,641,115,115,115,115,115,641,641,641,641,
+640,640,640,640,115,640,640,640,115,640,640,640,640,640,640,640,
+640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,
+640,640,640,640,115,115,115,115,641,641,641,115,115,115,115,641,
+642,642,642,642,642,642,642,642,115,115,115,115,115,115,115,115,
+643,643,643,643,643,643,643,643,643,115,115,115,115,115,115,115,
+644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,
+644,644,644,644,644,644,644,644,644,644,644,644,644,645,645,646,
 
 /* block 154 */
-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,620,620,620,620,620,
-620,620,620,620,620,620,115,115,115,621,621,621,621,621,621,621,
-622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,
-622,622,622,622,622,622,115,115,623,623,623,623,623,623,623,623,
-624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,
-624,624,624,115,115,115,115,115,625,625,625,625,625,625,625,625,
+647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,
+647,647,647,647,647,647,647,647,647,647,647,647,647,648,648,648,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+649,649,649,649,649,649,649,649,650,649,649,649,649,649,649,649,
+649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,649,
+649,649,649,649,649,651,651,115,115,115,115,652,652,652,652,652,
+653,653,653,653,653,653,653,115,115,115,115,115,115,115,115,115,
 
 /* block 155 */
-626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,
-626,626,115,115,115,115,115,115,115,627,627,627,627,115,115,115,
-115,115,115,115,115,115,115,115,115,628,628,628,628,628,628,628,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
+654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
+654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
+654,654,654,654,654,654,115,115,115,655,655,655,655,655,655,655,
+656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,656,
+656,656,656,656,656,656,115,115,657,657,657,657,657,657,657,657,
+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
+658,658,658,115,115,115,115,115,659,659,659,659,659,659,659,659,
 
 /* block 156 */
-629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
-629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
-629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
-629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,
-629,629,629,629,629,629,629,629,629,115,115,115,115,115,115,115,
+660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,
+660,660,115,115,115,115,115,115,115,661,661,661,661,115,115,115,
+115,115,115,115,115,115,115,115,115,662,662,662,662,662,662,662,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 157 */
-630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
-630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
-630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
-630,630,630,115,115,115,115,115,115,115,115,115,115,115,115,115,
-631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
-631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
-631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
-631,631,631,115,115,115,115,115,115,115,632,632,632,632,632,632,
+663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,
+663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,
+663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,
+663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,663,
+663,663,663,663,663,663,663,663,663,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 158 */
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,
-633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,115,
+664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,
+664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,
+664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,
+664,664,664,115,115,115,115,115,115,115,115,115,115,115,115,115,
+665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
+665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
+665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
+665,665,665,115,115,115,115,115,115,115,666,666,666,666,666,666,
 
 /* block 159 */
-634,635,634,636,636,636,636,636,636,636,636,636,636,636,636,636,
-636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,
-636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,
-636,636,636,636,636,636,636,636,635,635,635,635,635,635,635,635,
-635,635,635,635,635,635,635,637,637,637,637,637,637,637,115,115,
-115,115,638,638,638,638,638,638,638,638,638,638,638,638,638,638,
-638,638,638,638,638,638,639,639,639,639,639,639,639,639,639,639,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,635,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,115,
 
 /* block 160 */
-640,640,641,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,642,642,642,642,642,642,642,
-641,641,641,640,640,640,640,641,641,640,640,643,643,644,643,643,
-643,643,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,
-645,645,645,645,645,645,645,645,645,115,115,115,115,115,115,115,
-646,646,646,646,646,646,646,646,646,646,115,115,115,115,115,115,
+668,669,668,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,670,670,
+670,670,670,670,670,670,670,670,669,669,669,669,669,669,669,669,
+669,669,669,669,669,669,669,671,671,671,671,671,671,671,115,115,
+115,115,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,673,673,673,673,673,673,673,673,673,673,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,669,
 
 /* block 161 */
-647,647,647,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,647,647,647,647,647,649,647,647,647,
-647,647,647,647,647,115,650,650,650,650,650,650,650,650,650,650,
-651,651,651,651,115,115,115,115,115,115,115,115,115,115,115,115,
-652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
-652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
-652,652,652,653,654,654,652,115,115,115,115,115,115,115,115,115,
+674,674,675,676,676,676,676,676,676,676,676,676,676,676,676,676,
+676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,
+676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,
+675,675,675,674,674,674,674,675,675,674,674,677,677,678,677,677,
+677,677,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,115,115,115,115,115,115,115,
+680,680,680,680,680,680,680,680,680,680,115,115,115,115,115,115,
 
 /* block 162 */
-655,655,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,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,656,656,656,655,655,655,655,655,655,655,655,655,656,
-656,657,657,657,657,658,658,658,658,658,655,655,655,658,115,115,
-659,659,659,659,659,659,659,659,659,659,657,658,657,658,658,658,
-115,660,660,660,660,660,660,660,660,660,660,660,660,660,660,660,
-660,660,660,660,660,115,115,115,115,115,115,115,115,115,115,115,
+681,681,681,682,682,682,682,682,682,682,682,682,682,682,682,682,
+682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
+682,682,682,682,682,682,682,681,681,681,681,681,683,681,681,681,
+681,681,681,681,681,115,684,684,684,684,684,684,684,684,684,684,
+685,685,685,685,115,115,115,115,115,115,115,115,115,115,115,115,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,687,688,688,686,115,115,115,115,115,115,115,115,115,
 
 /* block 163 */
-661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
-661,661,115,661,661,661,661,661,661,661,661,661,661,661,661,661,
-661,661,661,661,661,661,661,661,661,661,661,661,662,662,662,663,
-663,663,662,662,663,662,663,663,664,664,664,664,664,664,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+689,689,690,691,691,691,691,691,691,691,691,691,691,691,691,691,
+691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
+691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
+691,691,691,690,690,690,689,689,689,689,689,689,689,689,689,690,
+690,691,692,692,691,693,693,693,693,693,689,689,689,693,115,115,
+694,694,694,694,694,694,694,694,694,694,691,693,691,693,693,693,
+115,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
+695,695,695,695,695,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 164 */
-665,665,665,665,665,665,665,115,665,115,665,665,665,665,115,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,115,665,
-665,665,665,665,665,665,665,665,665,666,115,115,115,115,115,115,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,668,
-669,669,669,668,668,668,668,668,668,668,668,115,115,115,115,115,
-670,670,670,670,670,670,670,670,670,670,115,115,115,115,115,115,
+696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,
+696,696,115,696,696,696,696,696,696,696,696,696,696,696,696,696,
+696,696,696,696,696,696,696,696,696,696,696,696,697,697,697,698,
+698,698,697,697,698,697,698,698,699,699,699,699,699,699,698,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 165 */
-671,671,672,672,115,673,673,673,673,673,673,673,673,115,115,673,
-673,115,115,673,673,673,673,673,673,673,673,673,673,673,673,673,
-673,673,673,673,673,673,673,673,673,115,673,673,673,673,673,673,
-673,115,673,673,115,673,673,673,673,673,115,115,671,673,674,672,
-671,672,672,672,672,115,115,672,672,115,115,672,672,672,115,115,
-673,115,115,115,115,115,115,674,115,115,115,115,115,673,673,673,
-673,673,672,672,115,115,671,671,671,671,671,671,671,115,115,115,
-671,671,671,671,671,115,115,115,115,115,115,115,115,115,115,115,
+700,700,700,700,700,700,700,115,700,115,700,700,700,700,115,700,
+700,700,700,700,700,700,700,700,700,700,700,700,700,700,115,700,
+700,700,700,700,700,700,700,700,700,701,115,115,115,115,115,115,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,703,
+704,704,704,703,703,703,703,703,703,703,703,115,115,115,115,115,
+705,705,705,705,705,705,705,705,705,705,115,115,115,115,115,115,
 
 /* block 166 */
-675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
-675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
-675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
-676,677,677,678,678,678,678,678,678,677,678,677,677,676,677,678,
-678,677,678,678,675,675,679,675,115,115,115,115,115,115,115,115,
-680,680,680,680,680,680,680,680,680,680,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+706,706,707,707,115,708,708,708,708,708,708,708,708,115,115,708,
+708,115,115,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,115,708,708,708,708,708,708,
+708,115,708,708,115,708,708,708,708,708,115,115,706,708,709,707,
+706,707,707,707,707,115,115,707,707,115,115,707,707,707,115,115,
+708,115,115,115,115,115,115,709,115,115,115,115,115,708,708,708,
+708,708,707,707,115,115,706,706,706,706,706,706,706,115,115,115,
+706,706,706,706,706,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 167 */
-681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,
-681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,
-681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,682,
-683,683,684,684,684,684,115,115,683,683,683,683,684,684,683,684,
-684,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
-685,685,685,685,685,685,685,685,681,681,681,681,684,684,115,115,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,711,711,711,712,712,712,712,712,712,712,712,
+711,711,712,712,712,711,712,710,710,710,710,713,713,713,713,713,
+714,714,714,714,714,714,714,714,714,714,115,713,115,713,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 168 */
-686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
-686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
-686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
-687,687,687,688,688,688,688,688,688,688,688,687,687,688,687,688,
-688,689,689,689,686,115,115,115,115,115,115,115,115,115,115,115,
-690,690,690,690,690,690,690,690,690,690,115,115,115,115,115,115,
+715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
+715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
+715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
+716,717,717,718,718,718,718,718,718,717,718,717,717,716,717,718,
+718,717,718,718,715,715,719,715,115,115,115,115,115,115,115,115,
+720,720,720,720,720,720,720,720,720,720,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 169 */
-691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
-691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
-691,691,691,691,691,691,691,691,691,691,691,692,693,692,693,693,
-692,692,692,692,692,692,693,692,115,115,115,115,115,115,115,115,
-694,694,694,694,694,694,694,694,694,694,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,
+721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,
+721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,722,
+723,723,724,724,724,724,115,115,723,723,723,723,724,724,723,724,
+724,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
+725,725,725,725,725,725,725,725,721,721,721,721,724,724,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 170 */
-695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
-695,695,695,695,695,695,695,695,695,695,115,115,115,696,696,696,
-697,697,696,696,696,696,697,696,696,696,696,696,115,115,115,115,
-698,698,698,698,698,698,698,698,698,698,699,699,700,700,700,701,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+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,726,726,726,726,726,726,726,
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
+727,727,727,728,728,728,728,728,728,728,728,727,727,728,727,728,
+728,729,729,729,726,115,115,115,115,115,115,115,115,115,115,115,
+730,730,730,730,730,730,730,730,730,730,115,115,115,115,115,115,
+369,369,369,369,369,369,369,369,369,369,369,369,369,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 171 */
+731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
+731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
+731,731,731,731,731,731,731,731,731,731,731,732,733,732,733,733,
+732,732,732,732,732,732,733,732,115,115,115,115,115,115,115,115,
+734,734,734,734,734,734,734,734,734,734,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
-702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
-703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
-703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
-704,704,704,704,704,704,704,704,704,704,705,705,705,705,705,705,
-705,705,705,115,115,115,115,115,115,115,115,115,115,115,115,706,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 172 */
+735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,
+735,735,735,735,735,735,735,735,735,735,115,115,115,736,736,736,
+737,737,736,736,736,736,737,736,736,736,736,736,115,115,115,115,
+738,738,738,738,738,738,738,738,738,738,739,739,740,740,740,741,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,115,115,115,115,115,115,115,
 
 /* block 173 */
-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,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
+742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
+743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,
+743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,
+744,744,744,744,744,744,744,744,744,744,745,745,745,745,745,745,
+745,745,745,115,115,115,115,115,115,115,115,115,115,115,115,746,
 
 /* block 174 */
-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,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+747,748,748,748,748,748,748,749,749,748,748,747,747,747,747,747,
+747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,
+747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,
+747,747,747,748,748,748,748,748,748,749,750,748,748,748,748,751,
+751,751,751,751,751,751,751,748,115,115,115,115,115,115,115,115,
+752,753,753,753,753,753,753,754,754,753,753,753,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,
 
 /* block 175 */
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,115,
-710,710,710,710,710,115,115,115,115,115,115,115,115,115,115,115,
+752,752,752,752,115,115,755,755,755,755,753,753,753,753,753,753,
+753,753,753,753,753,753,753,754,753,753,756,756,756,115,756,756,
+756,756,756,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+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,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,757,757,757,757,757,115,115,115,115,115,115,115,
 
 /* block 176 */
-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,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+758,758,758,758,758,758,758,758,758,115,758,758,758,758,758,758,
+758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,
+758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,759,
+760,760,760,760,760,760,760,115,760,760,760,760,760,760,759,760,
+758,761,761,761,761,761,115,115,115,115,115,115,115,115,115,115,
+762,762,762,762,762,762,762,762,762,762,763,763,763,763,763,763,
+763,763,763,763,763,763,763,763,763,763,763,763,763,115,115,115,
+764,764,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
 
 /* block 177 */
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
+115,115,766,766,766,766,766,766,766,766,766,766,766,766,766,766,
+766,766,766,766,766,766,766,766,115,767,766,766,766,766,766,766,
+766,767,766,766,767,766,766,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 178 */
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+768,768,768,768,768,768,768,115,768,768,115,768,768,768,768,768,
+768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,
+768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,
+768,769,769,769,769,769,769,115,115,115,769,115,769,769,115,769,
+769,769,769,769,769,769,770,769,115,115,115,115,115,115,115,115,
+771,771,771,771,771,771,771,771,771,771,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 179 */
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
 
 /* block 180 */
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,115,115,115,115,115,115,115,115,115,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 181 */
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,115,
+774,774,774,774,774,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 182 */
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,498,
-498,498,498,498,498,498,498,498,498,115,115,115,115,115,115,115,
-713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,
-713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,115,
-714,714,714,714,714,714,714,714,714,714,115,115,115,115,715,715,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 183 */
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
-716,716,716,716,716,716,716,716,716,716,716,716,716,716,115,115,
-717,717,717,717,717,718,115,115,115,115,115,115,115,115,115,115,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
 
 /* block 184 */
-719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
-719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
-719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
-720,720,720,720,720,720,720,721,721,721,721,721,722,722,722,722,
-723,723,723,723,721,722,115,115,115,115,115,115,115,115,115,115,
-724,724,724,724,724,724,724,724,724,724,115,725,725,725,725,725,
-725,725,115,719,719,719,719,719,719,719,719,719,719,719,719,719,
-719,719,719,719,719,719,719,719,115,115,115,115,115,719,719,719,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,775,775,775,775,775,775,775,775,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 185 */
-719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
 
 /* block 186 */
-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,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,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
-726,726,726,726,726,115,115,115,115,115,115,115,115,115,115,115,
-726,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
-727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
-727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,115,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 187 */
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,728,
-728,728,728,729,729,729,729,729,729,729,729,729,729,729,729,729,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
 
 /* block 188 */
-479,477,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,115,115,115,115,115,115,115,
+777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,
+777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,115,
+778,778,778,778,778,778,778,778,778,778,115,115,115,115,779,779,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
 /* block 189 */
-730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
-730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
-730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
-730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
-730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
-730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
-730,730,730,730,730,730,730,730,730,730,730,115,115,115,115,115,
-730,730,730,730,730,730,730,730,730,730,730,730,730,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,780,
+780,780,780,780,780,780,780,780,780,780,780,780,780,780,115,115,
+781,781,781,781,781,782,115,115,115,115,115,115,115,115,115,115,
 
 /* block 190 */
-730,730,730,730,730,730,730,730,730,115,115,115,115,115,115,115,
-730,730,730,730,730,730,730,730,730,730,115,115,731,732,732,733,
+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,783,783,783,783,783,783,783,783,783,783,
+784,784,784,784,784,784,784,785,785,785,785,785,786,786,786,786,
+787,787,787,787,785,786,115,115,115,115,115,115,115,115,115,115,
+788,788,788,788,788,788,788,788,788,788,115,789,789,789,789,789,
+789,789,115,783,783,783,783,783,783,783,783,783,783,783,783,783,
+783,783,783,783,783,783,783,783,115,115,115,115,115,783,783,783,
+
+/* block 191 */
+783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 192 */
+790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,
+790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,
+790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,
+790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,790,
+790,790,790,790,790,115,115,115,115,115,115,115,115,115,115,115,
+790,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,
+791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,
+791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,115,
+
+/* block 193 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,792,
+792,792,792,793,793,793,793,793,793,793,793,793,793,793,793,793,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+794,795,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 194 */
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+
+/* block 195 */
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 196 */
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 197 */
+509,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+
+/* block 198 */
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+
+/* block 199 */
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
+507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+
+/* block 200 */
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+
+/* block 201 */
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,115,115,115,115,
+
+/* block 202 */
+798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,
+798,798,798,798,798,798,798,798,798,798,798,115,115,115,115,115,
+798,798,798,798,798,798,798,798,798,798,798,798,798,115,115,115,
+
+/* block 203 */
+798,798,798,798,798,798,798,798,798,115,115,115,115,115,115,115,
+798,798,798,798,798,798,798,798,798,798,115,115,799,800,800,801,
  22, 22, 22, 22,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
@@ -3287,7 +3516,7 @@
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 191 */
+/* block 204 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -3297,17 +3526,17 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,
 
-/* block 192 */
+/* block 205 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19,115,115, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19,734,406,110,110,110, 19, 19, 19,406,734,734,
-734,734,734, 22, 22, 22, 22, 22, 22, 22, 22,110,110,110,110,110,
+ 19, 19, 19, 19, 19,802,433,110,110,110, 19, 19, 19,433,802,802,
+802,802,802, 22, 22, 22, 22, 22, 22, 22, 22,110,110,110,110,110,
 
-/* block 193 */
+/* block 206 */
 110,110,110, 19, 19,110,110,110,110,110,110,110, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19,110,110,110,110, 19, 19,
@@ -3317,17 +3546,17 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 194 */
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,735,735,735,564,115,115,115,115,115,115,115,115,115,115,
+/* block 207 */
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,803,803,803,596,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 195 */
+/* block 208 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -3337,157 +3566,177 @@
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  23, 23,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 196 */
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,439,439,
-439,439,439,439,439,115,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-
-/* block 197 */
-438,438,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,438,115,438,438,
-115,115,438,115,115,438,438,115,115,438,438,438,438,115,438,438,
-438,438,438,438,438,438,439,439,439,439,115,439,115,439,439,439,
-439,439,439,439,115,439,439,439,439,439,439,439,439,439,439,439,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-
-/* block 198 */
-439,439,439,439,438,438,115,438,438,438,438,115,115,438,438,438,
-438,438,438,438,438,115,438,438,438,438,438,438,438,115,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,438,438,115,438,438,438,438,115,
-438,438,438,438,438,115,438,115,115,115,438,438,438,438,438,438,
-438,115,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-
-/* block 199 */
-438,438,438,438,438,438,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-
-/* block 200 */
-439,439,439,439,439,439,439,439,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-
-/* block 201 */
-438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,115,115,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,  8,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,  8,439,439,439,439,
-439,439,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,  8,439,439,439,439,
-
-/* block 202 */
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,  8,439,439,439,439,439,439,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,  8,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,  8,
-439,439,439,439,439,439,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,  8,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-
-/* block 203 */
-439,439,439,439,439,439,439,439,439,  8,439,439,439,439,439,439,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,  8,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,  8,439,439,439,439,439,439,438,439,115,115, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-
-/* block 204 */
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,
-
-/* block 205 */
-737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-737,737,737,737,737,737,737,736,736,736,736,737,737,737,737,737,
-737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-737,737,737,737,737,737,737,737,737,737,737,737,737,736,736,736,
-736,736,736,736,736,737,736,736,736,736,736,736,736,736,736,736,
-
-/* block 206 */
-736,736,736,736,737,736,736,738,738,738,738,738,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,737,737,737,737,737,
-115,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-
-/* block 207 */
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-
-/* block 208 */
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,115,115,740,740,740,740,740,740,740,740,740,
-741,741,741,741,741,741,741,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-
 /* block 209 */
-200,200,200,200,115,200,200,200,200,200,200,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
-115,200,200,115,200,115,115,200,115,200,200,200,200,200,200,200,
-200,200,200,115,200,200,200,200,115,200,115,200,115,115,115,115,
-115,115,200,115,115,115,115,200,115,200,115,200,115,200,200,200,
-115,200,200,115,200,115,115,200,115,200,115,200,115,200,115,200,
-115,200,200,115,200,115,115,200,200,200,200,115,200,200,200,200,
-200,200,200,115,200,200,200,200,115,200,200,200,200,115,200,115,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,467,467,
+467,467,467,467,467,115,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
 
 /* block 210 */
-200,200,200,200,200,200,200,200,200,200,115,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,115,115,115,115,
-115,200,200,200,115,200,200,200,200,200,115,200,200,200,200,200,
-200,200,200,200,200,200,200,200,200,200,200,200,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-195,195,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+466,466,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,466,115,466,466,
+115,115,466,115,115,466,466,115,115,466,466,466,466,115,466,466,
+466,466,466,466,466,466,467,467,467,467,115,467,115,467,467,467,
+467,467,467,467,115,467,467,467,467,467,467,467,467,467,467,467,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
 
 /* block 211 */
+467,467,467,467,466,466,115,466,466,466,466,115,115,466,466,466,
+466,466,466,466,466,115,466,466,466,466,466,466,466,115,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,466,466,115,466,466,466,466,115,
+466,466,466,466,466,115,466,115,115,115,466,466,466,466,466,466,
+466,115,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+
+/* block 212 */
+466,466,466,466,466,466,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+
+/* block 213 */
+467,467,467,467,467,467,467,467,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+
+/* block 214 */
+466,466,466,466,466,466,466,466,466,466,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,115,115,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,  8,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,  8,467,467,467,467,
+467,467,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,  8,467,467,467,467,
+
+/* block 215 */
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,  8,467,467,467,467,467,467,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,  8,467,467,467,467,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,  8,
+467,467,467,467,467,467,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,  8,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+
+/* block 216 */
+467,467,467,467,467,467,467,467,467,  8,467,467,467,467,467,467,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,  8,467,467,467,467,467,467,
+467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
+467,467,467,  8,467,467,467,467,467,467,466,467,115,115, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+
+/* block 217 */
+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,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,
+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,804,804,804,804,804,804,804,804,
+
+/* block 218 */
+805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,
+805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,
+805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,
+805,805,805,805,805,805,805,804,804,804,804,805,805,805,805,805,
+805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,
+805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,
+805,805,805,805,805,805,805,805,805,805,805,805,805,804,804,804,
+804,804,804,804,804,805,804,804,804,804,804,804,804,804,804,804,
+
+/* block 219 */
+804,804,804,804,805,804,804,806,806,806,806,806,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,805,805,805,805,805,
+115,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 220 */
+807,807,807,807,807,807,807,115,807,807,807,807,807,807,807,807,
+807,807,807,807,807,807,807,807,807,115,115,807,807,807,807,807,
+807,807,115,807,807,115,807,807,807,807,807,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 221 */
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+
+/* block 222 */
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,115,115,809,809,809,809,809,809,809,809,809,
+810,810,810,810,810,810,810,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 223 */
+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,812,812,812,812,812,812,812,812,812,812,812,812,812,812,
+812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,
+812,812,812,812,813,813,813,813,813,813,813,115,115,115,115,115,
+814,814,814,814,814,814,814,814,814,814,115,115,115,115,815,815,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 224 */
+216,216,216,216,115,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+115,216,216,115,216,115,115,216,115,216,216,216,216,216,216,216,
+216,216,216,115,216,216,216,216,115,216,115,216,115,115,115,115,
+115,115,216,115,115,115,115,216,115,216,115,216,115,216,216,216,
+115,216,216,115,216,115,115,216,115,216,115,216,115,216,115,216,
+115,216,216,115,216,115,115,216,216,216,216,115,216,216,216,216,
+216,216,216,115,216,216,216,216,115,216,216,216,216,115,216,115,
+
+/* block 225 */
+216,216,216,216,216,216,216,216,216,216,115,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,115,115,115,115,
+115,216,216,216,115,216,216,216,216,216,115,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+210,210,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 226 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
@@ -3497,7 +3746,7 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
-/* block 212 */
+/* block 227 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,
@@ -3507,7 +3756,7 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,
 
-/* block 213 */
+/* block 228 */
  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,
@@ -3517,67 +3766,107 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
-/* block 214 */
+/* block 229 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,742,742,742,742,742,742,742,742,742,742,
-742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
+115,115,115,115,115,115,816,816,816,816,816,816,816,816,816,816,
+816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,816,
 
-/* block 215 */
-743, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,
+/* block 230 */
+817, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,
  19, 19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 216 */
+/* block 231 */
+ 19, 19, 19, 19, 19, 19, 19, 19,479, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,479, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 14, 14, 14, 14, 14,
+ 19, 19, 19,479, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
-/* block 217 */
+/* block 232 */
+ 19, 19, 19, 19, 19,478, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19,479, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,479, 19, 19, 19,479, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19,478,478,478, 19, 19,478, 19, 19,478,478,478, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,479, 19,479, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,818,818,818,818,818,
 
-/* block 218 */
+/* block 233 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19,115, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19,478,478, 19, 19,478,478,478,478,478,478,478,478,478,478,
+478, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19,819,819,819,819, 19, 19, 19, 19,478, 19,
+478,478,478,478,478,478,478,478,478, 19, 19, 19,478, 19, 19, 19,
+
+/* block 234 */
+ 19,478,478,478, 19,478,478,478, 19, 19, 19,479, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,478, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,479,479, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
-/* block 219 */
+/* block 235 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19,479, 19, 19, 19, 19,479, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,478,478, 19, 19, 19, 19,478, 19, 19, 19, 19, 19,
+
+/* block 236 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+478, 19, 19, 19, 19,478,478, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,479, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 237 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19,478,478,478, 19, 19, 19,478,478,478,478,478,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+
+/* block 238 */
+479, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19,479, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19,478, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19,478,478,478, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+478, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,478, 19, 19, 19,
+ 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,
- 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,
 
-/* block 220 */
+/* block 239 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -3587,7 +3876,7 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 221 */
+/* block 240 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -3597,7 +3886,7 @@
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 222 */
+/* block 241 */
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -3607,7 +3896,7 @@
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
 
-/* block 223 */
+/* block 242 */
  19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
  19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,
@@ -3617,69 +3906,79 @@
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 224 */
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
- 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+/* block 243 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19,478,478,478,478,478, 19,478,478,
+ 19, 19, 19, 19, 19, 19,478, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+478,478,478,478,478,478,478,478,478,478, 19, 19, 19,478,478,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 225 */
- 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+/* block 244 */
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
  19,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+ 19,478,478,478,478,478,478,478,478,478,478,478,478,478, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+
+/* block 245 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 226 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+/* block 246 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,115,115,115,115,115,115,115,115,115,115,115,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+
+/* block 247 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,115,115,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+
+/* block 248 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+
+/* block 249 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 227 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,115,115,115,115,115,115,115,115,115,115,115,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-
-/* block 228 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,115,115,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-
-/* block 229 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
-
-/* block 230 */
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
-485,485,485,485,485,485,485,485,485,485,485,485,485,485,115,115,
+/* block 250 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
@@ -3687,27 +3986,27 @@
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
 
-/* block 231 */
-437, 22,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+/* block 251 */
+465, 22,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+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,
 
-/* block 232 */
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+/* block 252 */
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
 
-/* block 233 */
+/* block 253 */
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
@@ -3717,7 +4016,7 @@
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 
-/* block 234 */
+/* block 254 */
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
@@ -3725,17 +4024,17 @@
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
-437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,
 
-/* block 235 */
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
-557,557,557,557,557,557,557,557,557,557,557,557,557,557,115,115,
+/* block 255 */
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,115,115,
 
 };
 
diff --git a/dist2/src/pcre2_ucp.h b/dist2/src/pcre2_ucp.h
index 0b7553e..defba4c 100644
--- a/dist2/src/pcre2_ucp.h
+++ b/dist2/src/pcre2_ucp.h
@@ -39,8 +39,8 @@
 */
 
 
-#ifndef _PCRE2_UCP_H
-#define _PCRE2_UCP_H
+#ifndef PCRE2_UCP_H_IDEMPOTENT_GUARD
+#define PCRE2_UCP_H_IDEMPOTENT_GUARD
 
 /* This file contains definitions of the property values that are returned by
 the UCD access macros. New values that are added for new releases of Unicode
@@ -100,9 +100,7 @@
   ucp_Zs     /* Space separator */
 };
 
-/* These are grapheme break properties. Note that the code for processing them
-assumes that the values are less than 16. If more values are added that take
-the number to 16 or more, the code will have to be rewritten. */
+/* These are grapheme break properties. */
 
 enum {
   ucp_gbCR,                /*  0 */
@@ -117,7 +115,12 @@
   ucp_gbLV,                /*  9 Hangul syllable type LV */
   ucp_gbLVT,               /* 10 Hangul syllable type LVT */
   ucp_gbRegionalIndicator, /* 11 */
-  ucp_gbOther              /* 12 */
+  ucp_gbOther,             /* 12 */
+  ucp_gbE_Base,            /* 13 */
+  ucp_gbE_Modifier,        /* 14 */
+  ucp_gbE_Base_GAZ,        /* 15 */
+  ucp_gbZWJ,               /* 16 */
+  ucp_gbGlue_After_Zwj     /* 17 */
 };
 
 /* These are the script identifications. */
@@ -184,13 +187,13 @@
   ucp_Tifinagh,
   ucp_Ugaritic,
   ucp_Yi,
-  /* New for Unicode 5.0: */
+  /* New for Unicode 5.0 */
   ucp_Balinese,
   ucp_Cuneiform,
   ucp_Nko,
   ucp_Phags_Pa,
   ucp_Phoenician,
-  /* New for Unicode 5.1: */
+  /* New for Unicode 5.1 */
   ucp_Carian,
   ucp_Cham,
   ucp_Kayah_Li,
@@ -202,7 +205,7 @@
   ucp_Saurashtra,
   ucp_Sundanese,
   ucp_Vai,
-  /* New for Unicode 5.2: */
+  /* New for Unicode 5.2 */
   ucp_Avestan,
   ucp_Bamum,
   ucp_Egyptian_Hieroglyphs,
@@ -218,11 +221,11 @@
   ucp_Samaritan,
   ucp_Tai_Tham,
   ucp_Tai_Viet,
-  /* New for Unicode 6.0.0: */
+  /* New for Unicode 6.0.0 */
   ucp_Batak,
   ucp_Brahmi,
   ucp_Mandaic,
-  /* New for Unicode 6.1.0: */
+  /* New for Unicode 6.1.0 */
   ucp_Chakma,
   ucp_Meroitic_Cursive,
   ucp_Meroitic_Hieroglyphs,
@@ -230,7 +233,7 @@
   ucp_Sharada,
   ucp_Sora_Sompeng,
   ucp_Takri,
-  /* New for Unicode 7.0.0: */
+  /* New for Unicode 7.0.0 */
   ucp_Bassa_Vah,
   ucp_Caucasian_Albanian,
   ucp_Duployan,
@@ -254,15 +257,26 @@
   ucp_Siddham,
   ucp_Tirhuta,
   ucp_Warang_Citi,
-  /* New for Unicode 8.0.0: */
+  /* New for Unicode 8.0.0 */
   ucp_Ahom,
   ucp_Anatolian_Hieroglyphs,
   ucp_Hatran,
   ucp_Multani,
   ucp_Old_Hungarian,
-  ucp_SignWriting
+  ucp_SignWriting,
+  /* New for Unicode 10.0.0 (no update since 8.0.0) */
+  ucp_Adlam,
+  ucp_Bhaiksuki,
+  ucp_Marchen,
+  ucp_Newa,
+  ucp_Osage,
+  ucp_Tangut,
+  ucp_Masaram_Gondi,
+  ucp_Nushu,
+  ucp_Soyombo,
+  ucp_Zanabazar_Square
 };
 
-#endif
+#endif  /* PCRE2_UCP_H_IDEMPOTENT_GUARD */
 
 /* End of pcre2_ucp.h */
diff --git a/dist2/src/pcre2_valid_utf.c b/dist2/src/pcre2_valid_utf.c
index 2dfd8df..96e8bff 100644
--- a/dist2/src/pcre2_valid_utf.c
+++ b/dist2/src/pcre2_valid_utf.c
@@ -7,7 +7,7 @@
 
                        Written by Philip Hazel
      Original API code Copyright (c) 1997-2012 University of Cambridge
-         New API code Copyright (c) 2016 University of Cambridge
+          New API code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -93,8 +93,8 @@
 int
 PRIV(valid_utf)(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)
 {
-register PCRE2_SPTR p;
-register uint32_t c;
+PCRE2_SPTR p;
+uint32_t c;
 
 /* ----------------- Check a UTF-8 string ----------------- */
 
@@ -133,7 +133,7 @@
 
 for (p = string; length > 0; p++)
   {
-  register uint32_t ab, d;
+  uint32_t ab, d;
 
   c = *p;
   length--;
@@ -142,20 +142,20 @@
 
   if (c < 0xc0)                         /* Isolated 10xx xxxx byte */
     {
-    *erroroffset = (int)(p - string);
+    *erroroffset = (PCRE2_SIZE)(p - string);
     return PCRE2_ERROR_UTF8_ERR20;
     }
 
   if (c >= 0xfe)                        /* Invalid 0xfe or 0xff bytes */
     {
-    *erroroffset = (int)(p - string);
+    *erroroffset = (PCRE2_SIZE)(p - string);
     return PCRE2_ERROR_UTF8_ERR21;
     }
 
   ab = PRIV(utf8_table4)[c & 0x3f];     /* Number of additional bytes (1-5) */
   if (length < ab)                      /* Missing bytes */
     {
-    *erroroffset = (int)(p - string);
+    *erroroffset = (PCRE2_SIZE)(p - string);
     switch(ab - length)
       {
       case 1: return PCRE2_ERROR_UTF8_ERR1;
diff --git a/dist2/src/pcre2demo.c b/dist2/src/pcre2demo.c
index 8ae49f1..5d9b321 100644
--- a/dist2/src/pcre2demo.c
+++ b/dist2/src/pcre2demo.c
@@ -211,6 +211,21 @@
 if (rc == 0)
   printf("ovector was not big enough for all the captured substrings\n");
 
+/* We must guard against patterns such as /(?=.\K)/ that use \K in an assertion
+to set the start of a match later than its end. In this demonstration program,
+we just detect this case and give up. */
+
+if (ovector[0] > ovector[1])
+  {
+  printf("\\K was used in an assertion to set the match start after its end.\n"
+    "From end to start the match was: %.*s\n", (int)(ovector[0] - ovector[1]),
+      (char *)(subject + ovector[1]));
+  printf("Run abandoned\n");
+  pcre2_match_data_free(match_data);
+  pcre2_code_free(re);
+  return 1;
+  }
+
 /* Show substrings stored in the output vector by number. Obviously, in a real
 application you might want to do things other than print them. */
 
@@ -338,6 +353,29 @@
     options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
     }
 
+  /* If the previous match was not an empty string, there is one tricky case to
+  consider. If a pattern contains \K within a lookbehind assertion at the
+  start, the end of the matched string can be at the offset where the match
+  started. Without special action, this leads to a loop that keeps on matching
+  the same substring. We must detect this case and arrange to move the start on
+  by one character. The pcre2_get_startchar() function returns the starting
+  offset that was passed to pcre2_match(). */
+
+  else
+    {
+    PCRE2_SIZE startchar = pcre2_get_startchar(match_data);
+    if (start_offset <= startchar)
+      {
+      if (startchar >= subject_length) break;   /* Reached end of subject.   */
+      start_offset = startchar + 1;             /* Advance by one character. */
+      if (utf8)                                 /* If UTF-8, it may be more  */
+        {                                       /*   than one code unit.     */
+        for (; start_offset < subject_length; start_offset++)
+          if ((subject[start_offset] & 0xc0) != 0x80) break;
+        }
+      }
+    }
+
   /* Run the next matching operation */
 
   rc = pcre2_match(
@@ -402,6 +440,21 @@
   if (rc == 0)
     printf("ovector was not big enough for all the captured substrings\n");
 
+  /* We must guard against patterns such as /(?=.\K)/ that use \K in an
+  assertion to set the start of a match later than its end. In this
+  demonstration program, we just detect this case and give up. */
+
+  if (ovector[0] > ovector[1])
+    {
+    printf("\\K was used in an assertion to set the match start after its end.\n"
+      "From end to start the match was: %.*s\n", (int)(ovector[0] - ovector[1]),
+        (char *)(subject + ovector[1]));
+    printf("Run abandoned\n");
+    pcre2_match_data_free(match_data);
+    pcre2_code_free(re);
+    return 1;
+    }
+
   /* As before, show substrings stored in the output vector by number, and then
   also any named substrings. */
 
diff --git a/dist2/src/pcre2grep.c b/dist2/src/pcre2grep.c
index 49747c0..02339f5 100644
--- a/dist2/src/pcre2grep.c
+++ b/dist2/src/pcre2grep.c
@@ -13,7 +13,7 @@
 The header can be found in the special z/OS distribution, which is available
 from www.zaconsultants.net or from www.cbttape.org.
 
-           Copyright (c) 1997-2016 University of Cambridge
+           Copyright (c) 1997-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -58,14 +58,28 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#if defined(_WIN32) || defined(WIN32)
+#if (defined _WIN32 || (defined HAVE_WINDOWS_H && HAVE_WINDOWS_H)) \
+  && !defined WIN32 && !defined(__CYGWIN__)
+#define WIN32
+#endif
+
+/* Some cmake's define it still */
+#if defined(__CYGWIN__) && !defined(WIN32)
+#define WIN32
+#endif
+
+#ifdef WIN32
 #include <io.h>                /* For _setmode() */
 #include <fcntl.h>             /* For _O_BINARY */
 #endif
 
 #ifdef SUPPORT_PCRE2GREP_CALLOUT
+#ifdef WIN32
+#include <process.h>
+#else
 #include <sys/wait.h>
 #endif
+#endif
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -95,7 +109,8 @@
 #define MAXPATLEN 8192
 #endif
 
-#define PATBUFSIZE (MAXPATLEN + 10)   /* Allows for prefix+suffix */
+#define FNBUFSIZ 2048
+#define ERRBUFSIZ 256
 
 /* Values for the "filenames" variable, which specifies options for file name
 output. The order is important; it is assumed that a file name is wanted for
@@ -128,17 +143,20 @@
 this, we use a macro that compiles a fudge. Oddly, this does not also seem to
 apply to fprintf(). */
 
-#define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {}
+#define FWRITE_IGNORE(a,b,c,d) if (fwrite(a,b,c,d)) {}
 
 /* Under Windows, we have to set stdout to be binary, so that it does not
 convert \r\n at the ends of output lines to \r\r\n. However, that means that
 any messages written to stdout must have \r\n as their line terminator. This is
-handled by using STDOUT_NL as the newline string. */
+handled by using STDOUT_NL as the newline string. We also use a normal double
+quote for the example, as single quotes aren't usually available. */
 
-#if defined(_WIN32) || defined(WIN32)
+#ifdef WIN32
 #define STDOUT_NL  "\r\n"
+#define QUOT       "\""
 #else
 #define STDOUT_NL  "\n"
+#define QUOT       "'"
 #endif
 
 
@@ -158,29 +176,36 @@
 static const char *jfriedl_postfix = "";
 #endif
 
-static char *colour_string = (char *)"1;31";
-static char *colour_option = NULL;
-static char *dee_option = NULL;
-static char *DEE_option = NULL;
-static char *locale = NULL;
+static const char *colour_string = "1;31";
+static const char *colour_option = NULL;
+static const char *dee_option = NULL;
+static const char *DEE_option = NULL;
+static const char *locale = NULL;
+static const char *newline_arg = NULL;
+static const char *om_separator = NULL;
+static const char *stdin_name = "(standard input)";
+static const char *output_text = NULL;
+
 static char *main_buffer = NULL;
-static char *newline_arg = NULL;
-static char *om_separator = (char *)"";
-static char *stdin_name = (char *)"(standard input)";
 
 static int after_context = 0;
 static int before_context = 0;
 static int binary_files = BIN_BINARY;
 static int both_context = 0;
 static int bufthird = PCRE2GREP_BUFSIZE;
+static int max_bufthird = PCRE2GREP_MAX_BUFSIZE;
 static int bufsize = 3*PCRE2GREP_BUFSIZE;
 static int endlinetype;
 
-#if defined HAVE_WINDOWS_H && HAVE_WINDOWS_H
+static unsigned long int total_count = 0;
+static unsigned long int counts_printed = 0;
+
+#ifdef WIN32
 static int dee_action = dee_SKIP;
 #else
 static int dee_action = dee_READ;
 #endif
+
 static int DEE_action = DEE_READ;
 static int error_count = 0;
 static int filenames = FN_DEFAULT;
@@ -194,9 +219,10 @@
 static const uint8_t *character_tables = NULL;
 
 static uint32_t pcre2_options = 0;
-static uint32_t process_options = 0;
+static uint32_t extra_options = 0;
+static PCRE2_SIZE heap_limit = PCRE2_UNSET;
 static uint32_t match_limit = 0;
-static uint32_t recursion_limit = 0;
+static uint32_t depth_limit = 0;
 
 static pcre2_compile_context *compile_context;
 static pcre2_match_context *match_context;
@@ -205,6 +231,9 @@
 
 static BOOL count_only = FALSE;
 static BOOL do_colour = FALSE;
+#ifdef WIN32
+static BOOL do_ansi = FALSE;
+#endif
 static BOOL file_offsets = FALSE;
 static BOOL hyphenpending = FALSE;
 static BOOL invert = FALSE;
@@ -215,7 +244,7 @@
 static BOOL omit_zero_count = FALSE;
 static BOOL resource_error = FALSE;
 static BOOL quiet = FALSE;
-static BOOL show_only_matching = FALSE;
+static BOOL show_total_count = FALSE;
 static BOOL silent = FALSE;
 static BOOL utf = FALSE;
 
@@ -228,6 +257,7 @@
 
 static omstr *only_matching = NULL;
 static omstr *only_matching_last = NULL;
+static int only_matching_count;
 
 /* Structure for holding the two variables that describe a number chain. */
 
@@ -309,7 +339,7 @@
 
 /* Structure for options and list of them */
 
-enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_U32NUMBER,
+enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_U32NUMBER, OP_SIZE,
        OP_OP_NUMBER, OP_OP_NUMBERS, OP_PATLIST, OP_FILELIST, OP_BINFILES };
 
 typedef struct option_item {
@@ -335,15 +365,17 @@
 #define N_LOFFSETS     (-10)
 #define N_FOFFSETS     (-11)
 #define N_LBUFFER      (-12)
-#define N_M_LIMIT      (-13)
-#define N_M_LIMIT_REC  (-14)
-#define N_BUFSIZE      (-15)
-#define N_NOJIT        (-16)
-#define N_FILE_LIST    (-17)
-#define N_BINARY_FILES (-18)
-#define N_EXCLUDE_FROM (-19)
-#define N_INCLUDE_FROM (-20)
-#define N_OM_SEPARATOR (-21)
+#define N_H_LIMIT      (-13)
+#define N_M_LIMIT      (-14)
+#define N_M_LIMIT_DEP  (-15)
+#define N_BUFSIZE      (-16)
+#define N_NOJIT        (-17)
+#define N_FILE_LIST    (-18)
+#define N_BINARY_FILES (-19)
+#define N_EXCLUDE_FROM (-20)
+#define N_INCLUDE_FROM (-21)
+#define N_OM_SEPARATOR (-22)
+#define N_MAX_BUFSIZE  (-23)
 
 static option_item optionlist[] = {
   { OP_NODATA,     N_NULL,   NULL,              "",              "terminate options" },
@@ -352,7 +384,8 @@
   { OP_NODATA,     'a',      NULL,              "text",          "treat binary files as text" },
   { OP_NUMBER,     'B',      &before_context,   "before-context=number", "set number of prior context lines" },
   { OP_BINFILES,   N_BINARY_FILES, NULL,        "binary-files=word", "set treatment of binary files" },
-  { OP_NUMBER,     N_BUFSIZE,&bufthird,         "buffer-size=number", "set processing buffer size parameter" },
+  { OP_NUMBER,     N_BUFSIZE,&bufthird,         "buffer-size=number", "set processing buffer starting size" },
+  { OP_NUMBER,     N_MAX_BUFSIZE,&max_bufthird, "max-buffer-size=number",  "set processing buffer maximum size" },
   { OP_OP_STRING,  N_COLOUR, &colour_option,    "color=option",  "matched text color option" },
   { OP_OP_STRING,  N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },
   { OP_NUMBER,     'C',      &both_context,     "context=number", "set number of context lines, before & after" },
@@ -368,22 +401,25 @@
   { OP_NODATA,     'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },
   { OP_NODATA,     'I',      NULL,              "",              "treat binary files as not matching (ignore)" },
   { OP_NODATA,     'i',      NULL,              "ignore-case",   "ignore case distinctions" },
-#ifdef SUPPORT_PCRE2GREP_JIT
-  { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "do not use just-in-time compiler optimization" },
-#else
-  { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "ignored: this pcre2grep does not support JIT" },
-#endif
   { OP_NODATA,     'l',      NULL,              "files-with-matches", "print only FILE names containing matches" },
   { OP_NODATA,     'L',      NULL,              "files-without-match","print only FILE names not containing matches" },
   { OP_STRING,     N_LABEL,  &stdin_name,       "label=name",    "set name for standard input" },
   { OP_NODATA,     N_LBUFFER, NULL,             "line-buffered", "use line buffering" },
   { OP_NODATA,     N_LOFFSETS, NULL,            "line-offsets",  "output line numbers and offsets, not text" },
   { OP_STRING,     N_LOCALE, &locale,           "locale=locale", "use the named locale" },
-  { OP_U32NUMBER,  N_M_LIMIT, &match_limit,     "match-limit=number", "set PCRE match limit option" },
-  { OP_U32NUMBER,  N_M_LIMIT_REC, &recursion_limit, "recursion-limit=number", "set PCRE match recursion limit option" },
+  { OP_SIZE,       N_H_LIMIT, &heap_limit,      "heap-limit=number",  "set PCRE2 heap limit option (kilobytes)" },
+  { OP_U32NUMBER,  N_M_LIMIT, &match_limit,     "match-limit=number", "set PCRE2 match limit option" },
+  { OP_U32NUMBER,  N_M_LIMIT_DEP, &depth_limit, "depth-limit=number", "set PCRE2 depth limit option" },
+  { OP_U32NUMBER,  N_M_LIMIT_DEP, &depth_limit, "recursion-limit=number", "obsolete synonym for depth-limit" },
   { OP_NODATA,     'M',      NULL,              "multiline",     "run in multiline mode" },
-  { OP_STRING,     'N',      &newline_arg,      "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },
+  { OP_STRING,     'N',      &newline_arg,      "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF, ANY, or NUL)" },
   { OP_NODATA,     'n',      NULL,              "line-number",   "print line number with output lines" },
+#ifdef SUPPORT_PCRE2GREP_JIT
+  { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "do not use just-in-time compiler optimization" },
+#else
+  { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "ignored: this pcre2grep does not support JIT" },
+#endif
+  { OP_STRING,     'O',      &output_text,       "output=text",   "show only this text (possibly expanded)" },
   { OP_OP_NUMBERS, 'o',      &only_matching_data, "only-matching=n", "show only the part of the line that matched" },
   { OP_STRING,     N_OM_SEPARATOR, &om_separator, "om-separator=text", "set separator for multiple -o output" },
   { OP_NODATA,     'q',      NULL,              "quiet",         "suppress output, just set return code" },
@@ -398,6 +434,7 @@
   { OP_OP_NUMBER, 'S',      &S_arg,            "jeffS",         "replace matched (sub)string with X" },
 #endif
   { OP_NODATA,    's',      NULL,              "no-messages",   "suppress error messages" },
+  { OP_NODATA,    't',      NULL,              "total-count",   "print total count of matching lines" },
   { OP_NODATA,    'u',      NULL,              "utf",           "use UTF mode" },
   { OP_NODATA,    'V',      NULL,              "version",       "print version information and exit" },
   { OP_NODATA,    'v',      NULL,              "invert-match",  "select non-matching lines" },
@@ -410,20 +447,7 @@
 of PCRE2_NEWLINE_xx in pcre2.h. */
 
 static const char *newlines[] = {
-  "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF" };
-
-/* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F
-options. These set the 1, 2, and 4 bits in process_options, respectively. Note
-that the combination of -w and -x has the same effect as -x on its own, so we
-can treat them as the same. Note that the MAXPATLEN macro assumes the longest
-prefix+suffix is 10 characters; if anything longer is added, it must be
-adjusted. */
-
-static const char *prefix[] = {
-  "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" };
-
-static const char *suffix[] = {
-  "", "\\b", ")$",   ")$",   "\\E", "\\E\\b", "\\E)$",   "\\E)$" };
+  "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF", "NUL" };
 
 /* UTF-8 tables - used only when the newline setting is "any". */
 
@@ -455,6 +479,34 @@
 }
 
 
+/*************************************************
+*         Parse GREP_COLORS                      *
+*************************************************/
+
+/* Extract ms or mt from GREP_COLORS.
+
+Argument:  the string, possibly NULL
+Returns:   the value of ms or mt, or NULL if neither present
+*/
+
+static char *
+parse_grep_colors(const char *gc)
+{
+static char seq[16];
+char *col;
+uint32_t len;
+if (gc == NULL) return NULL;
+col = strstr(gc, "ms=");
+if (col == NULL) col = strstr(gc, "mt=");
+if (col == NULL) return NULL;
+len = 0;
+col += 3;
+while (*col != ':' && *col != 0 && len < sizeof(seq)-1)
+  seq[len++] = *col++;
+seq[len] = 0;
+return seq;
+}
+
 
 /*************************************************
 *         Exit from the program                  *
@@ -469,11 +521,27 @@
 static void
 pcre2grep_exit(int rc)
 {
+/* VMS does exit codes differently: both exit(1) and exit(0) return with a
+status of 1, which is not helpful. To help with this problem, define a symbol
+(akin to an environment variable) called "PCRE2GREP_RC" and put the exit code
+therein. */
+
+#ifdef __VMS
+#include descrip
+#include lib$routines
+  char val_buf[4];
+  $DESCRIPTOR(sym_nam, "PCRE2GREP_RC");
+  $DESCRIPTOR(sym_val, val_buf);
+  sprintf(val_buf, "%d", rc);
+  sym_val.dsc$w_length = strlen(val_buf);
+  lib$set_symbol(&sym_nam, &sym_val);
+#endif
+
 if (resource_error)
   {
-  fprintf(stderr, "pcre2grep: Error %d, %d or %d means that a resource limit "
-    "was exceeded.\n", PCRE2_ERROR_JIT_STACKLIMIT, PCRE2_ERROR_MATCHLIMIT,
-    PCRE2_ERROR_RECURSIONLIMIT);
+  fprintf(stderr, "pcre2grep: Error %d, %d, %d or %d means that a resource "
+    "limit was exceeded.\n", PCRE2_ERROR_JIT_STACKLIMIT, PCRE2_ERROR_MATCHLIMIT,
+    PCRE2_ERROR_DEPTHLIMIT, PCRE2_ERROR_HEAPLIMIT);
   fprintf(stderr, "pcre2grep: Check your regex for nested unlimited loops.\n");
   }
 exit(rc);
@@ -571,9 +639,83 @@
 *            OS-specific functions               *
 *************************************************/
 
-/* These functions are defined so that they can be made system specific.
-At present there are versions for Unix-style environments, Windows, native
-z/OS, and "no support". */
+/* These definitions are needed in all Windows environments, even those where
+Unix-style directory scanning can be used (see below). */
+
+#ifdef WIN32
+
+#ifndef STRICT
+# define STRICT
+#endif
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+#define iswild(name) (strpbrk(name, "*?") != NULL)
+
+/* Convert ANSI BGR format to RGB used by Windows */
+#define BGR_RGB(x) ((x & 1 ? 4 : 0) | (x & 2) | (x & 4 ? 1 : 0))
+
+static HANDLE hstdout;
+static CONSOLE_SCREEN_BUFFER_INFO csbi;
+static WORD match_colour;
+
+static WORD
+decode_ANSI_colour(const char *cs)
+{
+WORD result = csbi.wAttributes;
+while (*cs)
+  {
+  if (isdigit(*cs))
+    {
+    int code = atoi(cs);
+    if (code == 1) result |= 0x08;
+    else if (code == 4) result |= 0x8000;
+    else if (code == 5) result |= 0x80;
+    else if (code >= 30 && code <= 37) result = (result & 0xF8) | BGR_RGB(code - 30);
+    else if (code == 39) result = (result & 0xF0) | (csbi.wAttributes & 0x0F);
+    else if (code >= 40 && code <= 47) result = (result & 0x8F) | (BGR_RGB(code - 40) << 4);
+    else if (code == 49) result = (result & 0x0F) | (csbi.wAttributes & 0xF0);
+    /* aixterm high intensity colour codes */
+    else if (code >= 90 && code <= 97) result = (result & 0xF0) | BGR_RGB(code - 90) | 0x08;
+    else if (code >= 100 && code <= 107) result = (result & 0x0F) | (BGR_RGB(code - 100) << 4) | 0x80;
+
+    while (isdigit(*cs)) cs++;
+    }
+  if (*cs) cs++;
+  }
+return result;
+}
+
+
+static void
+init_colour_output()
+{
+if (do_colour)
+  {
+  hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
+  /* This fails when redirected to con; try again if so. */
+  if (!GetConsoleScreenBufferInfo(hstdout, &csbi) && !do_ansi)
+    {
+    HANDLE hcon = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
+      FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+    GetConsoleScreenBufferInfo(hcon, &csbi);
+    CloseHandle(hcon);
+    }
+  match_colour = decode_ANSI_colour(colour_string);
+  /* No valid colour found - turn off colouring */
+  if (!match_colour) do_colour = FALSE;
+  }
+}
+
+#endif  /* WIN32 */
+
+
+/* The following sets of functions are defined so that they can be made system
+specific. At present there are versions for Unix-style environments, Windows,
+native z/OS, and "no support". */
 
 
 /************* Directory scanning Unix-style and z/OS ***********/
@@ -677,6 +819,18 @@
 }
 #endif
 
+
+/************* Print optionally coloured match Unix-style and z/OS **********/
+
+static void
+print_match(const void *buf, int length)
+{
+if (length == 0) return;
+if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
+FWRITE_IGNORE(buf, 1, length, stdout);
+if (do_colour) fprintf(stdout, "%c[0m", 0x1b);
+}
+
 /* End of Unix-style or native z/OS environment functions. */
 
 
@@ -686,19 +840,9 @@
 Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
 when it did not exist. David Byron added a patch that moved the #include of
 <windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after.
-The double test below stops gcc 4.4.4 grumbling that HAVE_WINDOWS_H is
-undefined when it is indeed undefined. */
+*/
 
-#elif defined HAVE_WINDOWS_H && HAVE_WINDOWS_H
-
-#ifndef STRICT
-# define STRICT
-#endif
-#ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-
-#include <windows.h>
+#elif defined WIN32
 
 #ifndef INVALID_FILE_ATTRIBUTES
 #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
@@ -738,7 +882,10 @@
   pcre2grep_exit(2);
   }
 memcpy(pattern, filename, len);
-memcpy(&(pattern[len]), "\\*", 3);
+if (iswild(filename))
+  pattern[len] = 0;
+else
+  memcpy(&(pattern[len]), "\\*", 3);
 dir->handle = FindFirstFile(pattern, &(dir->data));
 if (dir->handle != INVALID_HANDLE_VALUE)
   {
@@ -796,18 +943,36 @@
 
 /************* Test for a terminal in Windows **********/
 
-/* I don't know how to do this; assume never */
-
 static BOOL
 is_stdout_tty(void)
 {
-return FALSE;
+return _isatty(_fileno(stdout));
 }
 
 static BOOL
 is_file_tty(FILE *f)
 {
-return FALSE;
+return _isatty(_fileno(f));
+}
+
+
+/************* Print optionally coloured match in Windows **********/
+
+static void
+print_match(const void *buf, int length)
+{
+if (length == 0) return;
+if (do_colour)
+  {
+  if (do_ansi) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
+    else SetConsoleTextAttribute(hstdout, match_colour);
+  }
+FWRITE_IGNORE(buf, 1, length, stdout);
+if (do_colour)
+  {
+  if (do_ansi) fprintf(stdout, "%c[0m", 0x1b);
+    else SetConsoleTextAttribute(hstdout, csbi.wAttributes);
+  }
 }
 
 /* End of Windows functions */
@@ -849,6 +1014,16 @@
 return FALSE;
 }
 
+
+/************* Print optionally coloured match when we can't do it **********/
+
+static void
+print_match(const void *buf, int length)
+{
+if (length == 0) return;
+FWRITE_IGNORE(buf, 1, length, stdout);
+}
+
 #endif  /* End of system-specific functions */
 
 
@@ -889,7 +1064,7 @@
   if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);
   }
 fprintf(stderr, "] [long options] [pattern] [files]\n");
-fprintf(stderr, "Type `pcre2grep --help' for more information and the long "
+fprintf(stderr, "Type \"pcre2grep --help\" for more information and the long "
   "options.\n");
 return rc;
 }
@@ -931,7 +1106,7 @@
 printf("All files are read as plain files, without any interpretation." STDOUT_NL STDOUT_NL);
 #endif
 
-printf("Example: pcre2grep -i 'hello.*world' menu.h main.c" STDOUT_NL STDOUT_NL);
+printf("Example: pcre2grep -i " QUOT "hello.*world" QUOT " menu.h main.c" STDOUT_NL STDOUT_NL);
 printf("Options:" STDOUT_NL);
 
 for (op = optionlist; op->one_char != 0; op++)
@@ -952,8 +1127,9 @@
   printf("%.*s%s" STDOUT_NL, n, "                           ", op->help_text);
   }
 
-printf(STDOUT_NL "Numbers may be followed by K or M, e.g. --buffer-size=100K." STDOUT_NL);
+printf(STDOUT_NL "Numbers may be followed by K or M, e.g. --max-buffer-size=100K." STDOUT_NL);
 printf("The default value for --buffer-size is %d." STDOUT_NL, PCRE2GREP_BUFSIZE);
+printf("The default value for --max-buffer-size is %d." STDOUT_NL, PCRE2GREP_MAX_BUFSIZE);
 printf("When reading patterns or file names from a file, trailing white" STDOUT_NL);
 printf("space is removed and blank lines are ignored." STDOUT_NL);
 printf("The maximum size of any pattern is %d bytes." STDOUT_NL, MAXPATLEN);
@@ -1100,12 +1276,12 @@
 *            Read one line of input              *
 *************************************************/
 
-/* Normally, input is read using fread() into a large buffer, so many lines may
-be read at once. However, doing this for tty input means that no output appears
-until a lot of input has been typed. Instead, tty input is handled line by
-line. We cannot use fgets() for this, because it does not stop at a binary
-zero, and therefore there is no way of telling how many characters it has read,
-because there may be binary zeros embedded in the data.
+/* Normally, input is read using fread() (or gzread, or BZ2_read) into a large
+buffer, so many lines may be read at once. However, doing this for tty input
+means that no output appears until a lot of input has been typed. Instead, tty
+input is handled line by line. We cannot use fgets() for this, because it does
+not stop at a binary zero, and therefore there is no way of telling how many
+characters it has read, because there may be binary zeros embedded in the data.
 
 Arguments:
   buffer     the buffer to read into
@@ -1172,6 +1348,16 @@
   *lenptr = 0;
   return endptr;
 
+  case PCRE2_NEWLINE_NUL:
+  while (p < endptr && *p != '\0') p++;
+  if (p < endptr)
+    {
+    *lenptr = 1;
+    return p + 1;
+    }
+  *lenptr = 0;
+  return endptr;
+
   case PCRE2_NEWLINE_CRLF:
   for (;;)
     {
@@ -1193,7 +1379,7 @@
   while (p < endptr)
     {
     int extra = 0;
-    register int c = *((unsigned char *)p);
+    int c = *((unsigned char *)p);
 
     if (utf && c >= 0xc0)
       {
@@ -1237,7 +1423,7 @@
   while (p < endptr)
     {
     int extra = 0;
-    register int c = *((unsigned char *)p);
+    int c = *((unsigned char *)p);
 
     if (utf && c >= 0xc0)
       {
@@ -1323,6 +1509,11 @@
   while (p > startptr && p[-1] != '\n') p--;
   return p;
 
+  case PCRE2_NEWLINE_NUL:
+  p--;
+  while (p > startptr && p[-1] != '\0') p--;
+  return p;
+
   case PCRE2_NEWLINE_CRLF:
   for (;;)
     {
@@ -1339,7 +1530,7 @@
 
   while (p > startptr)
     {
-    register unsigned int c;
+    unsigned int c;
     char *pp = p - 1;
 
     if (utf)
@@ -1378,7 +1569,7 @@
       case '\v':    /* VT */
       case '\f':    /* FF */
       case '\r':    /* CR */
-#ifndef EBCDIE
+#ifndef EBCDIC
       case 0x85:    /* Unicode NEL */
       case 0x2028:  /* Unicode LS */
       case 0x2029:  /* Unicode PS */
@@ -1398,8 +1589,6 @@
 
 
 
-
-
 /*************************************************
 *       Print the previous "after" lines         *
 *************************************************/
@@ -1418,23 +1607,24 @@
 */
 
 static void
-do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr,
-  char *printname)
+do_after_lines(unsigned long int lastmatchnumber, char *lastmatchrestart,
+  char *endptr, const char *printname)
 {
 if (after_context > 0 && lastmatchnumber > 0)
   {
   int count = 0;
-  while (lastmatchrestart < endptr && count++ < after_context)
+  while (lastmatchrestart < endptr && count < after_context)
     {
     int ellength;
-    char *pp = lastmatchrestart;
+    char *pp = end_of_line(lastmatchrestart, endptr, &ellength);
+    if (ellength == 0 && pp == main_buffer + bufsize) break;
     if (printname != NULL) fprintf(stdout, "%s-", printname);
-    if (number) fprintf(stdout, "%d-", lastmatchnumber++);
-    pp = end_of_line(pp, endptr, &ellength);
-    FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
+    if (number) fprintf(stdout, "%lu-", lastmatchnumber++);
+    FWRITE_IGNORE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
     lastmatchrestart = pp;
+    count++;
     }
-  hyphenpending = TRUE;
+  if (count > 0) hyphenpending = TRUE;
   }
 }
 
@@ -1483,10 +1673,10 @@
   fprintf(stderr, "pcre2grep: pcre2_match() gave error %d while matching ", *mrc);
   if (patterns->next != NULL) fprintf(stderr, "pattern number %d to ", i);
   fprintf(stderr, "%s", msg);
-  FWRITE(matchptr, 1, slen, stderr);   /* In case binary zero included */
+  FWRITE_IGNORE(matchptr, 1, slen, stderr);   /* In case binary zero included */
   fprintf(stderr, "\n\n");
-  if (*mrc == PCRE2_ERROR_MATCHLIMIT || *mrc == PCRE2_ERROR_RECURSIONLIMIT ||
-      *mrc == PCRE2_ERROR_JIT_STACKLIMIT)
+  if (*mrc == PCRE2_ERROR_MATCHLIMIT || *mrc == PCRE2_ERROR_DEPTHLIMIT ||
+      *mrc == PCRE2_ERROR_HEAPLIMIT || *mrc == PCRE2_ERROR_JIT_STACKLIMIT)
     resource_error = TRUE;
   if (error_count++ > 20)
     {
@@ -1500,6 +1690,277 @@
 }
 
 
+/*************************************************
+*          Check output text for errors          *
+*************************************************/
+
+static BOOL
+syntax_check_output_text(PCRE2_SPTR string, BOOL callout)
+{
+PCRE2_SPTR begin = string;
+for (; *string != 0; string++)
+  {
+  if (*string == '$')
+    {
+    PCRE2_SIZE capture_id = 0;
+    BOOL brace = FALSE;
+
+    string++;
+
+    /* Syntax error: a character must be present after $. */
+    if (*string == 0)
+      {
+      if (!callout)
+        fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
+          (int)(string - begin), "no character after $");
+      return FALSE;
+      }
+
+    if (*string == '{')
+      {
+      /* Must be a decimal number in braces, e.g: {5} or {38} */
+      string++;
+
+      brace = TRUE;
+      }
+
+    if ((*string >= '1' && *string <= '9') || (!callout && *string == '0'))
+      {
+      do
+        {
+        /* Maximum capture id is 65535. */
+        if (capture_id <= 65535)
+          capture_id = capture_id * 10 + (*string - '0');
+
+        string++;
+        }
+      while (*string >= '0' && *string <= '9');
+
+      if (brace)
+        {
+        /* Syntax error: closing brace is missing. */
+        if (*string != '}')
+          {
+          if (!callout)
+            fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
+              (int)(string - begin), "missing closing brace");
+          return FALSE;
+          }
+        }
+      else
+        {
+        /* To negate the effect of the for. */
+        string--;
+        }
+      }
+    else if (brace)
+      {
+      /* Syntax error: a decimal number required. */
+      if (!callout)
+        fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
+          (int)(string - begin), "decimal number expected");
+      return FALSE;
+      }
+    else if (*string == 'o')
+      {
+      string++;
+
+      if (*string < '0' || *string > '7')
+        {
+        /* Syntax error: an octal number required. */
+        if (!callout)
+          fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
+            (int)(string - begin), "octal number expected");
+        return FALSE;
+        }
+      }
+    else if (*string == 'x')
+      {
+      string++;
+
+      if (!isxdigit((unsigned char)*string))
+        {
+        /* Syntax error: a hexdecimal number required. */
+        if (!callout)
+          fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
+            (int)(string - begin), "hexadecimal number expected");
+        return FALSE;
+        }
+      }
+    }
+  }
+
+  return TRUE;
+}
+
+
+/*************************************************
+*              Display output text               *
+*************************************************/
+
+/* Display the output text, which is assumed to have already been syntax
+checked. Output may contain escape sequences started by the dollar sign. The
+escape sequences are substituted as follows:
+
+  $<digits> or ${<digits>} is replaced by the captured substring of the given
+  decimal number; zero will substitute the whole match. If the number is
+  greater than the number of capturing substrings, or if the capture is unset,
+  the replacement is empty.
+
+  $a is replaced by bell.
+  $b is replaced by backspace.
+  $e is replaced by escape.
+  $f is replaced by form feed.
+  $n is replaced by newline.
+  $r is replaced by carriage return.
+  $t is replaced by tab.
+  $v is replaced by vertical tab.
+
+  $o<digits> is replaced by the character represented by the given octal
+  number; up to three digits are processed.
+
+  $x<digits> is replaced by the character represented by the given hexadecimal
+  number; up to two digits are processed.
+
+  Any other character is substituted by itself. E.g: $$ is replaced by a single
+  dollar.
+
+Arguments:
+  string:       the output text
+  callout:      TRUE for the builtin callout, FALSE for --output
+  subject       the start of the subject
+  ovector:      capture offsets
+  capture_top:  number of captures
+
+Returns:        TRUE if something was output, other than newline
+                FALSE if nothing was output, or newline was last output
+*/
+
+static BOOL
+display_output_text(PCRE2_SPTR string, BOOL callout, PCRE2_SPTR subject,
+  PCRE2_SIZE *ovector, PCRE2_SIZE capture_top)
+{
+BOOL printed = FALSE;
+
+for (; *string != 0; string++)
+  {
+  int ch = EOF;
+  if (*string == '$')
+    {
+    PCRE2_SIZE capture_id = 0;
+    BOOL brace = FALSE;
+
+    string++;
+
+    if (*string == '{')
+      {
+      /* Must be a decimal number in braces, e.g: {5} or {38} */
+      string++;
+
+      brace = TRUE;
+      }
+
+    if ((*string >= '1' && *string <= '9') || (!callout && *string == '0'))
+      {
+      do
+        {
+        /* Maximum capture id is 65535. */
+        if (capture_id <= 65535)
+          capture_id = capture_id * 10 + (*string - '0');
+
+        string++;
+        }
+      while (*string >= '0' && *string <= '9');
+
+      if (!brace)
+        {
+        /* To negate the effect of the for. */
+        string--;
+        }
+
+      if (capture_id < capture_top)
+        {
+        PCRE2_SIZE capturesize;
+        capture_id *= 2;
+
+        capturesize = ovector[capture_id + 1] - ovector[capture_id];
+        if (capturesize > 0)
+          {
+          print_match(subject + ovector[capture_id], capturesize);
+          printed = TRUE;
+          }
+        }
+      }
+    else if (*string == 'a') ch = '\a';
+    else if (*string == 'b') ch = '\b';
+#ifndef EBCDIC
+    else if (*string == 'e') ch = '\033';
+#else
+    else if (*string == 'e') ch = '\047';
+#endif
+    else if (*string == 'f') ch = '\f';
+    else if (*string == 'r') ch = '\r';
+    else if (*string == 't') ch = '\t';
+    else if (*string == 'v') ch = '\v';
+    else if (*string == 'n')
+      {
+      fprintf(stdout, STDOUT_NL);
+      printed = FALSE;
+      }
+    else if (*string == 'o')
+      {
+      string++;
+
+      ch = *string - '0';
+      if (string[1] >= '0' && string[1] <= '7')
+        {
+        string++;
+        ch = ch * 8 + (*string - '0');
+        }
+      if (string[1] >= '0' && string[1] <= '7')
+        {
+        string++;
+        ch = ch * 8 + (*string - '0');
+        }
+      }
+    else if (*string == 'x')
+      {
+      string++;
+
+      if (*string >= '0' && *string <= '9')
+        ch = *string - '0';
+      else
+        ch = (*string | 0x20) - 'a' + 10;
+      if (isxdigit((unsigned char)string[1]))
+        {
+        string++;
+        ch *= 16;
+        if (*string >= '0' && *string <= '9')
+          ch += *string - '0';
+        else
+          ch += (*string | 0x20) - 'a' + 10;
+        }
+      }
+    else
+      {
+      ch = *string;
+      }
+    }
+  else
+    {
+    ch = *string;
+    }
+  if (ch != EOF)
+    {
+    fprintf(stdout, "%c", ch);
+    printed = TRUE;
+    }
+  }
+
+return printed;
+}
+
+
 #ifdef SUPPORT_PCRE2GREP_CALLOUT
 
 /*************************************************
@@ -1513,7 +1974,7 @@
 
   program_name|param1|param2|...
 
-Any substirng (including the program name) can contain escape sequences
+Any substring (including the program name) can contain escape sequences
 started by the dollar character. The escape sequences are substituted as
 follows:
 
@@ -1525,6 +1986,10 @@
   Any other character is substituted by itself. E.g: $$ is replaced by a single
   dollar or $| replaced by a pipe character.
 
+Alternatively, if string starts with pipe, the remainder is taken as an output
+string, same as --output. In this case, --om-separator is used to separate each
+callout, defaulting to newline.
+
 Example:
 
   echo -e "abcde\n12345" | pcre2grep \
@@ -1557,7 +2022,9 @@
 char *argsptr;
 char **argsvector;
 char **argsvectorptr;
+#ifndef WIN32
 pid_t pid;
+#endif
 int result = 0;
 
 (void)unused;   /* Avoid compiler warning */
@@ -1565,6 +2032,16 @@
 /* Only callout with strings are supported. */
 if (string == NULL || length == 0) return 0;
 
+/* If there's no command, output the remainder directly. */
+
+if (*string == '|')
+  {
+  string++;
+  if (!syntax_check_output_text(string, TRUE)) return 0;
+  (void)display_output_text(string, TRUE, subject, ovector, capture_top);
+  return 0;
+  }
+
 /* Checking syntax and compute the number of string fragments. Callout strings
 are ignored in case of a syntax error. */
 
@@ -1606,7 +2083,7 @@
       }
     else if (*string == '{')
       {
-      /* Must be a decimal number in parenthesis, e.g: (5) or (38) */
+      /* Must be a decimal number in braces, e.g: {5} or {38} */
       string++;
       length--;
 
@@ -1628,7 +2105,7 @@
         }
       while (*string >= '0' && *string <= '9');
 
-      /* Syntax error: close paren is missing. */
+      /* Syntax error: closing brace is missing. */
       if (*string != '}') return 0;
       }
 
@@ -1745,6 +2222,9 @@
 *argsptr++ = '\0';
 *argsvectorptr = NULL;
 
+#ifdef WIN32
+result = _spawnvp(_P_WAIT, argsvector[0], (const char * const *)argsvector);
+#else
 pid = fork();
 
 if (pid == 0)
@@ -1755,6 +2235,7 @@
   }
 else if (pid > 0)
   (void)waitpid(pid, &result, 0);
+#endif
 
 free(args);
 free(argsvector);
@@ -1770,6 +2251,35 @@
 
 
 /*************************************************
+*     Read a portion of the file into buffer     *
+*************************************************/
+
+static int
+fill_buffer(void *handle, int frtype, char *buffer, int length,
+  BOOL input_line_buffered)
+{
+(void)frtype;  /* Avoid warning when not used */
+
+#ifdef SUPPORT_LIBZ
+if (frtype == FR_LIBZ)
+  return gzread((gzFile)handle, buffer, length);
+else
+#endif
+
+#ifdef SUPPORT_LIBBZ2
+if (frtype == FR_LIBBZ2)
+  return BZ2_bzread((BZFILE *)handle, buffer, length);
+else
+#endif
+
+return (input_line_buffered ?
+  read_one_line(buffer, length, (FILE *)handle) :
+  fread(buffer, 1, length, (FILE *)handle));
+}
+
+
+
+/*************************************************
 *            Grep an individual file             *
 *************************************************/
 
@@ -1797,13 +2307,13 @@
 */
 
 static int
-pcre2grep(void *handle, int frtype, char *filename, char *printname)
+pcre2grep(void *handle, int frtype, const char *filename, const char *printname)
 {
 int rc = 1;
-int linenumber = 1;
-int lastmatchnumber = 0;
-int count = 0;
 int filepos = 0;
+unsigned long int linenumber = 1;
+unsigned long int lastmatchnumber = 0;
+unsigned long int count = 0;
 char *lastmatchrestart = NULL;
 char *ptr = main_buffer;
 char *endptr;
@@ -1813,59 +2323,36 @@
 BOOL input_line_buffered = line_buffered;
 FILE *in = NULL;                    /* Ensure initialized */
 
-#ifdef SUPPORT_LIBZ
-gzFile ingz = NULL;
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-BZFILE *inbz2 = NULL;
-#endif
-
-
 /* Do the first read into the start of the buffer and set up the pointer to end
 of what we have. In the case of libz, a non-zipped .gz file will be read as a
 plain file. However, if a .bz2 file isn't actually bzipped, the first read will
 fail. */
 
-(void)frtype;
-
-#ifdef SUPPORT_LIBZ
-if (frtype == FR_LIBZ)
-  {
-  ingz = (gzFile)handle;
-  bufflength = gzread (ingz, main_buffer, bufsize);
-  }
-else
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-if (frtype == FR_LIBBZ2)
-  {
-  inbz2 = (BZFILE *)handle;
-  bufflength = BZ2_bzread(inbz2, main_buffer, bufsize);
-  if ((int)bufflength < 0) return 2;   /* Gotcha: bufflength is size_t; */
-  }                                    /* without the cast it is unsigned. */
-else
-#endif
-
+if (frtype != FR_LIBZ && frtype != FR_LIBBZ2)
   {
   in = (FILE *)handle;
   if (is_file_tty(in)) input_line_buffered = TRUE;
-  bufflength = input_line_buffered?
-    read_one_line(main_buffer, bufsize, in) :
-    fread(main_buffer, 1, bufsize, in);
   }
+else input_line_buffered = FALSE;
+
+bufflength = fill_buffer(handle, frtype, main_buffer, bufsize,
+  input_line_buffered);
+
+#ifdef SUPPORT_LIBBZ2
+if (frtype == FR_LIBBZ2 && (int)bufflength < 0) return 2;   /* Gotcha: bufflength is size_t; */
+#endif
 
 endptr = main_buffer + bufflength;
 
 /* Unless binary-files=text, see if we have a binary file. This uses the same
 rule as GNU grep, namely, a search for a binary zero byte near the start of the
-file. */
+file. However, when the newline convention is binary zero, we can't do this. */
 
 if (binary_files != BIN_TEXT)
   {
-  binary =
-    memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL;
+  if (endlinetype != PCRE2_NEWLINE_NUL)
+    binary = memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength)
+      != NULL;
   if (binary && binary_files == BIN_NOMATCH) return 1;
   }
 
@@ -1880,7 +2367,6 @@
   int mrc = 0;
   unsigned int options = 0;
   BOOL match;
-  char *matchptr = ptr;
   char *t = ptr;
   size_t length, linelength;
   size_t startoffset = 0;
@@ -1899,18 +2385,61 @@
 
   /* Check to see if the line we are looking at extends right to the very end
   of the buffer without a line terminator. This means the line is too long to
-  handle. */
+  handle at the current buffer size. Until the buffer reaches its maximum size,
+  try doubling it and reading more data. */
 
   if (endlinelength == 0 && t == main_buffer + bufsize)
     {
-    fprintf(stderr, "pcre2grep: line %d%s%s is too long for the internal buffer\n"
-                    "pcre2grep: the buffer size is %d\n"
-                    "pcre2grep: use the --buffer-size option to change it\n",
-                    linenumber,
-                    (filename == NULL)? "" : " of file ",
-                    (filename == NULL)? "" : filename,
-                    bufthird);
-    return 2;
+    if (bufthird < max_bufthird)
+      {
+      char *new_buffer;
+      int new_bufthird = 2*bufthird;
+
+      if (new_bufthird > max_bufthird) new_bufthird = max_bufthird;
+      new_buffer = (char *)malloc(3*new_bufthird);
+
+      if (new_buffer == NULL)
+        {
+        fprintf(stderr,
+          "pcre2grep: line %lu%s%s is too long for the internal buffer\n"
+          "pcre2grep: not enough memory to increase the buffer size to %d\n",
+          linenumber,
+          (filename == NULL)? "" : " of file ",
+          (filename == NULL)? "" : filename,
+          new_bufthird);
+        return 2;
+        }
+
+      /* Copy the data and adjust pointers to the new buffer location. */
+
+      memcpy(new_buffer, main_buffer, bufsize);
+      bufthird = new_bufthird;
+      bufsize = 3*bufthird;
+      ptr = new_buffer + (ptr - main_buffer);
+      lastmatchrestart = new_buffer + (lastmatchrestart - main_buffer);
+      free(main_buffer);
+      main_buffer = new_buffer;
+
+      /* Read more data into the buffer and then try to find the line ending
+      again. */
+
+      bufflength += fill_buffer(handle, frtype, main_buffer + bufflength,
+        bufsize - bufflength, input_line_buffered);
+      endptr = main_buffer + bufflength;
+      continue;
+      }
+    else
+      {
+      fprintf(stderr,
+        "pcre2grep: line %lu%s%s is too long for the internal buffer\n"
+        "pcre2grep: the maximum buffer size is %d\n"
+        "pcre2grep: use the --max-buffer-size option to change it\n",
+        linenumber,
+        (filename == NULL)? "" : " of file ",
+        (filename == NULL)? "" : filename,
+        bufthird);
+      return 2;
+      }
     }
 
   /* Extra processing for Jeffrey Friedl's debugging. */
@@ -1963,8 +2492,8 @@
   }
 #endif
 
-  /* We come back here after a match when show_only_matching is set, in order
-  to find any further matches in the same line. This applies to
+  /* We come back here after a match when only_matching_count is non-zero, in
+  order to find any further matches in the same line. This applies to
   --only-matching, --file-offsets, and --line-offsets. */
 
   ONLY_MATCHING_RESTART:
@@ -1975,10 +2504,13 @@
   match, set PCRE2_NOTEMPTY to disable any further matches of null strings in
   this line. */
 
-  match = match_patterns(matchptr, length, options, startoffset, &mrc);
+  match = match_patterns(ptr, length, options, startoffset, &mrc);
   options = PCRE2_NOTEMPTY;
 
-  /* If it's a match or a not-match (as required), do what's wanted. */
+  /* If it's a match or a not-match (as required), do what's wanted. NOTE: Use
+  only FWRITE_IGNORE() - which is just a packaged fwrite() that ignores its
+  return code - to output data lines, so that binary zeroes are treated as just
+  another data character. */
 
   if (match != invert)
     {
@@ -1994,7 +2526,7 @@
 
     /* Just count if just counting is wanted. */
 
-    else if (count_only) count++;
+    else if (count_only || show_total_count) count++;
 
     /* When handling a binary file and binary-files==binary, the "binary"
     variable will be set true (it's false in all other cases). In this
@@ -2018,34 +2550,44 @@
     /* The --only-matching option prints just the substring that matched,
     and/or one or more captured portions of it, as long as these strings are
     not empty. The --file-offsets and --line-offsets options output offsets for
-    the matching substring (all three set show_only_matching). None of these
-    mutually exclusive options prints any context. Afterwards, adjust the start
-    and then jump back to look for further matches in the same line. If we are
-    in invert mode, however, nothing is printed and we do not restart - this
-    could still be useful because the return code is set. */
+    the matching substring (all three set only_matching_count non-zero). None
+    of these mutually exclusive options prints any context. Afterwards, adjust
+    the start and then jump back to look for further matches in the same line.
+    If we are in invert mode, however, nothing is printed and we do not restart
+    - this could still be useful because the return code is set. */
 
-    else if (show_only_matching)
+    else if (only_matching_count != 0)
       {
       if (!invert)
         {
         size_t oldstartoffset;
 
         if (printname != NULL) fprintf(stdout, "%s:", printname);
-        if (number) fprintf(stdout, "%d:", linenumber);
+        if (number) fprintf(stdout, "%lu:", linenumber);
 
         /* Handle --line-offsets */
 
         if (line_offsets)
-          fprintf(stdout, "%d,%d" STDOUT_NL, (int)(matchptr + offsets[0] - ptr),
+          fprintf(stdout, "%d,%d" STDOUT_NL, (int)(ptr + offsets[0] - ptr),
             (int)(offsets[1] - offsets[0]));
 
         /* Handle --file-offsets */
 
         else if (file_offsets)
           fprintf(stdout, "%d,%d" STDOUT_NL,
-            (int)(filepos + matchptr + offsets[0] - ptr),
+            (int)(filepos + ptr + offsets[0] - ptr),
             (int)(offsets[1] - offsets[0]));
 
+        /* Handle --output (which has already been syntax checked) */
+
+        else if (output_text != NULL)
+          {
+          if (display_output_text((PCRE2_SPTR)output_text, FALSE,
+              (PCRE2_SPTR)ptr, offsets, mrc) || printname != NULL ||
+              number)
+            fprintf(stdout, STDOUT_NL);
+          }
+
         /* Handle --only-matching, which may occur many times */
 
         else
@@ -2061,10 +2603,9 @@
               int plen = offsets[2*n + 1] - offsets[2*n];
               if (plen > 0)
                 {
-                if (printed) fprintf(stdout, "%s", om_separator);
-                if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
-                FWRITE(matchptr + offsets[n*2], 1, plen, stdout);
-                if (do_colour) fprintf(stdout, "%c[00m", 0x1b);
+                if (printed && om_separator != NULL)
+                  fprintf(stdout, "%s", om_separator);
+                print_match(ptr + offsets[n*2], plen);
                 printed = TRUE;
                 }
               }
@@ -2080,11 +2621,6 @@
         if (line_buffered) fflush(stdout);
         rc = 0;                      /* Had some success */
 
-        /* If the current match ended past the end of the line (only possible
-        in multiline mode), we are done with this line. */
-
-        if (offsets[1] > linelength) goto END_ONE_MATCH;
-
         /* If the pattern contained a lookbehind that included \K, it is
         possible that the end of the match might be at or before the actual
         starting offset we have just used. In this case, start one character
@@ -2096,9 +2632,24 @@
           {
           if (startoffset >= length) goto END_ONE_MATCH;  /* Were at end */
           startoffset = oldstartoffset + 1;
-          if (utf)
-            while ((matchptr[startoffset] & 0xc0) == 0x80) startoffset++;
+          if (utf) while ((ptr[startoffset] & 0xc0) == 0x80) startoffset++;
           }
+
+        /* If the current match ended past the end of the line (only possible
+        in multiline mode), we must move on to the line in which it did end
+        before searching for more matches. */
+
+        while (startoffset > linelength)
+          {
+          ptr += linelength + endlinelength;
+          filepos += (int)(linelength + endlinelength);
+          linenumber++;
+          startoffset -= (int)(linelength + endlinelength);
+          t = end_of_line(ptr, endptr, &endlinelength);
+          linelength = t - ptr - endlinelength;
+          length = (size_t)(endptr - ptr);
+          }
+
         goto ONLY_MATCHING_RESTART;
         }
       }
@@ -2132,9 +2683,9 @@
           {
           char *pp = lastmatchrestart;
           if (printname != NULL) fprintf(stdout, "%s-", printname);
-          if (number) fprintf(stdout, "%d-", lastmatchnumber++);
+          if (number) fprintf(stdout, "%lu-", lastmatchnumber++);
           pp = end_of_line(pp, endptr, &ellength);
-          FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
+          FWRITE_IGNORE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
           lastmatchrestart = pp;
           }
         if (lastmatchrestart != ptr) hyphenpending = TRUE;
@@ -2172,9 +2723,9 @@
           int ellength;
           char *pp = p;
           if (printname != NULL) fprintf(stdout, "%s-", printname);
-          if (number) fprintf(stdout, "%d-", linenumber - linecount--);
+          if (number) fprintf(stdout, "%lu-", linenumber - linecount--);
           pp = end_of_line(pp, endptr, &ellength);
-          FWRITE(p, 1, pp - p, stdout);
+          FWRITE_IGNORE(p, 1, pp - p, stdout);
           p = pp;
           }
         }
@@ -2186,28 +2737,7 @@
         endhyphenpending = TRUE;
 
       if (printname != NULL) fprintf(stdout, "%s:", printname);
-      if (number) fprintf(stdout, "%d:", linenumber);
-
-      /* In multiline mode, we want to print to the end of the line in which
-      the end of the matched string is found, so we adjust linelength and the
-      line number appropriately, but only when there actually was a match
-      (invert not set). Because the PCRE2_FIRSTLINE option is set, the start of
-      the match will always be before the first newline sequence. */
-
-      if (multiline & !invert)
-        {
-        char *endmatch = ptr + offsets[1];
-        t = ptr;
-        while (t <= endmatch)
-          {
-          t = end_of_line(t, endptr, &endlinelength);
-          if (t < endmatch) linenumber++; else break;
-          }
-        linelength = t - ptr - endlinelength;
-        }
-
-      /*** NOTE: Use only fwrite() to output the data line, so that binary
-      zeroes are treated as just another data character. */
+      if (number) fprintf(stdout, "%lu:", linenumber);
 
       /* This extra option, for Jeffrey Friedl's debugging requirements,
       replaces the matched string, or a specific captured string if it exists,
@@ -2218,46 +2748,109 @@
         {
         int first = S_arg * 2;
         int last  = first + 1;
-        FWRITE(ptr, 1, offsets[first], stdout);
+        FWRITE_IGNORE(ptr, 1, offsets[first], stdout);
         fprintf(stdout, "X");
-        FWRITE(ptr + offsets[last], 1, linelength - offsets[last], stdout);
+        FWRITE_IGNORE(ptr + offsets[last], 1, linelength - offsets[last], stdout);
         }
       else
 #endif
 
-      /* We have to split the line(s) up if colouring, and search for further
-      matches, but not of course if the line is a non-match. */
+      /* In multiline mode, or if colouring, we have to split the line(s) up
+      and search for further matches, but not of course if the line is a
+      non-match. In multiline mode this is necessary in case there is another
+      match that spans the end of the current line. When colouring we want to
+      colour all matches. */
 
-      if (do_colour && !invert)
+      if ((multiline || do_colour) && !invert)
         {
         int plength;
-        FWRITE(ptr, 1, offsets[0], stdout);
-        fprintf(stdout, "%c[%sm", 0x1b, colour_string);
-        FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
-        fprintf(stdout, "%c[00m", 0x1b);
+        PCRE2_SIZE endprevious;
+
+        /* The use of \K may make the end offset earlier than the start. In
+        this situation, swap them round. */
+
+        if (offsets[0] > offsets[1])
+          {
+          PCRE2_SIZE temp = offsets[0];
+          offsets[0] = offsets[1];
+          offsets[1] = temp;
+          }
+
+        FWRITE_IGNORE(ptr, 1, offsets[0], stdout);
+        print_match(ptr + offsets[0], offsets[1] - offsets[0]);
+
         for (;;)
           {
-          startoffset = offsets[1];
-          if (startoffset >= linelength + endlinelength ||
-              !match_patterns(matchptr, length, options, startoffset, &mrc))
-            break;
-          FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
-          fprintf(stdout, "%c[%sm", 0x1b, colour_string);
-          FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
-          fprintf(stdout, "%c[00m", 0x1b);
+          PCRE2_SIZE oldstartoffset = pcre2_get_startchar(match_data);
+
+          endprevious = offsets[1];
+          startoffset = endprevious;  /* Advance after previous match. */
+
+          /* If the pattern contained a lookbehind that included \K, it is
+          possible that the end of the match might be at or before the actual
+          starting offset we have just used. In this case, start one character
+          further on. */
+
+          if (startoffset <= oldstartoffset)
+            {
+            startoffset = oldstartoffset + 1;
+            if (utf) while ((ptr[startoffset] & 0xc0) == 0x80) startoffset++;
+            }
+
+          /* If the current match ended past the end of the line (only possible
+          in multiline mode), we must move on to the line in which it did end
+          before searching for more matches. Because the PCRE2_FIRSTLINE option
+          is set, the start of the match will always be before the first
+          newline sequence. */
+
+          while (startoffset > linelength + endlinelength)
+            {
+            ptr += linelength + endlinelength;
+            filepos += (int)(linelength + endlinelength);
+            linenumber++;
+            startoffset -= (int)(linelength + endlinelength);
+            endprevious -= (int)(linelength + endlinelength);
+            t = end_of_line(ptr, endptr, &endlinelength);
+            linelength = t - ptr - endlinelength;
+            length = (size_t)(endptr - ptr);
+            }
+
+          /* If startoffset is at the exact end of the line it means this
+          complete line was the final part of the match, so there is nothing
+          more to do. */
+
+          if (startoffset == linelength + endlinelength) break;
+
+          /* Otherwise, run a match from within the final line, and if found,
+          loop for any that may follow. */
+
+          if (!match_patterns(ptr, length, options, startoffset, &mrc)) break;
+
+          /* The use of \K may make the end offset earlier than the start. In
+          this situation, swap them round. */
+
+          if (offsets[0] > offsets[1])
+            {
+            PCRE2_SIZE temp = offsets[0];
+            offsets[0] = offsets[1];
+            offsets[1] = temp;
+            }
+
+          FWRITE_IGNORE(ptr + endprevious, 1, offsets[0] - endprevious, stdout);
+          print_match(ptr + offsets[0], offsets[1] - offsets[0]);
           }
 
         /* In multiline mode, we may have already printed the complete line
         and its line-ending characters (if they matched the pattern), so there
         may be no more to print. */
 
-        plength = (int)((linelength + endlinelength) - startoffset);
-        if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout);
+        plength = (int)((linelength + endlinelength) - endprevious);
+        if (plength > 0) FWRITE_IGNORE(ptr + endprevious, 1, plength, stdout);
         }
 
-      /* Not colouring; no need to search for further matches */
+      /* Not colouring or multiline; no need to search for further matches. */
 
-      else FWRITE(ptr, 1, linelength + endlinelength, stdout);
+      else FWRITE_IGNORE(ptr, 1, linelength + endlinelength, stdout);
       }
 
     /* End of doing what has to be done for a match. If --line-buffered was
@@ -2321,7 +2914,7 @@
         lastmatchrestart < main_buffer + bufthird)
       {
       do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
-      lastmatchnumber = 0;
+      lastmatchnumber = 0;  /* Indicates no after lines pending */
       }
 
     /* Now do the shuffle */
@@ -2329,24 +2922,8 @@
     memmove(main_buffer, main_buffer + bufthird, 2*bufthird);
     ptr -= bufthird;
 
-#ifdef SUPPORT_LIBZ
-    if (frtype == FR_LIBZ)
-      bufflength = 2*bufthird +
-        gzread (ingz, main_buffer + 2*bufthird, bufthird);
-    else
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-    if (frtype == FR_LIBBZ2)
-      bufflength = 2*bufthird +
-        BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird);
-    else
-#endif
-
-    bufflength = 2*bufthird +
-      (input_line_buffered?
-       read_one_line(main_buffer + 2*bufthird, bufthird, in) :
-       fread(main_buffer + 2*bufthird, 1, bufthird, in));
+    bufflength = 2*bufthird + fill_buffer(handle, frtype,
+      main_buffer + 2*bufthird, bufthird, input_line_buffered);
     endptr = main_buffer + bufflength;
 
     /* Adjust any last match point */
@@ -2358,7 +2935,7 @@
 /* End of file; print final "after" lines if wanted; do_after_lines sets
 hyphenpending if it prints something. */
 
-if (!show_only_matching && !count_only)
+if (only_matching_count == 0 && !(count_only|show_total_count))
   {
   do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
   hyphenpending |= endhyphenpending;
@@ -2381,10 +2958,12 @@
     {
     if (printname != NULL && filenames != FN_NONE)
       fprintf(stdout, "%s:", printname);
-    fprintf(stdout, "%d" STDOUT_NL, count);
+    fprintf(stdout, "%lu" STDOUT_NL, count);
+    counts_printed++;
     }
   }
 
+total_count += count;   /* Can be set without count_only */
 return rc;
 }
 
@@ -2503,7 +3082,7 @@
 
   if (dee_action == dee_RECURSE)
     {
-    char buffer[1024];
+    char buffer[FNBUFSIZ];
     char *nextfile;
     directory_type *dir = opendirectory(pathname);
 
@@ -2518,7 +3097,14 @@
     while ((nextfile = readdirectory(dir)) != NULL)
       {
       int frc;
-      sprintf(buffer, "%.512s%c%.128s", pathname, FILESEP, nextfile);
+      int fnlength = strlen(pathname) + strlen(nextfile) + 2;
+      if (fnlength > FNBUFSIZ)
+        {
+        fprintf(stderr, "pcre2grep: recursive filename is too long\n");
+        rc = 2;
+        break;
+        }
+      sprintf(buffer, "%s%c%s", pathname, FILESEP, nextfile);
       frc = grep_or_recurse(buffer, dir_recurse, FALSE);
       if (frc > 1) rc = frc;
        else if (frc == 0 && rc == 1) rc = 0;
@@ -2529,6 +3115,36 @@
     }
   }
 
+#ifdef WIN32
+if (iswild(pathname))
+  {
+  char buffer[1024];
+  char *nextfile;
+  char *name;
+  directory_type *dir = opendirectory(pathname);
+
+  if (dir == NULL)
+    return 0;
+
+  for (nextfile = name = pathname; *nextfile != 0; nextfile++)
+    if (*nextfile == '/' || *nextfile == '\\')
+      name = nextfile + 1;
+  *name = 0;
+
+  while ((nextfile = readdirectory(dir)) != NULL)
+    {
+    int frc;
+    sprintf(buffer, "%.512s%.128s", pathname, nextfile);
+    frc = grep_or_recurse(buffer, dir_recurse, FALSE);
+    if (frc > 1) rc = frc;
+     else if (frc == 0 && rc == 1) rc = 0;
+    }
+
+  closedirectory(dir);
+  return rc;
+  }
+#endif
+
 #if defined NATIVE_ZOS
  }
 #endif
@@ -2669,13 +3285,13 @@
 switch(letter)
   {
   case N_FOFFSETS: file_offsets = TRUE; break;
-  case N_HELP: help(); pcre2grep_exit(0);
+  case N_HELP: help(); pcre2grep_exit(0); break; /* Stops compiler warning */
   case N_LBUFFER: line_buffered = TRUE; break;
   case N_LOFFSETS: line_offsets = number = TRUE; break;
   case N_NOJIT: use_jit = FALSE; break;
   case 'a': binary_files = BIN_TEXT; break;
   case 'c': count_only = TRUE; break;
-  case 'F': process_options |= PO_FIXED_STRINGS; break;
+  case 'F': options |= PCRE2_LITERAL; break;
   case 'H': filenames = FN_FORCE; break;
   case 'I': binary_files = BIN_NOMATCH; break;
   case 'h': filenames = FN_NONE; break;
@@ -2693,10 +3309,11 @@
   case 'q': quiet = TRUE; break;
   case 'r': dee_action = dee_RECURSE; break;
   case 's': silent = TRUE; break;
+  case 't': show_total_count = TRUE; break;
   case 'u': options |= PCRE2_UTF; utf = TRUE; break;
   case 'v': invert = TRUE; break;
-  case 'w': process_options |= PO_WORD_MATCH; break;
-  case 'x': process_options |= PO_LINE_MATCH; break;
+  case 'w': extra_options |= PCRE2_EXTRA_MATCH_WORD; break;
+  case 'x': extra_options |= PCRE2_EXTRA_MATCH_LINE; break;
 
   case 'V':
     {
@@ -2717,7 +3334,6 @@
 
 
 
-
 /*************************************************
 *          Construct printed ordinal             *
 *************************************************/
@@ -2731,6 +3347,8 @@
 char *p = buffer;
 sprintf(p, "%d", n);
 while (*p != 0) p++;
+n %= 100;
+if (n >= 11 && n <= 13) n = 0;
 switch (n%10)
   {
   case 1: strcpy(p, "st"); break;
@@ -2758,7 +3376,6 @@
 Arguments:
   p              points to the pattern block
   options        the PCRE options
-  popts          the processing options
   fromfile       TRUE if the pattern was read from a file
   fromtext       file name or identifying text (e.g. "include")
   count          0 if this is the only command line pattern, or
@@ -2769,18 +3386,20 @@
 */
 
 static BOOL
-compile_pattern(patstr *p, int options, int popts, int fromfile,
-  const char *fromtext, int count)
+compile_pattern(patstr *p, int options, int fromfile, const char *fromtext,
+  int count)
 {
-unsigned char buffer[PATBUFSIZE];
-PCRE2_SIZE erroffset;
-char *ps = p->string;
-unsigned int patlen = strlen(ps);
+char *ps;
 int errcode;
+PCRE2_SIZE patlen, erroffset;
+PCRE2_UCHAR errmessbuffer[ERRBUFSIZ];
 
 if (p->compiled != NULL) return TRUE;
 
-if ((popts & PO_FIXED_STRINGS) != 0)
+ps = p->string;
+patlen = strlen(ps);
+
+if ((options & PCRE2_LITERAL) != 0)
   {
   int ellength;
   char *eop = ps + patlen;
@@ -2793,45 +3412,39 @@
     }
   }
 
-sprintf((char *)buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]);
-p->compiled = pcre2_compile(buffer, PCRE2_ZERO_TERMINATED, options, &errcode,
+p->compiled = pcre2_compile((PCRE2_SPTR)ps, patlen, options, &errcode,
   &erroffset, compile_context);
 
-/* Handle successful compile */
+/* Handle successful compile. Try JIT-compiling if supported and enabled. We
+ignore any JIT compiler errors, relying falling back to interpreting if
+anything goes wrong with JIT. */
 
 if (p->compiled != NULL)
   {
 #ifdef SUPPORT_PCRE2GREP_JIT
-  if (use_jit)
-    {
-    errcode = pcre2_jit_compile(p->compiled, PCRE2_JIT_COMPLETE);
-    if (errcode == 0) return TRUE;
-    erroffset = PCRE2_SIZE_MAX;     /* Will get reduced to patlen below */
-    }
-  else
+  if (use_jit) (void)pcre2_jit_compile(p->compiled, PCRE2_JIT_COMPLETE);
 #endif
   return TRUE;
   }
 
-/* Handle compile and JIT compile errors */
+/* Handle compile errors */
 
-erroffset -= (int)strlen(prefix[popts]);
 if (erroffset > patlen) erroffset = patlen;
-pcre2_get_error_message(errcode, buffer, PATBUFSIZE);
+pcre2_get_error_message(errcode, errmessbuffer, sizeof(errmessbuffer));
 
 if (fromfile)
   {
   fprintf(stderr, "pcre2grep: Error in regex in line %d of %s "
-    "at offset %d: %s\n", count, fromtext, (int)erroffset, buffer);
+    "at offset %d: %s\n", count, fromtext, (int)erroffset, errmessbuffer);
   }
 else
   {
   if (count == 0)
     fprintf(stderr, "pcre2grep: Error in %s regex at offset %d: %s\n",
-      fromtext, (int)erroffset, buffer);
+      fromtext, (int)erroffset, errmessbuffer);
   else
     fprintf(stderr, "pcre2grep: Error in %s %s regex at offset %d: %s\n",
-      ordin(count), fromtext, (int)erroffset, buffer);
+      ordin(count), fromtext, (int)erroffset, errmessbuffer);
   }
 
 return FALSE;
@@ -2849,18 +3462,17 @@
   name         the name of the file; "-" is stdin
   patptr       pointer to the pattern chain anchor
   patlastptr   pointer to the last pattern pointer
-  popts        the process options to pass to pattern_compile()
 
 Returns:       TRUE if all went well
 */
 
 static BOOL
-read_pattern_file(char *name, patstr **patptr, patstr **patlastptr, int popts)
+read_pattern_file(char *name, patstr **patptr, patstr **patlastptr)
 {
 int linenumber = 0;
 FILE *f;
-char *filename;
-char buffer[PATBUFSIZE];
+const char *filename;
+char buffer[MAXPATLEN+20];
 
 if (strcmp(name, "-") == 0)
   {
@@ -2878,7 +3490,7 @@
   filename = name;
   }
 
-while (fgets(buffer, PATBUFSIZE, f) != NULL)
+while (fgets(buffer, sizeof(buffer), f) != NULL)
   {
   char *s = buffer + (int)strlen(buffer);
   while (s > buffer && isspace((unsigned char)(s[-1]))) s--;
@@ -2906,7 +3518,7 @@
 
   for(;;)
     {
-    if (!compile_pattern(*patlastptr, pcre2_options, popts, TRUE, filename,
+    if (!compile_pattern(*patlastptr, pcre2_options, TRUE, filename,
         linenumber))
       {
       if (f != stdin) fclose(f);
@@ -2950,8 +3562,8 @@
 that stdout is a binary stream. Note that this means all other output to stdout
 must use STDOUT_NL to terminate lines. */
 
-#if defined(_WIN32) || defined(WIN32)
-_setmode( _fileno(stdout), _O_BINARY);
+#ifdef WIN32
+_setmode(_fileno(stdout), _O_BINARY);
 #endif
 
 /* Set up a default compile and match contexts and a match data block. */
@@ -3174,7 +3786,7 @@
     switch (op->one_char)
       {
       case N_COLOUR:
-      colour_option = (char *)"auto";
+      colour_option = "auto";
       break;
 
       case 'o':
@@ -3268,7 +3880,7 @@
   /* Otherwise, deal with a single string or numeric data value. */
 
   else if (op->type != OP_NUMBER && op->type != OP_U32NUMBER &&
-           op->type != OP_OP_NUMBER)
+           op->type != OP_OP_NUMBER && op->type != OP_SIZE)
     {
     *((char **)op->dataptr) = option_data;
     }
@@ -3276,6 +3888,7 @@
     {
     unsigned long int n = decode_number(option_data, op, longop);
     if (op->type == OP_U32NUMBER) *((uint32_t *)op->dataptr) = n;
+      else if (op->type == OP_SIZE) *((PCRE2_SIZE *)op->dataptr) = n;
       else *((int *)op->dataptr) = n;
     }
   }
@@ -3289,25 +3902,31 @@
   if (before_context == 0) before_context = both_context;
   }
 
-/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.
-However, all three set show_only_matching because they display, each in their
-own way, only the data that has matched. */
+/* Only one of --only-matching, --output, --file-offsets, or --line-offsets is
+permitted. They display, each in their own way, only the data that has matched.
+*/
 
-if ((only_matching != NULL && (file_offsets || line_offsets)) ||
-    (file_offsets && line_offsets))
+only_matching_count = (only_matching != NULL) + (output_text != NULL) +
+  file_offsets + line_offsets;
+
+if (only_matching_count > 1)
   {
-  fprintf(stderr, "pcre2grep: Cannot mix --only-matching, --file-offsets "
-    "and/or --line-offsets\n");
+  fprintf(stderr, "pcre2grep: Cannot mix --only-matching, --output, "
+    "--file-offsets and/or --line-offsets\n");
   pcre2grep_exit(usage(2));
   }
 
+/* Check the text supplied to --output for errors. */
+
+if (output_text != NULL &&
+    !syntax_check_output_text((PCRE2_SPTR)output_text, FALSE))
+  goto EXIT2;
+
 /* Put limits into the match data block. */
 
+if (heap_limit != PCRE2_UNSET) pcre2_set_heap_limit(match_context, heap_limit);
 if (match_limit > 0) pcre2_set_match_limit(match_context, match_limit);
-if (recursion_limit > 0) pcre2_set_recursion_limit(match_context, recursion_limit);
-
-if (only_matching != NULL || file_offsets || line_offsets)
-  show_only_matching = TRUE;
+if (depth_limit > 0) pcre2_set_depth_limit(match_context, depth_limit);
 
 /* If a locale has not been provided as an option, see if the LC_CTYPE or
 LC_ALL environment variable is set, and if so, use it. */
@@ -3315,7 +3934,7 @@
 if (locale == NULL)
   {
   locale = getenv("LC_ALL");
-  locale_from = "LCC_ALL";
+  locale_from = "LC_ALL";
   }
 
 if (locale == NULL)
@@ -3343,7 +3962,11 @@
 
 if (colour_option != NULL && strcmp(colour_option, "never") != 0)
   {
-  if (strcmp(colour_option, "always") == 0) do_colour = TRUE;
+  if (strcmp(colour_option, "always") == 0)
+#ifdef WIN32
+    do_ansi = !is_stdout_tty(),
+#endif
+    do_colour = TRUE;
   else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty();
   else
     {
@@ -3355,7 +3978,17 @@
     {
     char *cs = getenv("PCRE2GREP_COLOUR");
     if (cs == NULL) cs = getenv("PCRE2GREP_COLOR");
-    if (cs != NULL) colour_string = cs;
+    if (cs == NULL) cs = getenv("PCREGREP_COLOUR");
+    if (cs == NULL) cs = getenv("PCREGREP_COLOR");
+    if (cs == NULL) cs = parse_grep_colors(getenv("GREP_COLORS"));
+    if (cs == NULL) cs = getenv("GREP_COLOR");
+    if (cs != NULL)
+      {
+      if (strspn(cs, ";0123456789") == strlen(cs)) colour_string = cs;
+      }
+#ifdef WIN32
+    init_colour_output();
+#endif
     }
   }
 
@@ -3410,6 +4043,10 @@
     }
   }
 
+/* Set the extra options */
+
+(void)pcre2_set_compile_extra_options(compile_context, extra_options);
+
 /* Check the values for Jeffrey Friedl's debugging options. */
 
 #ifdef JFRIEDL_DEBUG
@@ -3425,8 +4062,24 @@
   }
 #endif
 
+/* If use_jit is set, check whether JIT is available. If not, do not try
+to use JIT. */
+
+if (use_jit)
+  {
+  uint32_t answer;
+  (void)pcre2_config(PCRE2_CONFIG_JIT, &answer);
+  if (!answer) use_jit = FALSE;
+  }
+
 /* Get memory for the main buffer. */
 
+if (bufthird <= 0)
+  {
+  fprintf(stderr, "pcre2grep: --buffer-size must be greater than zero\n");
+  goto EXIT2;
+  }
+
 bufsize = 3*bufthird;
 main_buffer = (char *)malloc(bufsize);
 
@@ -3454,7 +4107,7 @@
 
 for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next)
   {
-  if (!compile_pattern(cp, pcre2_options, process_options, FALSE, "command-line",
+  if (!compile_pattern(cp, pcre2_options, FALSE, "command-line",
        (j == 1 && patterns->next == NULL)? 0 : j))
     goto EXIT2;
   }
@@ -3463,35 +4116,35 @@
 
 for (fn = pattern_files; fn != NULL; fn = fn->next)
   {
-  if (!read_pattern_file(fn->name, &patterns, &patterns_last, process_options))
-    goto EXIT2;
+  if (!read_pattern_file(fn->name, &patterns, &patterns_last)) goto EXIT2;
   }
 
 /* Unless JIT has been explicitly disabled, arrange a stack for it to use. */
 
 #ifdef SUPPORT_PCRE2GREP_JIT
 if (use_jit)
+  {
   jit_stack = pcre2_jit_stack_create(32*1024, 1024*1024, NULL);
+  if (jit_stack != NULL                        )
+    pcre2_jit_stack_assign(match_context, NULL, jit_stack);
+  }
 #endif
 
-for (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next)
-  {
-#ifdef SUPPORT_PCRE2GREP_JIT
-  if (jit_stack != NULL && cp->compiled != NULL)
-    pcre2_jit_stack_assign(match_context, NULL, jit_stack);
-#endif
-  }
+/* -F, -w, and -x do not apply to include or exclude patterns, so we must
+adjust the options. */
+
+pcre2_options &= ~PCRE2_LITERAL;
+(void)pcre2_set_compile_extra_options(compile_context, 0);
 
 /* If there are include or exclude patterns read from the command line, compile
-them. -F, -w, and -x do not apply, so the third argument of compile_pattern is
-0. */
+them. */
 
 for (j = 0; j < 4; j++)
   {
   int k;
   for (k = 1, cp = *(incexlist[j]); cp != NULL; k++, cp = cp->next)
     {
-    if (!compile_pattern(cp, pcre2_options, 0, FALSE, incexname[j],
+    if (!compile_pattern(cp, pcre2_options, FALSE, incexname[j],
          (k == 1 && cp->next == NULL)? 0 : k))
       goto EXIT2;
     }
@@ -3501,13 +4154,13 @@
 
 for (fn = include_from; fn != NULL; fn = fn->next)
   {
-  if (!read_pattern_file(fn->name, &include_patterns, &include_patterns_last, 0))
+  if (!read_pattern_file(fn->name, &include_patterns, &include_patterns_last))
     goto EXIT2;
   }
 
 for (fn = exclude_from; fn != NULL; fn = fn->next)
   {
-  if (!read_pattern_file(fn->name, &exclude_patterns, &exclude_patterns_last, 0))
+  if (!read_pattern_file(fn->name, &exclude_patterns, &exclude_patterns_last))
     goto EXIT2;
   }
 
@@ -3526,7 +4179,7 @@
 
 for (fn = file_lists; fn != NULL; fn = fn->next)
   {
-  char buffer[PATBUFSIZE];
+  char buffer[FNBUFSIZ];
   FILE *fl;
   if (strcmp(fn->name, "-") == 0) fl = stdin; else
     {
@@ -3538,7 +4191,7 @@
       goto EXIT2;
       }
     }
-  while (fgets(buffer, PATBUFSIZE, fl) != NULL)
+  while (fgets(buffer, sizeof(buffer), fl) != NULL)
     {
     int frc;
     char *end = buffer + (int)strlen(buffer);
@@ -3568,6 +4221,24 @@
     else if (frc == 0 && rc == 1) rc = 0;
   }
 
+#ifdef SUPPORT_PCRE2GREP_CALLOUT
+/* If separating builtin echo callouts by implicit newline, add one more for
+the final item. */
+
+if (om_separator != NULL && strcmp(om_separator, STDOUT_NL) == 0)
+  fprintf(stdout, STDOUT_NL);
+#endif
+
+/* Show the total number of matches if requested, but not if only one file's
+count was printed. */
+
+if (show_total_count && counts_printed != 1 && filenames != FN_NOMATCH_ONLY)
+  {
+  if (counts_printed != 0 && filenames >= FN_DEFAULT)
+    fprintf(stdout, "TOTAL:");
+  fprintf(stdout, "%lu" STDOUT_NL, total_count);
+  }
+
 EXIT:
 #ifdef SUPPORT_PCRE2GREP_JIT
 if (jit_stack != NULL) pcre2_jit_stack_free(jit_stack);
diff --git a/dist2/src/pcre2posix.c b/dist2/src/pcre2posix.c
index e7cf9c2..026943e 100644
--- a/dist2/src/pcre2posix.c
+++ b/dist2/src/pcre2posix.c
@@ -142,6 +142,7 @@
   32, REG_INVARG,  /* this version of PCRE2 does not have Unicode support */
   37, REG_EESCAPE, /* PCRE2 does not support \L, \l, \N{name}, \U, or \u */
   56, REG_INVARG,  /* internal error: unknown newline setting */
+  92, REG_INVARG,  /* invalid option bits with PCRE2_LITERAL */
 };
 
 /* Table of texts corresponding to POSIX error codes */
@@ -231,20 +232,25 @@
 regcomp(regex_t *preg, const char *pattern, int cflags)
 {
 PCRE2_SIZE erroffset;
+PCRE2_SIZE patlen;
 int errorcode;
 int options = 0;
 int re_nsub = 0;
 
+patlen = ((cflags & REG_PEND) != 0)? (PCRE2_SIZE)(preg->re_endp - pattern) :
+  PCRE2_ZERO_TERMINATED;
+
 if ((cflags & REG_ICASE) != 0)    options |= PCRE2_CASELESS;
 if ((cflags & REG_NEWLINE) != 0)  options |= PCRE2_MULTILINE;
 if ((cflags & REG_DOTALL) != 0)   options |= PCRE2_DOTALL;
+if ((cflags & REG_NOSPEC) != 0)   options |= PCRE2_LITERAL;
 if ((cflags & REG_UTF) != 0)      options |= PCRE2_UTF;
 if ((cflags & REG_UCP) != 0)      options |= PCRE2_UCP;
 if ((cflags & REG_UNGREEDY) != 0) options |= PCRE2_UNGREEDY;
 
 preg->re_cflags = cflags;
-preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED,
-   options, &errorcode, &erroffset, NULL);
+preg->re_pcre2_code = pcre2_compile((PCRE2_SPTR)pattern, patlen, options,
+  &errorcode, &erroffset, NULL);
 preg->re_erroffset = erroffset;
 
 if (preg->re_pcre2_code == NULL)
@@ -259,7 +265,7 @@
 
   if (errorcode < (int)(sizeof(eint1)/sizeof(const int)))
     return eint1[errorcode];
-  for (i = 0; i < sizeof(eint2)/(2*sizeof(const int)); i += 2)
+  for (i = 0; i < sizeof(eint2)/sizeof(const int); i += 2)
     if (errorcode == eint2[i]) return eint2[i+1];
   return REG_BADPAT;
   }
@@ -286,8 +292,7 @@
 
 /* A suitable match_data block, large enough to hold all possible captures, was
 obtained when the pattern was compiled, to save having to allocate and free it
-for each match. If REG_NOSUB was specified at compile time, the
-PCRE_NO_AUTO_CAPTURE flag will be set. When this is the case, the nmatch and
+for each match. If REG_NOSUB was specified at compile time, the nmatch and
 pmatch arguments are ignored, and the only result is yes/no/error. */
 
 PCRE2POSIX_EXP_DEFN int PCRE2_CALL_CONVENTION
@@ -339,8 +344,8 @@
   if ((size_t)rc > nmatch) rc = (int)nmatch;
   for (i = 0; i < (size_t)rc; i++)
     {
-    pmatch[i].rm_so = ovector[i*2];
-    pmatch[i].rm_eo = ovector[i*2+1];
+    pmatch[i].rm_so = ovector[i*2] + so;
+    pmatch[i].rm_eo = ovector[i*2+1] + so;
     }
   for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
   return 0;
diff --git a/dist2/src/pcre2posix.h b/dist2/src/pcre2posix.h
index 5f2906a..4ae1d3c 100644
--- a/dist2/src/pcre2posix.h
+++ b/dist2/src/pcre2posix.h
@@ -56,12 +56,14 @@
 #define REG_NOTBOL    0x0004  /* Maps to PCRE2_NOTBOL */
 #define REG_NOTEOL    0x0008  /* Maps to PCRE2_NOTEOL */
 #define REG_DOTALL    0x0010  /* NOT defined by POSIX; maps to PCRE2_DOTALL */
-#define REG_NOSUB     0x0020  /* Maps to PCRE2_NO_AUTO_CAPTURE */
+#define REG_NOSUB     0x0020  /* Do not report what was matched */
 #define REG_UTF       0x0040  /* NOT defined by POSIX; maps to PCRE2_UTF */
 #define REG_STARTEND  0x0080  /* BSD feature: pass subject string by so,eo */
 #define REG_NOTEMPTY  0x0100  /* NOT defined by POSIX; maps to PCRE2_NOTEMPTY */
 #define REG_UNGREEDY  0x0200  /* NOT defined by POSIX; maps to PCRE2_UNGREEDY */
 #define REG_UCP       0x0400  /* NOT defined by POSIX; maps to PCRE2_UCP */
+#define REG_PEND      0x0800  /* GNU feature: pass end pattern by re_endp */
+#define REG_NOSPEC    0x1000  /* Maps to PCRE2_LITERAL */
 
 /* This is not used by PCRE2, but by defining it we make it easier
 to slot PCRE2 into existing programs that make POSIX calls. */
@@ -91,11 +93,13 @@
 };
 
 
-/* The structure representing a compiled regular expression. */
+/* The structure representing a compiled regular expression. It is also used
+for passing the pattern end pointer when REG_PEND is set. */
 
 typedef struct {
   void *re_pcre2_code;
   void *re_match_data;
+  const char *re_endp;
   size_t re_nsub;
   size_t re_erroffset;
   int re_cflags;
diff --git a/dist2/src/pcre2test.c b/dist2/src/pcre2test.c
index a8dffa3..15bf404 100644
--- a/dist2/src/pcre2test.c
+++ b/dist2/src/pcre2test.c
@@ -11,7 +11,7 @@
 
                        Written by Philip Hazel
      Original code Copyright (c) 1997-2012 University of Cambridge
-         Rewritten code Copyright (c) 2016 University of Cambridge
+    Rewritten code Copyright (c) 2016-2017 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -78,6 +78,10 @@
 #include <unistd.h>
 #endif
 
+/* Debugging code enabler */
+
+// #define DEBUG_SHOW_MALLOC_ADDRESSES
+
 /* Both libreadline and libedit are optionally supported. The user-supplied
 original patch uses readline/readline.h for libedit, but in at least one system
 it is installed as editline/readline.h, so the configuration code now looks for
@@ -158,6 +162,13 @@
 void vms_setsymbol( char *, char *, int );
 #endif
 
+/* VC doesn't support "%td". */
+#ifdef _MSC_VER
+#define PTR_SPEC "%lu"
+#else
+#define PTR_SPEC "%td"
+#endif
+
 /* ------------------End of system-specific definitions -------------------- */
 
 /* Glueing macros that are used in several places below. */
@@ -175,15 +186,18 @@
 #endif
 #endif
 
-#define CFAIL_UNSET UINT32_MAX  /* Unset value for cfail fields */
-#define DFA_WS_DIMENSION 1000   /* Size of DFA workspace */
-#define DEFAULT_OVECCOUNT 15    /* Default ovector count */
-#define JUNK_OFFSET 0xdeadbeef  /* For initializing ovector */
-#define LOCALESIZE 32           /* Size of locale name */
-#define LOOPREPEAT 500000       /* Default loop count for timing */
-#define PATSTACKSIZE 20         /* Pattern stack for save/restore testing */
-#define REPLACE_MODSIZE 100     /* Field for reading 8-bit replacement */
-#define VERSION_SIZE 64         /* Size of buffer for the version strings */
+#define CFORE_UNSET UINT32_MAX    /* Unset value for startend/cfail/cerror fields */
+#define CONVERT_UNSET UINT32_MAX  /* Unset value for convert_type field */
+#define DFA_WS_DIMENSION 1000     /* Size of DFA workspace */
+#define DEFAULT_OVECCOUNT 15      /* Default ovector count */
+#define JUNK_OFFSET 0xdeadbeef    /* For initializing ovector */
+#define LOCALESIZE 32             /* Size of locale name */
+#define LOOPREPEAT 500000         /* Default loop count for timing */
+#define MALLOCLISTSIZE 20         /* For remembering mallocs */
+#define PARENS_NEST_DEFAULT 220   /* Default parentheses nest limit */
+#define PATSTACKSIZE 20           /* Pattern stack for save/restore testing */
+#define REPLACE_MODSIZE 100       /* Field for reading 8-bit replacement */
+#define VERSION_SIZE 64           /* Size of buffer for the version strings */
 
 /* Make sure the buffer into which replacement strings are copied is big enough
 to hold them as 32-bit code units. */
@@ -211,7 +225,7 @@
 #define PRINTABLE(c) ((c) >= 32 && (c) < 127)
 #endif
 
-#define PRINTOK(c) ((locale_tables != NULL)? isprint(c) : PRINTABLE(c))
+#define PRINTOK(c) ((use_tables != NULL && c < 256)? isprint(c) : PRINTABLE(c))
 
 /* We have to include some of the library source files because we need
 to use some of the macros, internal structure definitions, and other internal
@@ -312,7 +326,7 @@
 
 /* If we have 8-bit support, default to it; if there is also 16-or 32-bit
 support, it can be selected by a command-line option. If there is no 8-bit
-support, there must be 16- or 32-bit support, so default to one of them. The
+support, there must be 16-bit or 32-bit support, so default to one of them. The
 config function, JIT stack, contexts, and version string are the same in all
 modes, so use the form of the first that is available. */
 
@@ -323,8 +337,8 @@
 #define PCRE2_JIT_STACK pcre2_jit_stack_8
 #define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_8
 #define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_8
+#define PCRE2_REAL_CONVERT_CONTEXT pcre2_real_convert_context_8
 #define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_8
-#define VERSION_TYPE PCRE2_UCHAR8
 
 #elif defined SUPPORT_PCRE2_16
 #define DEFAULT_TEST_MODE PCRE16_MODE
@@ -333,6 +347,7 @@
 #define PCRE2_JIT_STACK pcre2_jit_stack_16
 #define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_16
 #define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_16
+#define PCRE2_REAL_CONVERT_CONTEXT pcre2_real_convert_context_16
 #define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_16
 
 #elif defined SUPPORT_PCRE2_32
@@ -342,6 +357,7 @@
 #define PCRE2_JIT_STACK pcre2_jit_stack_32
 #define PCRE2_REAL_GENERAL_CONTEXT pcre2_real_general_context_32
 #define PCRE2_REAL_COMPILE_CONTEXT pcre2_real_compile_context_32
+#define PCRE2_REAL_CONVERT_CONTEXT pcre2_real_convert_context_32
 #define PCRE2_REAL_MATCH_CONTEXT pcre2_real_match_context_32
 #endif
 
@@ -366,7 +382,7 @@
   { "save",            CMD_SAVE },
   { "subject",         CMD_SUBJECT }};
 
-#define cmdlistcount sizeof(cmdlist)/sizeof(cmdstruct)
+#define cmdlistcount (sizeof(cmdlist)/sizeof(cmdstruct))
 
 /* ------------- Structures and tables for handling modifiers -------------- */
 
@@ -374,7 +390,24 @@
 of PCRE2_NEWLINE_xx in pcre2.h. */
 
 static const char *newlines[] = {
-  "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF" };
+  "DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF", "NUL" };
+
+/* Structure and table for handling pattern conversion types. */
+
+typedef struct convertstruct {
+  const char *name;
+  uint32_t option;
+} convertstruct;
+
+static convertstruct convertlist[] = {
+  { "glob",                   PCRE2_CONVERT_GLOB },
+  { "glob_no_starstar",       PCRE2_CONVERT_GLOB_NO_STARSTAR },
+  { "glob_no_wild_separator", PCRE2_CONVERT_GLOB_NO_WILD_SEPARATOR },
+  { "posix_basic",            PCRE2_CONVERT_POSIX_BASIC },
+  { "posix_extended",         PCRE2_CONVERT_POSIX_EXTENDED },
+  { "unset",                  CONVERT_UNSET }};
+
+#define convertlistcount (sizeof(convertlist)/sizeof(convertstruct))
 
 /* Modifier types and applicability */
 
@@ -387,6 +420,8 @@
        MOD_PDP,    /* As MOD_PD, OK for Perl test */
        MOD_PND,    /* As MOD_PD, but not for a default pattern */
        MOD_PNDP,   /* As MOD_PND, OK for Perl test */
+       MOD_CHR,    /* Is a single character */
+       MOD_CON,    /* Is a "convert" type/options list */
        MOD_CTL,    /* Is a control bit */
        MOD_BSR,    /* Is a BSR value */
        MOD_IN2,    /* Is one or two unsigned integers */
@@ -415,33 +450,26 @@
 #define CTL_DFA                          0x00000200u
 #define CTL_EXPAND                       0x00000400u
 #define CTL_FINDLIMITS                   0x00000800u
-#define CTL_FULLBINCODE                  0x00001000u
-#define CTL_GETALL                       0x00002000u
-#define CTL_GLOBAL                       0x00004000u
-#define CTL_HEXPAT                       0x00008000u
-#define CTL_INFO                         0x00010000u
-#define CTL_JITFAST                      0x00020000u
-#define CTL_JITVERIFY                    0x00040000u
-#define CTL_MARK                         0x00080000u
-#define CTL_MEMORY                       0x00100000u
-#define CTL_NULLCONTEXT                  0x00200000u
-#define CTL_POSIX                        0x00400000u
-#define CTL_POSIX_NOSUB                  0x00800000u
-#define CTL_PUSH                         0x01000000u
-#define CTL_PUSHCOPY                     0x02000000u
-#define CTL_STARTCHAR                    0x04000000u
-#define CTL_ZERO_TERMINATE               0x08000000u
-/* Spare                                 0x10000000u  */
-/* Spare                                 0x20000000u  */
-#define CTL_NL_SET                       0x40000000u  /* Informational */
-#define CTL_BSR_SET                      0x80000000u  /* Informational */
-
-/* Second control word */
-
-#define CTL2_SUBSTITUTE_EXTENDED         0x00000001u
-#define CTL2_SUBSTITUTE_OVERFLOW_LENGTH  0x00000002u
-#define CTL2_SUBSTITUTE_UNKNOWN_UNSET    0x00000004u
-#define CTL2_SUBSTITUTE_UNSET_EMPTY      0x00000008u
+#define CTL_FRAMESIZE                    0x00001000u
+#define CTL_FULLBINCODE                  0x00002000u
+#define CTL_GETALL                       0x00004000u
+#define CTL_GLOBAL                       0x00008000u
+#define CTL_HEXPAT                       0x00010000u  /* Same word as USE_LENGTH */
+#define CTL_INFO                         0x00020000u
+#define CTL_JITFAST                      0x00040000u
+#define CTL_JITVERIFY                    0x00080000u
+#define CTL_MARK                         0x00100000u
+#define CTL_MEMORY                       0x00200000u
+#define CTL_NULLCONTEXT                  0x00400000u
+#define CTL_POSIX                        0x00800000u
+#define CTL_POSIX_NOSUB                  0x01000000u
+#define CTL_PUSH                         0x02000000u  /* These three must be */
+#define CTL_PUSHCOPY                     0x04000000u  /*   all in the same */
+#define CTL_PUSHTABLESCOPY               0x08000000u  /*     word. */
+#define CTL_STARTCHAR                    0x10000000u
+#define CTL_USE_LENGTH                   0x20000000u  /* Same word as HEXPAT */
+#define CTL_UTF8_INPUT                   0x40000000u
+#define CTL_ZERO_TERMINATE               0x80000000u
 
 /* Combinations */
 
@@ -449,8 +477,23 @@
 #define CTL_ANYINFO          (CTL_DEBUG|CTL_BINCODE|CTL_CALLOUT_INFO)
 #define CTL_ANYGLOB          (CTL_ALTGLOBAL|CTL_GLOBAL)
 
-/* These are all the controls that may be set either on a pattern or on a
-data line. */
+/* Second control word */
+
+#define CTL2_SUBSTITUTE_EXTENDED         0x00000001u
+#define CTL2_SUBSTITUTE_OVERFLOW_LENGTH  0x00000002u
+#define CTL2_SUBSTITUTE_UNKNOWN_UNSET    0x00000004u
+#define CTL2_SUBSTITUTE_UNSET_EMPTY      0x00000008u
+#define CTL2_SUBJECT_LITERAL             0x00000010u
+#define CTL2_CALLOUT_NO_WHERE            0x00000020u
+#define CTL2_CALLOUT_EXTRA               0x00000040u
+
+#define CTL2_NL_SET                      0x40000000u  /* Informational */
+#define CTL2_BSR_SET                     0x80000000u  /* Informational */
+
+/* These are the matching controls that may be set either on a pattern or on a
+data line. They are copied from the pattern controls as initial settings for
+data line controls Note that CTL_MEMORY is not included here, because it does
+different things in the two cases. */
 
 #define CTL_ALLPD  (CTL_AFTERTEXT|\
                     CTL_ALLAFTERTEXT|\
@@ -459,8 +502,8 @@
                     CTL_ALTGLOBAL|\
                     CTL_GLOBAL|\
                     CTL_MARK|\
-                    CTL_MEMORY|\
-                    CTL_STARTCHAR)
+                    CTL_STARTCHAR|\
+                    CTL_UTF8_INPUT)
 
 #define CTL2_ALLPD (CTL2_SUBSTITUTE_EXTENDED|\
                     CTL2_SUBSTITUTE_OVERFLOW_LENGTH|\
@@ -476,10 +519,15 @@
   uint32_t  options;       /* Must be in same position as datctl */
   uint32_t  control;       /* Must be in same position as datctl */
   uint32_t  control2;      /* Must be in same position as datctl */
+  uint32_t  jitstack;      /* Must be in same position as datctl */
    uint8_t  replacement[REPLACE_MODSIZE];  /* So must this */
   uint32_t  jit;
   uint32_t  stackguard_test;
   uint32_t  tables_id;
+  uint32_t  convert_type;
+  uint32_t  convert_length;
+  uint32_t  convert_glob_escape;
+  uint32_t  convert_glob_separator;
   uint32_t  regerror_buffsize;
    uint8_t  locale[LOCALESIZE];
 } patctl;
@@ -491,12 +539,14 @@
   uint32_t  options;       /* Must be in same position as patctl */
   uint32_t  control;       /* Must be in same position as patctl */
   uint32_t  control2;      /* Must be in same position as patctl */
+  uint32_t  jitstack;      /* Must be in same position as patctl */
    uint8_t  replacement[REPLACE_MODSIZE];  /* So must this */
+  uint32_t  startend[2];
+  uint32_t  cerror[2];
   uint32_t  cfail[2];
    int32_t  callout_data;
    int32_t  copy_numbers[MAXCPYGET];
    int32_t  get_numbers[MAXCPYGET];
-  uint32_t  jitstack;
   uint32_t  oveccount;
   uint32_t  offset;
   uint8_t   copy_names[LENCPYGET];
@@ -535,6 +585,7 @@
   { "allaftertext",               MOD_PNDP, MOD_CTL, CTL_ALLAFTERTEXT,           PO(control) },
   { "allcaptures",                MOD_PND,  MOD_CTL, CTL_ALLCAPTURES,            PO(control) },
   { "allow_empty_class",          MOD_PAT,  MOD_OPT, PCRE2_ALLOW_EMPTY_CLASS,    PO(options) },
+  { "allow_surrogate_escapes",    MOD_CTC,  MOD_OPT, PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES, CO(extra_options) },
   { "allusedtext",                MOD_PNDP, MOD_CTL, CTL_ALLUSEDTEXT,            PO(control) },
   { "alt_bsux",                   MOD_PAT,  MOD_OPT, PCRE2_ALT_BSUX,             PO(options) },
   { "alt_circumflex",             MOD_PAT,  MOD_OPT, PCRE2_ALT_CIRCUMFLEX,       PO(options) },
@@ -542,40 +593,56 @@
   { "altglobal",                  MOD_PND,  MOD_CTL, CTL_ALTGLOBAL,              PO(control) },
   { "anchored",                   MOD_PD,   MOD_OPT, PCRE2_ANCHORED,             PD(options) },
   { "auto_callout",               MOD_PAT,  MOD_OPT, PCRE2_AUTO_CALLOUT,         PO(options) },
+  { "bad_escape_is_literal",      MOD_CTC,  MOD_OPT, PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL, CO(extra_options) },
   { "bincode",                    MOD_PAT,  MOD_CTL, CTL_BINCODE,                PO(control) },
   { "bsr",                        MOD_CTC,  MOD_BSR, 0,                          CO(bsr_convention) },
   { "callout_capture",            MOD_DAT,  MOD_CTL, CTL_CALLOUT_CAPTURE,        DO(control) },
   { "callout_data",               MOD_DAT,  MOD_INS, 0,                          DO(callout_data) },
+  { "callout_error",              MOD_DAT,  MOD_IN2, 0,                          DO(cerror) },
+  { "callout_extra",              MOD_DAT,  MOD_CTL, CTL2_CALLOUT_EXTRA,         DO(control2) },
   { "callout_fail",               MOD_DAT,  MOD_IN2, 0,                          DO(cfail) },
   { "callout_info",               MOD_PAT,  MOD_CTL, CTL_CALLOUT_INFO,           PO(control) },
+  { "callout_no_where",           MOD_DAT,  MOD_CTL, CTL2_CALLOUT_NO_WHERE,      DO(control2) },
   { "callout_none",               MOD_DAT,  MOD_CTL, CTL_CALLOUT_NONE,           DO(control) },
   { "caseless",                   MOD_PATP, MOD_OPT, PCRE2_CASELESS,             PO(options) },
+  { "convert",                    MOD_PAT,  MOD_CON, 0,                          PO(convert_type) },
+  { "convert_glob_escape",        MOD_PAT,  MOD_CHR, 0,                          PO(convert_glob_escape) },
+  { "convert_glob_separator",     MOD_PAT,  MOD_CHR, 0,                          PO(convert_glob_separator) },
+  { "convert_length",             MOD_PAT,  MOD_INT, 0,                          PO(convert_length) },
   { "copy",                       MOD_DAT,  MOD_NN,  DO(copy_numbers),           DO(copy_names) },
   { "debug",                      MOD_PAT,  MOD_CTL, CTL_DEBUG,                  PO(control) },
+  { "depth_limit",                MOD_CTM,  MOD_INT, 0,                          MO(depth_limit) },
   { "dfa",                        MOD_DAT,  MOD_CTL, CTL_DFA,                    DO(control) },
   { "dfa_restart",                MOD_DAT,  MOD_OPT, PCRE2_DFA_RESTART,          DO(options) },
   { "dfa_shortest",               MOD_DAT,  MOD_OPT, PCRE2_DFA_SHORTEST,         DO(options) },
   { "dollar_endonly",             MOD_PAT,  MOD_OPT, PCRE2_DOLLAR_ENDONLY,       PO(options) },
   { "dotall",                     MOD_PATP, MOD_OPT, PCRE2_DOTALL,               PO(options) },
   { "dupnames",                   MOD_PATP, MOD_OPT, PCRE2_DUPNAMES,             PO(options) },
+  { "endanchored",                MOD_PD,   MOD_OPT, PCRE2_ENDANCHORED,          PD(options) },
   { "expand",                     MOD_PAT,  MOD_CTL, CTL_EXPAND,                 PO(control) },
   { "extended",                   MOD_PATP, MOD_OPT, PCRE2_EXTENDED,             PO(options) },
+  { "extended_more",              MOD_PATP, MOD_OPT, PCRE2_EXTENDED_MORE,        PO(options) },
   { "find_limits",                MOD_DAT,  MOD_CTL, CTL_FINDLIMITS,             DO(control) },
   { "firstline",                  MOD_PAT,  MOD_OPT, PCRE2_FIRSTLINE,            PO(options) },
+  { "framesize",                  MOD_PAT,  MOD_CTL, CTL_FRAMESIZE,              PO(control) },
   { "fullbincode",                MOD_PAT,  MOD_CTL, CTL_FULLBINCODE,            PO(control) },
   { "get",                        MOD_DAT,  MOD_NN,  DO(get_numbers),            DO(get_names) },
   { "getall",                     MOD_DAT,  MOD_CTL, CTL_GETALL,                 DO(control) },
   { "global",                     MOD_PNDP, MOD_CTL, CTL_GLOBAL,                 PO(control) },
+  { "heap_limit",                 MOD_CTM,  MOD_INT, 0,                          MO(heap_limit) },
   { "hex",                        MOD_PAT,  MOD_CTL, CTL_HEXPAT,                 PO(control) },
   { "info",                       MOD_PAT,  MOD_CTL, CTL_INFO,                   PO(control) },
   { "jit",                        MOD_PAT,  MOD_IND, 7,                          PO(jit) },
   { "jitfast",                    MOD_PAT,  MOD_CTL, CTL_JITFAST,                PO(control) },
-  { "jitstack",                   MOD_DAT,  MOD_INT, 0,                          DO(jitstack) },
+  { "jitstack",                   MOD_PNDP, MOD_INT, 0,                          PO(jitstack) },
   { "jitverify",                  MOD_PAT,  MOD_CTL, CTL_JITVERIFY,              PO(control) },
+  { "literal",                    MOD_PAT,  MOD_OPT, PCRE2_LITERAL,              PO(options) },
   { "locale",                     MOD_PAT,  MOD_STR, LOCALESIZE,                 PO(locale) },
   { "mark",                       MOD_PNDP, MOD_CTL, CTL_MARK,                   PO(control) },
   { "match_limit",                MOD_CTM,  MOD_INT, 0,                          MO(match_limit) },
+  { "match_line",                 MOD_CTC,  MOD_OPT, PCRE2_EXTRA_MATCH_LINE,     CO(extra_options) },
   { "match_unset_backref",        MOD_PAT,  MOD_OPT, PCRE2_MATCH_UNSET_BACKREF,  PO(options) },
+  { "match_word",                 MOD_CTC,  MOD_OPT, PCRE2_EXTRA_MATCH_WORD,     CO(extra_options) },
   { "max_pattern_length",         MOD_CTC,  MOD_SIZ, 0,                          CO(max_pattern_length) },
   { "memory",                     MOD_PD,   MOD_CTL, CTL_MEMORY,                 PD(control) },
   { "multiline",                  MOD_PATP, MOD_OPT, PCRE2_MULTILINE,            PO(options) },
@@ -603,15 +670,18 @@
   { "ph",                         MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_HARD,         DO(options) },
   { "posix",                      MOD_PAT,  MOD_CTL, CTL_POSIX,                  PO(control) },
   { "posix_nosub",                MOD_PAT,  MOD_CTL, CTL_POSIX|CTL_POSIX_NOSUB,  PO(control) },
+  { "posix_startend",             MOD_DAT,  MOD_IN2, 0,                          DO(startend) },
   { "ps",                         MOD_DAT,  MOD_OPT, PCRE2_PARTIAL_SOFT,         DO(options) },
   { "push",                       MOD_PAT,  MOD_CTL, CTL_PUSH,                   PO(control) },
-  { "pushcopy",                   MOD_PAT,  MOD_CTL, CTL_PUSHCOPY,              PO(control) },
-  { "recursion_limit",            MOD_CTM,  MOD_INT, 0,                          MO(recursion_limit) },
+  { "pushcopy",                   MOD_PAT,  MOD_CTL, CTL_PUSHCOPY,               PO(control) },
+  { "pushtablescopy",             MOD_PAT,  MOD_CTL, CTL_PUSHTABLESCOPY,         PO(control) },
+  { "recursion_limit",            MOD_CTM,  MOD_INT, 0,                          MO(depth_limit) },  /* Obsolete synonym */
   { "regerror_buffsize",          MOD_PAT,  MOD_INT, 0,                          PO(regerror_buffsize) },
   { "replace",                    MOD_PND,  MOD_STR, REPLACE_MODSIZE,            PO(replacement) },
   { "stackguard",                 MOD_PAT,  MOD_INT, 0,                          PO(stackguard_test) },
   { "startchar",                  MOD_PND,  MOD_CTL, CTL_STARTCHAR,              PO(control) },
   { "startoffset",                MOD_DAT,  MOD_INT, 0,                          DO(offset) },
+  { "subject_literal",            MOD_PATP, MOD_CTL, CTL2_SUBJECT_LITERAL,       PO(control2) },
   { "substitute_extended",        MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_EXTENDED,   PO(control2) },
   { "substitute_overflow_length", MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_OVERFLOW_LENGTH, PO(control2) },
   { "substitute_unknown_unset",   MOD_PND,  MOD_CTL, CTL2_SUBSTITUTE_UNKNOWN_UNSET, PO(control2) },
@@ -619,8 +689,10 @@
   { "tables",                     MOD_PAT,  MOD_INT, 0,                          PO(tables_id) },
   { "ucp",                        MOD_PATP, MOD_OPT, PCRE2_UCP,                  PO(options) },
   { "ungreedy",                   MOD_PAT,  MOD_OPT, PCRE2_UNGREEDY,             PO(options) },
+  { "use_length",                 MOD_PAT,  MOD_CTL, CTL_USE_LENGTH,             PO(control) },
   { "use_offset_limit",           MOD_PAT,  MOD_OPT, PCRE2_USE_OFFSET_LIMIT,     PO(options) },
   { "utf",                        MOD_PATP, MOD_OPT, PCRE2_UTF,                  PO(options) },
+  { "utf8_input",                 MOD_PAT,  MOD_CTL, CTL_UTF8_INPUT,             PO(control) },
   { "zero_terminate",             MOD_DAT,  MOD_CTL, CTL_ZERO_TERMINATE,         DO(control) }
 };
 
@@ -629,11 +701,14 @@
 /* Controls and options that are supported for use with the POSIX interface. */
 
 #define POSIX_SUPPORTED_COMPILE_OPTIONS ( \
-  PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_MULTILINE|PCRE2_UCP|PCRE2_UTF| \
-  PCRE2_UNGREEDY)
+  PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_LITERAL|PCRE2_MULTILINE|PCRE2_UCP| \
+  PCRE2_UTF|PCRE2_UNGREEDY)
+
+#define POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS (0)
 
 #define POSIX_SUPPORTED_COMPILE_CONTROLS ( \
-  CTL_AFTERTEXT|CTL_ALLAFTERTEXT|CTL_EXPAND|CTL_POSIX|CTL_POSIX_NOSUB)
+  CTL_AFTERTEXT|CTL_ALLAFTERTEXT|CTL_EXPAND|CTL_HEXPAT|CTL_POSIX| \
+  CTL_POSIX_NOSUB|CTL_USE_LENGTH)
 
 #define POSIX_SUPPORTED_COMPILE_CONTROLS2 (0)
 
@@ -647,9 +722,10 @@
 
 #define PUSH_SUPPORTED_COMPILE_CONTROLS ( \
   CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \
-  CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_PUSHCOPY|CTL_BSR_SET|CTL_NL_SET)
+  CTL_JITVERIFY|CTL_MEMORY|CTL_FRAMESIZE|CTL_PUSH|CTL_PUSHCOPY| \
+  CTL_PUSHTABLESCOPY|CTL_USE_LENGTH)
 
-#define PUSH_SUPPORTED_COMPILE_CONTROLS2 (0)
+#define PUSH_SUPPORTED_COMPILE_CONTROLS2 (CTL2_BSR_SET|CTL2_NL_SET)
 
 /* Controls that apply only at compile time with 'push'. */
 
@@ -659,20 +735,24 @@
 /* Controls that are forbidden with #pop or #popcopy. */
 
 #define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_POSIX_NOSUB|CTL_PUSH| \
-  CTL_PUSHCOPY)
+  CTL_PUSHCOPY|CTL_PUSHTABLESCOPY|CTL_USE_LENGTH)
 
 /* Pattern controls that are mutually exclusive. At present these are all in
 the first control word. Note that CTL_POSIX_NOSUB is always accompanied by
 CTL_POSIX, so it doesn't need its own entries. */
 
 static uint32_t exclusive_pat_controls[] = {
-  CTL_POSIX  | CTL_HEXPAT,
-  CTL_POSIX  | CTL_PUSH,
-  CTL_POSIX  | CTL_PUSHCOPY,
-  CTL_EXPAND | CTL_HEXPAT };
+  CTL_POSIX    | CTL_PUSH,
+  CTL_POSIX    | CTL_PUSHCOPY,
+  CTL_POSIX    | CTL_PUSHTABLESCOPY,
+  CTL_PUSH     | CTL_PUSHCOPY,
+  CTL_PUSH     | CTL_PUSHTABLESCOPY,
+  CTL_PUSHCOPY | CTL_PUSHTABLESCOPY,
+  CTL_EXPAND   | CTL_HEXPAT };
 
 /* Data controls that are mutually exclusive. At present these are all in the
 first control word. */
+
 static uint32_t exclusive_dat_controls[] = {
   CTL_ALLUSEDTEXT | CTL_STARTCHAR,
   CTL_FINDLIMITS  | CTL_NULLCONTEXT };
@@ -690,13 +770,14 @@
 } c1modstruct;
 
 static c1modstruct c1modlist[] = {
-  { "bincode",      'B',           -1 },
-  { "info",         'I',           -1 },
-  { "global",       'g',           -1 },
-  { "caseless",     'i',           -1 },
-  { "multiline",    'm',           -1 },
-  { "dotall",       's',           -1 },
-  { "extended",     'x',           -1 }
+  { "bincode",         'B',           -1 },
+  { "info",            'I',           -1 },
+  { "global",          'g',           -1 },
+  { "caseless",        'i',           -1 },
+  { "multiline",       'm',           -1 },
+  { "no_auto_capture", 'n',           -1 },
+  { "dotall",          's',           -1 },
+  { "extended",        'x',           -1 }
 };
 
 #define C1MODLISTCOUNT sizeof(c1modlist)/sizeof(c1modstruct)
@@ -817,12 +898,17 @@
 static void *patstack[PATSTACKSIZE];
 static int patstacknext = 0;
 
+static void *malloclist[MALLOCLISTSIZE];
+static PCRE2_SIZE malloclistlength[MALLOCLISTSIZE];
+static uint32_t malloclistptr = 0;
+
 #ifdef SUPPORT_PCRE2_8
-static regex_t preg = { NULL, NULL, 0, 0, 0 };
+static regex_t preg = { NULL, NULL, 0, 0, 0, 0 };
 #endif
 
 static int *dfa_workspace = NULL;
 static const uint8_t *locale_tables = NULL;
+static const uint8_t *use_tables = NULL;
 static uint8_t locale_name[32];
 
 /* We need buffers for building 16/32-bit strings; 8-bit strings don't need
@@ -848,6 +934,7 @@
 static pcre2_code_8             *compiled_code8;
 static pcre2_general_context_8  *general_context8, *general_context_copy8;
 static pcre2_compile_context_8  *pat_context8, *default_pat_context8;
+static pcre2_convert_context_8  *con_context8, *default_con_context8;
 static pcre2_match_context_8    *dat_context8, *default_dat_context8;
 static pcre2_match_data_8       *match_data8;
 #endif
@@ -856,6 +943,7 @@
 static pcre2_code_16            *compiled_code16;
 static pcre2_general_context_16 *general_context16, *general_context_copy16;
 static pcre2_compile_context_16 *pat_context16, *default_pat_context16;
+static pcre2_convert_context_16 *con_context16, *default_con_context16;
 static pcre2_match_context_16   *dat_context16, *default_dat_context16;
 static pcre2_match_data_16      *match_data16;
 static PCRE2_SIZE pbuffer16_size = 0;   /* Set only when needed */
@@ -866,6 +954,7 @@
 static pcre2_code_32            *compiled_code32;
 static pcre2_general_context_32 *general_context32, *general_context_copy32;
 static pcre2_compile_context_32 *pat_context32, *default_pat_context32;
+static pcre2_convert_context_32 *con_context32, *default_con_context32;
 static pcre2_match_context_32   *dat_context32, *default_dat_context32;
 static pcre2_match_data_32      *match_data32;
 static PCRE2_SIZE pbuffer32_size = 0;   /* Set only when needed */
@@ -906,6 +995,21 @@
   (test_mode == PCRE16_MODE)? (uint32_t)(((PCRE2_SPTR16)(a))[b]) : \
   (uint32_t)(((PCRE2_SPTR32)(a))[b]))
 
+#define CONCTXCPY(a,b) \
+  if (test_mode == PCRE8_MODE) \
+    memcpy(G(a,8),G(b,8),sizeof(pcre2_convert_context_8)); \
+  else if (test_mode == PCRE16_MODE) \
+    memcpy(G(a,16),G(b,16),sizeof(pcre2_convert_context_16)); \
+  else memcpy(G(a,32),G(b,32),sizeof(pcre2_convert_context_32))
+
+#define CONVERT_COPY(a,b,c) \
+  if (test_mode == PCRE8_MODE) \
+    memcpy(G(a,8),(char *)b,c); \
+  else if (test_mode == PCRE16_MODE) \
+    memcpy(G(a,16),(char *)b,(c)*2); \
+  else if (test_mode == PCRE32_MODE) \
+    memcpy(G(a,32),(char *)b,(c)*4)
+
 #define DATCTXCPY(a,b) \
   if (test_mode == PCRE8_MODE) \
     memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8)); \
@@ -966,6 +1070,14 @@
   else \
     a = (void *)pcre2_code_copy_32(G(b,32))
 
+#define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) \
+  if (test_mode == PCRE8_MODE) \
+    a = (void *)pcre2_code_copy_with_tables_8(G(b,8)); \
+  else if (test_mode == PCRE16_MODE) \
+    a = (void *)pcre2_code_copy_with_tables_16(G(b,16)); \
+  else \
+    a = (void *)pcre2_code_copy_with_tables_32(G(b,32))
+
 #define PCRE2_COMPILE(a,b,c,d,e,f,g) \
   if (test_mode == PCRE8_MODE) \
     G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g); \
@@ -974,6 +1086,11 @@
   else \
     G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g)
 
+#define PCRE2_CONVERTED_PATTERN_FREE(a) \
+  if (test_mode == PCRE8_MODE) pcre2_converted_pattern_free_8((PCRE2_UCHAR8 *)a); \
+  else if (test_mode == PCRE16_MODE) pcre2_converted_pattern_free_16((PCRE2_UCHAR16 *)a); \
+  else pcre2_converted_pattern_free_32((PCRE2_UCHAR32 *)a)
+
 #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
   if (test_mode == PCRE8_MODE) \
     a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j); \
@@ -986,9 +1103,9 @@
   if (test_mode == PCRE8_MODE) \
     r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)); \
   else if (test_mode == PCRE16_MODE) \
-    r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size)); \
+    r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size/2)); \
   else \
-    r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size))
+    r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size/4))
 
 #define PCRE2_GET_OVECTOR_COUNT(a,b) \
   if (test_mode == PCRE8_MODE) \
@@ -1085,6 +1202,14 @@
   else \
     pcre2_match_data_free_32(G(a,32))
 
+#define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) \
+  if (test_mode == PCRE8_MODE) \
+    a = pcre2_pattern_convert_8(G(b,8),c,d,(PCRE2_UCHAR8 **)e,f,G(g,8)); \
+  else if (test_mode == PCRE16_MODE) \
+    a = pcre2_pattern_convert_16(G(b,16),c,d,(PCRE2_UCHAR16 **)e,f,G(g,16)); \
+  else \
+    a = pcre2_pattern_convert_32(G(b,32),c,d,(PCRE2_UCHAR32 **)e,f,G(g,32))
+
 #define PCRE2_PATTERN_INFO(a,b,c,d) \
   if (test_mode == PCRE8_MODE) \
     a = pcre2_pattern_info_8(G(b,8),c,d); \
@@ -1157,6 +1282,38 @@
   else \
     pcre2_set_compile_recursion_guard_32(G(a,32),b,c)
 
+#define PCRE2_SET_DEPTH_LIMIT(a,b) \
+  if (test_mode == PCRE8_MODE) \
+    pcre2_set_depth_limit_8(G(a,8),b); \
+  else if (test_mode == PCRE16_MODE) \
+    pcre2_set_depth_limit_16(G(a,16),b); \
+  else \
+    pcre2_set_depth_limit_32(G(a,32),b)
+
+#define PCRE2_SET_GLOB_SEPARATOR(r,a,b) \
+  if (test_mode == PCRE8_MODE) \
+    r = pcre2_set_glob_separator_8(G(a,8),b); \
+  else if (test_mode == PCRE16_MODE) \
+    r = pcre2_set_glob_separator_16(G(a,16),b); \
+  else \
+    r = pcre2_set_glob_separator_32(G(a,32),b)
+
+#define PCRE2_SET_GLOB_ESCAPE(r,a,b) \
+  if (test_mode == PCRE8_MODE) \
+    r = pcre2_set_glob_escape_8(G(a,8),b); \
+  else if (test_mode == PCRE16_MODE) \
+    r = pcre2_set_glob_escape_16(G(a,16),b); \
+  else \
+    r = pcre2_set_glob_escape_32(G(a,32),b)
+
+#define PCRE2_SET_HEAP_LIMIT(a,b) \
+  if (test_mode == PCRE8_MODE) \
+    pcre2_set_heap_limit_8(G(a,8),b); \
+  else if (test_mode == PCRE16_MODE) \
+    pcre2_set_heap_limit_16(G(a,16),b); \
+  else \
+    pcre2_set_heap_limit_32(G(a,32),b)
+
 #define PCRE2_SET_MATCH_LIMIT(a,b) \
   if (test_mode == PCRE8_MODE) \
     pcre2_set_match_limit_8(G(a,8),b); \
@@ -1189,14 +1346,6 @@
   else \
     pcre2_set_parens_nest_limit_32(G(a,32),b)
 
-#define PCRE2_SET_RECURSION_LIMIT(a,b) \
-  if (test_mode == PCRE8_MODE) \
-    pcre2_set_recursion_limit_8(G(a,8),b); \
-  else if (test_mode == PCRE16_MODE) \
-    pcre2_set_recursion_limit_16(G(a,16),b); \
-  else \
-    pcre2_set_recursion_limit_32(G(a,32),b)
-
 #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
   if (test_mode == PCRE8_MODE) \
     a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
@@ -1339,7 +1488,6 @@
   (test_mode == PCRE32_MODE && G(x,32)->f r (y)))
 
 
-
 /* ----- Two out of three modes are supported ----- */
 
 #else
@@ -1369,6 +1517,9 @@
 
 /* ----- Common macros for two-mode cases ----- */
 
+#define BYTEONE (BITONE/8)
+#define BYTETWO (BITTWO/8)
+
 #define CASTFLD(t,a,b) \
   ((test_mode == G(G(PCRE,BITONE),_MODE))? (t)(G(a,BITONE)->b) : \
     (t)(G(a,BITTWO)->b))
@@ -1382,6 +1533,17 @@
   (uint32_t)(((G(PCRE2_SPTR,BITONE))(a))[b]) : \
   (uint32_t)(((G(PCRE2_SPTR,BITTWO))(a))[b]))
 
+#define CONCTXCPY(a,b) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_convert_context_,BITONE))); \
+  else \
+    memcpy(G(a,BITTWO),G(b,BITTWO),sizeof(G(pcre2_convert_context_,BITTWO)))
+
+#define CONVERT_COPY(a,b,c) \
+  (test_mode == G(G(PCRE,BITONE),_MODE))? \
+  memcpy(G(a,BITONE),(char *)b,(c)*BYTEONE) : \
+  memcpy(G(a,BITTWO),(char *)b,(c)*BYTETWO)
+
 #define DATCTXCPY(a,b) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
     memcpy(G(a,BITONE),G(b,BITONE),sizeof(G(pcre2_match_context_,BITONE))); \
@@ -1429,12 +1591,24 @@
   else \
     a = (void *)G(pcre2_code_copy_,BITTWO)(G(b,BITTWO))
 
+#define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    a = (void *)G(pcre2_code_copy_with_tables_,BITONE)(G(b,BITONE)); \
+  else \
+    a = (void *)G(pcre2_code_copy_with_tables_,BITTWO)(G(b,BITTWO))
+
 #define PCRE2_COMPILE(a,b,c,d,e,f,g) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
     G(a,BITONE) = G(pcre2_compile_,BITONE)(G(b,BITONE),c,d,e,f,g); \
   else \
     G(a,BITTWO) = G(pcre2_compile_,BITTWO)(G(b,BITTWO),c,d,e,f,g)
 
+#define PCRE2_CONVERTED_PATTERN_FREE(a) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    G(pcre2_converted_pattern_free_,BITONE)((G(PCRE2_UCHAR,BITONE) *)a); \
+  else \
+    G(pcre2_converted_pattern_free_,BITTWO)((G(PCRE2_UCHAR,BITTWO) *)a)
+
 #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
     a = G(pcre2_dfa_match_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
@@ -1445,9 +1619,9 @@
 
 #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
-    r = G(pcre2_get_error_message_,BITONE)(a,G(b,BITONE),G(G(b,BITONE),_size)); \
+    r = G(pcre2_get_error_message_,BITONE)(a,G(b,BITONE),G(G(b,BITONE),_size/BYTEONE)); \
   else \
-    r = G(pcre2_get_error_message_,BITTWO)(a,G(b,BITTWO),G(G(b,BITTWO),_size))
+    r = G(pcre2_get_error_message_,BITTWO)(a,G(b,BITTWO),G(G(b,BITTWO),_size/BYTETWO))
 
 #define PCRE2_GET_OVECTOR_COUNT(a,b) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
@@ -1531,6 +1705,12 @@
   else \
     G(pcre2_match_data_free_,BITTWO)(G(a,BITTWO))
 
+#define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    a = G(pcre2_pattern_convert_,BITONE)(G(b,BITONE),c,d,(G(PCRE2_UCHAR,BITONE) **)e,f,G(g,BITONE)); \
+  else \
+    a = G(pcre2_pattern_convert_,BITTWO)(G(b,BITTWO),c,d,(G(PCRE2_UCHAR,BITTWO) **)e,f,G(g,BITTWO))
+
 #define PCRE2_PATTERN_INFO(a,b,c,d) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
     a = G(pcre2_pattern_info_,BITONE)(G(b,BITONE),c,d); \
@@ -1587,6 +1767,30 @@
   else \
     G(pcre2_set_compile_recursion_guard_,BITTWO)(G(a,BITTWO),b,c)
 
+#define PCRE2_SET_DEPTH_LIMIT(a,b) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    G(pcre2_set_depth_limit_,BITONE)(G(a,BITONE),b); \
+  else \
+    G(pcre2_set_depth_limit_,BITTWO)(G(a,BITTWO),b)
+
+#define PCRE2_SET_GLOB_ESCAPE(r,a,b) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    r = G(pcre2_set_glob_escape_,BITONE)(G(a,BITONE),b); \
+  else \
+    r = G(pcre2_set_glob_escape_,BITTWO)(G(a,BITTWO),b)
+
+#define PCRE2_SET_GLOB_SEPARATOR(r,a,b) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    r = G(pcre2_set_glob_separator_,BITONE)(G(a,BITONE),b); \
+  else \
+    r = G(pcre2_set_glob_separator_,BITTWO)(G(a,BITTWO),b)
+
+#define PCRE2_SET_HEAP_LIMIT(a,b) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    G(pcre2_set_heap_limit_,BITONE)(G(a,BITONE),b); \
+  else \
+    G(pcre2_set_heap_limit_,BITTWO)(G(a,BITTWO),b)
+
 #define PCRE2_SET_MATCH_LIMIT(a,b) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
     G(pcre2_set_match_limit_,BITONE)(G(a,BITONE),b); \
@@ -1611,12 +1815,6 @@
   else \
     G(pcre2_set_parens_nest_limit_,BITTWO)(G(a,BITTWO),b)
 
-#define PCRE2_SET_RECURSION_LIMIT(a,b) \
-  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
-    G(pcre2_set_recursion_limit_,BITONE)(G(a,BITONE),b); \
-  else \
-    G(pcre2_set_recursion_limit_,BITTWO)(G(a,BITTWO),b)
-
 #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
     a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
@@ -1754,6 +1952,8 @@
 #define CASTFLD(t,a,b) (t)(G(a,8)->b)
 #define CASTVAR(t,x) (t)G(x,8)
 #define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR8)(a))[b])
+#define CONCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_convert_context_8))
+#define CONVERT_COPY(a,b,c) memcpy(G(a,8),(char *)b, c)
 #define DATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_match_context_8))
 #define FLD(a,b) G(a,8)->b
 #define PATCTXCPY(a,b) memcpy(G(a,8),G(b,8),sizeof(pcre2_compile_context_8))
@@ -1766,8 +1966,11 @@
      (int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c)
 #define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,8) = pcre2_code_copy_8(b)
 #define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_8(G(b,8))
+#define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) a = (void *)pcre2_code_copy_with_tables_8(G(b,8))
 #define PCRE2_COMPILE(a,b,c,d,e,f,g) \
   G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g)
+#define PCRE2_CONVERTED_PATTERN_FREE(a) \
+  pcre2_converted_pattern_free_8((PCRE2_UCHAR8 *)a)
 #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
   a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h,i,j)
 #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
@@ -1790,6 +1993,7 @@
 #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
   G(a,8) = pcre2_match_data_create_from_pattern_8(G(b,8),c)
 #define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_8(G(a,8))
+#define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) a = pcre2_pattern_convert_8(G(b,8),c,d,(PCRE2_UCHAR8 **)e,f,G(g,8))
 #define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_8(G(b,8),c,d)
 #define PCRE2_PRINTINT(a) pcre2_printint_8(compiled_code8,outfile,a)
 #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
@@ -1804,11 +2008,14 @@
 #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_8(G(a,8),b)
 #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
   pcre2_set_compile_recursion_guard_8(G(a,8),b,c)
+#define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_8(G(a,8),b)
+#define PCRE2_SET_GLOB_ESCAPE(r,a,b) r = pcre2_set_glob_escape_8(G(a,8),b)
+#define PCRE2_SET_GLOB_SEPARATOR(r,a,b) r = pcre2_set_glob_separator_8(G(a,8),b)
+#define PCRE2_SET_HEAP_LIMIT(a,b) pcre2_set_heap_limit_8(G(a,8),b)
 #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b)
 #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_8(G(a,8),b)
 #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_8(G(a,8),b)
 #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b)
-#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_8(G(a,8),b)
 #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
   a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
     (PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l)
@@ -1849,6 +2056,8 @@
 #define CASTFLD(t,a,b) (t)(G(a,16)->b)
 #define CASTVAR(t,x) (t)G(x,16)
 #define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR16)(a))[b])
+#define CONCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_convert_context_16))
+#define CONVERT_COPY(a,b,c) memcpy(G(a,16),(char *)b, (c)*2)
 #define DATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_match_context_16))
 #define FLD(a,b) G(a,16)->b
 #define PATCTXCPY(a,b) memcpy(G(a,16),G(b,16),sizeof(pcre2_compile_context_16))
@@ -1861,12 +2070,15 @@
      (int (*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c)
 #define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,16) = pcre2_code_copy_16(b)
 #define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_16(G(b,16))
+#define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) a = (void *)pcre2_code_copy_with_tables_16(G(b,16))
 #define PCRE2_COMPILE(a,b,c,d,e,f,g) \
   G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g)
+#define PCRE2_CONVERTED_PATTERN_FREE(a) \
+  pcre2_converted_pattern_free_16((PCRE2_UCHAR16 *)a)
 #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
   a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h,i,j)
 #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
-  r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size))
+  r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size/2))
 #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_16(G(b,16))
 #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_16(G(b,16))
 #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_16(G(a,16),b)
@@ -1885,6 +2097,7 @@
 #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
   G(a,16) = pcre2_match_data_create_from_pattern_16(G(b,16),c)
 #define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_16(G(a,16))
+#define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) a = pcre2_pattern_convert_16(G(b,16),c,d,(PCRE2_UCHAR16 **)e,f,G(g,16))
 #define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_16(G(b,16),c,d)
 #define PCRE2_PRINTINT(a) pcre2_printint_16(compiled_code16,outfile,a)
 #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
@@ -1899,11 +2112,14 @@
 #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_16(G(a,16),b)
 #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
   pcre2_set_compile_recursion_guard_16(G(a,16),b,c)
+#define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_16(G(a,16),b)
+#define PCRE2_SET_GLOB_ESCAPE(r,a,b) r = pcre2_set_glob_escape_16(G(a,16),b)
+#define PCRE2_SET_GLOB_SEPARATOR(r,a,b) r = pcre2_set_glob_separator_16(G(a,16),b)
+#define PCRE2_SET_HEAP_LIMIT(a,b) pcre2_set_heap_limit_16(G(a,16),b)
 #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b)
 #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_16(G(a,16),b)
 #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_16(G(a,16),b)
 #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b)
-#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_16(G(a,16),b)
 #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
   a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \
     (PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l)
@@ -1944,6 +2160,8 @@
 #define CASTFLD(t,a,b) (t)(G(a,32)->b)
 #define CASTVAR(t,x) (t)G(x,32)
 #define CODE_UNIT(a,b) (uint32_t)(((PCRE2_SPTR32)(a))[b])
+#define CONCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_convert_context_32))
+#define CONVERT_COPY(a,b,c) memcpy(G(a,32),(char *)b, (c)*4)
 #define DATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_match_context_32))
 #define FLD(a,b) G(a,32)->b
 #define PATCTXCPY(a,b) memcpy(G(a,32),G(b,32),sizeof(pcre2_compile_context_32))
@@ -1956,12 +2174,15 @@
      (int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c)
 #define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,32) = pcre2_code_copy_32(b)
 #define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_32(G(b,32))
+#define PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(a,b) a = (void *)pcre2_code_copy_with_tables_32(G(b,32))
 #define PCRE2_COMPILE(a,b,c,d,e,f,g) \
   G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g)
+#define PCRE2_CONVERTED_PATTERN_FREE(a) \
+  pcre2_converted_pattern_free_32((PCRE2_UCHAR32 *)a)
 #define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
   a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h,i,j)
 #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
-  r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size))
+  r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size/4))
 #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_32(G(b,32))
 #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_32(G(b,32))
 #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_32(G(a,32),b)
@@ -1980,6 +2201,7 @@
 #define PCRE2_MATCH_DATA_CREATE_FROM_PATTERN(a,b,c) \
   G(a,32) = pcre2_match_data_create_from_pattern_32(G(b,32),c)
 #define PCRE2_MATCH_DATA_FREE(a) pcre2_match_data_free_32(G(a,32))
+#define PCRE2_PATTERN_CONVERT(a,b,c,d,e,f,g) a = pcre2_pattern_convert_32(G(b,32),c,d,(PCRE2_UCHAR32 **)e,f,G(g,32))
 #define PCRE2_PATTERN_INFO(a,b,c,d) a = pcre2_pattern_info_32(G(b,32),c,d)
 #define PCRE2_PRINTINT(a) pcre2_printint_32(compiled_code32,outfile,a)
 #define PCRE2_SERIALIZE_DECODE(r,a,b,c,d) \
@@ -1994,11 +2216,14 @@
 #define PCRE2_SET_CHARACTER_TABLES(a,b) pcre2_set_character_tables_32(G(a,32),b)
 #define PCRE2_SET_COMPILE_RECURSION_GUARD(a,b,c) \
   pcre2_set_compile_recursion_guard_32(G(a,32),b,c)
+#define PCRE2_SET_DEPTH_LIMIT(a,b) pcre2_set_depth_limit_32(G(a,32),b)
+#define PCRE2_SET_GLOB_ESCAPE(r,a,b) r = pcre2_set_glob_escape_32(G(a,32),b)
+#define PCRE2_SET_GLOB_SEPARATOR(r,a,b) r = pcre2_set_glob_separator_32(G(a,32),b)
+#define PCRE2_SET_HEAP_LIMIT(a,b) pcre2_set_heap_limit_32(G(a,32),b)
 #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b)
 #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_32(G(a,32),b)
 #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_32(G(a,32),b)
 #define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b)
-#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_32(G(a,32),b)
 #define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
   a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \
     (PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
@@ -2365,6 +2590,27 @@
 };
 
 
+#ifndef HAVE_STRERROR
+/*************************************************
+*     Provide strerror() for non-ANSI libraries  *
+*************************************************/
+
+/* Some old-fashioned systems (e.g. SunOS4) didn't have strerror() in their
+libraries. They may no longer be around, but just in case, we can try to
+provide the same facility by this simple alternative function. */
+
+extern int   sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(int n)
+{
+if (n < 0 || n >= sys_nerr) return "unknown error number";
+return sys_errlist[n];
+}
+#endif /* HAVE_STRERROR */
+
+
 
 /*************************************************
 *            Local memory functions              *
@@ -2372,12 +2618,32 @@
 
 /* Alternative memory functions, to test functionality. */
 
-static void *my_malloc(size_t size, void *data)
+static void *my_malloc(PCRE2_SIZE size, void *data)
 {
 void *block = malloc(size);
 (void)data;
 if (show_memory)
-  fprintf(outfile, "malloc       %3d %p\n", (int)size, block);
+  {
+  if (block == NULL)
+    {
+    fprintf(outfile, "** malloc() failed for %zd\n", size);
+    }
+  else
+    {
+    fprintf(outfile, "malloc  %5zd", size);
+#ifdef DEBUG_SHOW_MALLOC_ADDRESSES
+    fprintf(outfile, " %p", block);   /* Not portable */
+#endif
+    if (malloclistptr < MALLOCLISTSIZE)
+      {
+      malloclist[malloclistptr] = block;
+      malloclistlength[malloclistptr++] = size;
+      }
+    else
+      fprintf(outfile, " (not remembered)");
+    fprintf(outfile, "\n");
+    }
+  }
 return block;
 }
 
@@ -2385,30 +2651,35 @@
 {
 (void)data;
 if (show_memory)
-  fprintf(outfile, "free             %p\n", block);
+  {
+  uint32_t i, j;
+  BOOL found = FALSE;
+
+  fprintf(outfile, "free");
+  for (i = 0; i < malloclistptr; i++)
+    {
+    if (block == malloclist[i])
+      {
+      fprintf(outfile, "    %5zd", malloclistlength[i]);
+      malloclistptr--;
+      for (j = i; j < malloclistptr; j++)
+        {
+        malloclist[j] = malloclist[j+1];
+        malloclistlength[j] = malloclistlength[j+1];
+        }
+      found = TRUE;
+      break;
+      }
+    }
+  if (!found) fprintf(outfile, " unremembered block");
+#ifdef DEBUG_SHOW_MALLOC_ADDRESSES
+  fprintf(outfile, " %p", block);  /* Not portable */
+#endif
+  fprintf(outfile, "\n");
+  }
 free(block);
 }
 
-/* For recursion malloc/free, to test stacking calls */
-
-#ifdef HEAP_MATCH_RECURSE
-static void *my_stack_malloc(size_t size, void *data)
-{
-void *block = malloc(size);
-(void)data;
-if (show_memory)
-  fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);
-return block;
-}
-
-static void my_stack_free(void *block, void *data)
-{
-(void)data;
-if (show_memory)
-  fprintf(outfile, "stack_free       %p\n", block);
-free(block);
-}
-#endif  /* HEAP_MATCH_RECURSE */
 
 
 /*************************************************
@@ -2525,6 +2796,8 @@
 pchar(uint32_t c, BOOL utf, FILE *f)
 {
 int n = 0;
+char tempbuffer[16];
+
 if (PRINTOK(c))
   {
   if (f != NULL) fprintf(f, "%c", c);
@@ -2546,6 +2819,8 @@
   }
 
 if (f != NULL) n = fprintf(f, "\\x{%02x}", c);
+  else n = sprintf(tempbuffer, "\\x{%02x}", c);
+
 return n >= 0 ? n : 0;
 }
 
@@ -2657,13 +2932,14 @@
 *************************************************/
 
 /* Must handle UTF-32 strings in utf mode. Yields number of characters printed.
-For printing *MARK strings, a negative length is given.If handed a NULL file,
+For printing *MARK strings, a negative length is given. If handed a NULL file,
 just counts chars without printing. */
 
 static int pchars32(PCRE2_SPTR32 p, int length, BOOL utf, FILE *f)
 {
 int yield = 0;
 (void)(utf);  /* Avoid compiler warning */
+
 if (length < 0) length = p[-1];
 while (length-- > 0)
   {
@@ -2695,7 +2971,7 @@
 static int
 ord2utf8(uint32_t cvalue, uint8_t *utf8bytes)
 {
-register int i, j;
+int i, j;
 if (cvalue > 0x7fffffffu)
   return -1;
 for (i = 0; i < utf8_table1_size; i++)
@@ -2715,16 +2991,22 @@
 
 #ifdef SUPPORT_PCRE2_16
 /*************************************************
-*          Convert pattern to 16-bit             *
+*           Convert string to 16-bit             *
 *************************************************/
 
-/* In UTF mode the input is always interpreted as a string of UTF-8 bytes. If
-all the input bytes are ASCII, the space needed for a 16-bit string is exactly
-double the 8-bit size. Otherwise, the size needed for a 16-bit string is no
-more than double, because up to 0xffff uses no more than 3 bytes in UTF-8 but
-possibly 4 in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in
-UTF-16. The result is always left in pbuffer16. Impose a minimum size to save
-repeated re-sizing.
+/* In UTF mode the input is always interpreted as a string of UTF-8 bytes using
+the original UTF-8 definition of RFC 2279, which allows for up to 6 bytes, and
+code values from 0 to 0x7fffffff. However, values greater than the later UTF
+limit of 0x10ffff cause an error. In non-UTF mode the input is interpreted as
+UTF-8 if the utf8_input modifier is set, but an error is generated for values
+greater than 0xffff.
+
+If all the input bytes are ASCII, the space needed for a 16-bit string is
+exactly double the 8-bit size. Otherwise, the size needed for a 16-bit string
+is no more than double, because up to 0xffff uses no more than 3 bytes in UTF-8
+but possibly 4 in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes
+in UTF-16. The result is always left in pbuffer16. Impose a minimum size to
+save repeated re-sizing.
 
 Note that this function does not object to surrogate values. This is
 deliberate; it makes it possible to construct UTF-16 strings that are invalid,
@@ -2732,7 +3014,7 @@
 
 Arguments:
   p          points to a byte string
-  utf        non-zero if converting to UTF-16
+  utf        true in UTF mode
   lenptr     points to number of bytes in the string (excluding trailing zero)
 
 Returns:     0 on success, with the length updated to the number of 16-bit
@@ -2752,7 +3034,7 @@
   {
   if (pbuffer16 != NULL) free(pbuffer16);
   pbuffer16_size = 2*len + 2;
-  if (pbuffer16_size < 256) pbuffer16_size = 256;
+  if (pbuffer16_size < 4096) pbuffer16_size = 4096;
   pbuffer16 = (uint16_t *)malloc(pbuffer16_size);
   if (pbuffer16 == NULL)
     {
@@ -2763,7 +3045,7 @@
   }
 
 pp = pbuffer16;
-if (!utf)
+if (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)
   {
   for (; len > 0; len--) *pp++ = *p++;
   }
@@ -2772,12 +3054,12 @@
   uint32_t c;
   int chlen = utf82ord(p, &c);
   if (chlen <= 0) return -1;
+  if (!utf && c > 0xffff) return -3;
   if (c > 0x10ffff) return -2;
   p += chlen;
   len -= chlen;
   if (c < 0x10000) *pp++ = c; else
     {
-    if (!utf) return -3;
     c -= 0x10000;
     *pp++ = 0xD800 | (c >> 10);
     *pp++ = 0xDC00 | (c & 0x3ff);
@@ -2794,15 +3076,25 @@
 
 #ifdef SUPPORT_PCRE2_32
 /*************************************************
-*          Convert pattern to 32-bit             *
+*           Convert string to 32-bit             *
 *************************************************/
 
-/* In UTF mode the input is always interpreted as a string of UTF-8 bytes. If
-all the input bytes are ASCII, the space needed for a 32-bit string is exactly
-four times the 8-bit size. Otherwise, the size needed for a 32-bit string is no
-more than four times, because the number of characters must be less than the
-number of bytes. The result is always left in pbuffer32. Impose a minimum size
-to save repeated re-sizing.
+/* In UTF mode the input is always interpreted as a string of UTF-8 bytes using
+the original UTF-8 definition of RFC 2279, which allows for up to 6 bytes, and
+code values from 0 to 0x7fffffff. However, values greater than the later UTF
+limit of 0x10ffff cause an error.
+
+In non-UTF mode the input is interpreted as UTF-8 if the utf8_input modifier
+is set, and no limit is imposed. There is special interpretation of the 0xff
+byte (which is illegal in UTF-8) in this case: it causes the top bit of the
+next character to be set. This provides a way of generating 32-bit characters
+greater than 0x7fffffff.
+
+If all the input bytes are ASCII, the space needed for a 32-bit string is
+exactly four times the 8-bit size. Otherwise, the size needed for a 32-bit
+string is no more than four times, because the number of characters must be
+less than the number of bytes. The result is always left in pbuffer32. Impose a
+minimum size to save repeated re-sizing.
 
 Note that this function does not object to surrogate values. This is
 deliberate; it makes it possible to construct UTF-32 strings that are invalid,
@@ -2810,7 +3102,7 @@
 
 Arguments:
   p          points to a byte string
-  utf        true if UTF-8 (to be converted to UTF-32)
+  utf        true in UTF mode
   lenptr     points to number of bytes in the string (excluding trailing zero)
 
 Returns:     0 on success, with the length updated to the number of 32-bit
@@ -2829,7 +3121,7 @@
   {
   if (pbuffer32 != NULL) free(pbuffer32);
   pbuffer32_size = 4*len + 4;
-  if (pbuffer32_size < 256) pbuffer32_size = 256;
+  if (pbuffer32_size < 8192) pbuffer32_size = 8192;
   pbuffer32 = (uint32_t *)malloc(pbuffer32_size);
   if (pbuffer32 == NULL)
     {
@@ -2840,19 +3132,29 @@
   }
 
 pp = pbuffer32;
-if (!utf)
+
+if (!utf && (pat_patctl.control & CTL_UTF8_INPUT) == 0)
   {
   for (; len > 0; len--) *pp++ = *p++;
   }
+
 else while (len > 0)
   {
+  int chlen;
   uint32_t c;
-  int chlen = utf82ord(p, &c);
+  uint32_t topbit = 0;
+  if (!utf && *p == 0xff && len > 1)
+    {
+    topbit = 0x80000000u;
+    p++;
+    len--;
+    }
+  chlen = utf82ord(p, &c);
   if (chlen <= 0) return -1;
   if (utf && c > 0x10ffff) return -2;
   p += chlen;
   len -= chlen;
-  *pp++ = c;
+  *pp++ = c | topbit;
   }
 
 *pp = 0;
@@ -3072,7 +3374,7 @@
 while (n--)
   {
   int c = tolower(*s++) - tolower(*t++);
-  if (c) return c;
+  if (c != 0) return c;
   }
 return 0;
 }
@@ -3183,7 +3485,8 @@
   case MOD_PND:  /* Ditto, but not default pattern */
   case MOD_PNDP: /* Ditto, allowed for Perl test */
   if (dctl != NULL) field = dctl;
-    else if (pctl != NULL && (m->which == MOD_PD || ctx != CTX_DEFPAT))
+    else if (pctl != NULL && (m->which == MOD_PD || m->which == MOD_PDP ||
+             ctx != CTX_DEFPAT))
       field = pctl;
   break;
   }
@@ -3318,7 +3621,17 @@
 
       field = check_modifier(modlist + index, ctx, pctl, dctl, *p);
       if (field == NULL) return FALSE;
-      *((uint32_t *)field) |= modlist[index].value;
+
+      /* /x is a special case; a second appearance changes PCRE2_EXTENDED to
+      PCRE2_EXTENDED_MORE. */
+
+      if (cc == 'x' && (*((uint32_t *)field) & PCRE2_EXTENDED) != 0)
+        {
+        *((uint32_t *)field) &= ~PCRE2_EXTENDED;
+        *((uint32_t *)field) |= PCRE2_EXTENDED_MORE;
+        }
+      else
+        *((uint32_t *)field) |= modlist[index].value;
       }
 
     continue;    /* With tne next (fullname) modifier */
@@ -3377,8 +3690,8 @@
 #else
       *((uint16_t *)field) = PCRE2_BSR_UNICODE;
 #endif
-      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control &= ~CTL_BSR_SET;
-        else dctl->control &= ~CTL_BSR_SET;
+      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 &= ~CTL2_BSR_SET;
+        else dctl->control2 &= ~CTL2_BSR_SET;
       }
     else
       {
@@ -3387,12 +3700,38 @@
       else if (len == 7 && strncmpic(pp, (const uint8_t *)"unicode", 7) == 0)
         *((uint16_t *)field) = PCRE2_BSR_UNICODE;
       else goto INVALID_VALUE;
-      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control |= CTL_BSR_SET;
-        else dctl->control |= CTL_BSR_SET;
+      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 |= CTL2_BSR_SET;
+        else dctl->control2 |= CTL2_BSR_SET;
       }
     pp = ep;
     break;
 
+    case MOD_CHR:  /* A single character */
+    *((uint32_t *)field) = *pp++;
+    break;
+
+    case MOD_CON:  /* A convert type/options list */
+    for (;; pp++)
+      {
+      uint8_t *colon = (uint8_t *)strchr((const char *)pp, ':');
+      len = ((colon != NULL && colon < ep)? colon:ep) - pp;
+      for (i = 0; i < convertlistcount; i++)
+        {
+        if (strncmpic(pp, (const uint8_t *)convertlist[i].name, len) == 0)
+          {
+          if (*((uint32_t *)field) == CONVERT_UNSET)
+            *((uint32_t *)field) = convertlist[i].option;
+          else
+            *((uint32_t *)field) |= convertlist[i].option;
+          break;
+          }
+        }
+      if (i >= convertlistcount) goto INVALID_VALUE;
+      pp += len;
+      if (*pp != ':') break;
+      }
+    break;
+
     case MOD_IN2:    /* One or two unsigned integers */
     if (!isdigit(*pp)) goto INVALID_VALUE;
     uli = strtoul((const char *)pp, &endptr, 10);
@@ -3455,14 +3794,14 @@
     if (i == 0)
       {
       *((uint16_t *)field) = NEWLINE_DEFAULT;
-      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control &= ~CTL_NL_SET;
-        else dctl->control &= ~CTL_NL_SET;
+      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 &= ~CTL2_NL_SET;
+        else dctl->control2 &= ~CTL2_NL_SET;
       }
     else
       {
       *((uint16_t *)field) = i;
-      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control |= CTL_NL_SET;
-        else dctl->control |= CTL_NL_SET;
+      if (ctx == CTX_PAT || ctx == CTX_DEFPAT) pctl->control2 |= CTL2_NL_SET;
+        else dctl->control2 |= CTL2_NL_SET;
       }
     pp = ep;
     break;
@@ -3498,10 +3837,16 @@
       char *nn = (char *)field;
       if (len > 0)                    /* Add new name */
         {
-        while (*nn != 0) nn += strlen(nn) + 1;
-        if (nn + len + 1 - (char *)field > LENCPYGET)
+        if (len > MAX_NAME_SIZE)
           {
-          fprintf(outfile, "** Too many named '%s' modifiers\n", m->name);
+          fprintf(outfile, "** Group name in '%s' is too long\n", m->name);
+          return FALSE;
+          }
+        while (*nn != 0) nn += strlen(nn) + 1;
+        if (nn + len + 2 - (char *)field > LENCPYGET)
+          {
+          fprintf(outfile, "** Too many characters in named '%s' modifiers\n",
+            m->name);
           return FALSE;
           }
         memcpy(nn, pp, len);
@@ -3572,6 +3917,7 @@
 pattern_info(int what, void *where, BOOL unsetok)
 {
 int rc;
+PCRE2_PATTERN_INFO(rc, compiled_code, what, NULL);  /* Exercise the code */
 PCRE2_PATTERN_INFO(rc, compiled_code, what, where);
 if (rc >= 0) return 0;
 if (rc != PCRE2_ERROR_UNSET || !unsetok)
@@ -3627,7 +3973,7 @@
 static void
 show_controls(uint32_t controls, uint32_t controls2, const char *before)
 {
-fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
   before,
   ((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "",
   ((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "",
@@ -3635,13 +3981,16 @@
   ((controls & CTL_ALLUSEDTEXT) != 0)? " allusedtext" : "",
   ((controls & CTL_ALTGLOBAL) != 0)? " altglobal" : "",
   ((controls & CTL_BINCODE) != 0)? " bincode" : "",
-  ((controls & CTL_BSR_SET) != 0)? " bsr" : "",
+  ((controls2 & CTL2_BSR_SET) != 0)? " bsr" : "",
   ((controls & CTL_CALLOUT_CAPTURE) != 0)? " callout_capture" : "",
+  ((controls2 & CTL2_CALLOUT_EXTRA) != 0)? " callout_extra" : "",
   ((controls & CTL_CALLOUT_INFO) != 0)? " callout_info" : "",
   ((controls & CTL_CALLOUT_NONE) != 0)? " callout_none" : "",
+  ((controls2 & CTL2_CALLOUT_NO_WHERE) != 0)? " callout_no_where" : "",
   ((controls & CTL_DFA) != 0)? " dfa" : "",
   ((controls & CTL_EXPAND) != 0)? " expand" : "",
   ((controls & CTL_FINDLIMITS) != 0)? " find_limits" : "",
+  ((controls & CTL_FRAMESIZE) != 0)? " framesize" : "",
   ((controls & CTL_FULLBINCODE) != 0)? " fullbincode" : "",
   ((controls & CTL_GETALL) != 0)? " getall" : "",
   ((controls & CTL_GLOBAL) != 0)? " global" : "",
@@ -3651,17 +4000,20 @@
   ((controls & CTL_JITVERIFY) != 0)? " jitverify" : "",
   ((controls & CTL_MARK) != 0)? " mark" : "",
   ((controls & CTL_MEMORY) != 0)? " memory" : "",
-  ((controls & CTL_NL_SET) != 0)? " newline" : "",
+  ((controls2 & CTL2_NL_SET) != 0)? " newline" : "",
   ((controls & CTL_NULLCONTEXT) != 0)? " null_context" : "",
   ((controls & CTL_POSIX) != 0)? " posix" : "",
   ((controls & CTL_POSIX_NOSUB) != 0)? " posix_nosub" : "",
   ((controls & CTL_PUSH) != 0)? " push" : "",
   ((controls & CTL_PUSHCOPY) != 0)? " pushcopy" : "",
+  ((controls & CTL_PUSHTABLESCOPY) != 0)? " pushtablescopy" : "",
   ((controls & CTL_STARTCHAR) != 0)? " startchar" : "",
   ((controls2 & CTL2_SUBSTITUTE_EXTENDED) != 0)? " substitute_extended" : "",
   ((controls2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)? " substitute_overflow_length" : "",
   ((controls2 & CTL2_SUBSTITUTE_UNKNOWN_UNSET) != 0)? " substitute_unknown_unset" : "",
   ((controls2 & CTL2_SUBSTITUTE_UNSET_EMPTY) != 0)? " substitute_unset_empty" : "",
+  ((controls & CTL_USE_LENGTH) != 0)? " use_length" : "",
+  ((controls & CTL_UTF8_INPUT) != 0)? " utf8_input" : "",
   ((controls & CTL_ZERO_TERMINATE) != 0)? " zero_terminate" : "");
 }
 
@@ -3685,7 +4037,7 @@
 show_compile_options(uint32_t options, const char *before, const char *after)
 {
 if (options == 0) fprintf(outfile, "%s <none>%s", before, after);
-else fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+else fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
   before,
   ((options & PCRE2_ALT_BSUX) != 0)? " alt_bsux" : "",
   ((options & PCRE2_ALT_CIRCUMFLEX) != 0)? " alt_circumflex" : "",
@@ -3697,8 +4049,11 @@
   ((options & PCRE2_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
   ((options & PCRE2_DOTALL) != 0)? " dotall" : "",
   ((options & PCRE2_DUPNAMES) != 0)? " dupnames" : "",
+  ((options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",
   ((options & PCRE2_EXTENDED) != 0)? " extended" : "",
+  ((options & PCRE2_EXTENDED_MORE) != 0)? " extended_more" : "",
   ((options & PCRE2_FIRSTLINE) != 0)? " firstline" : "",
+  ((options & PCRE2_LITERAL) != 0)? " literal" : "",
   ((options & PCRE2_MATCH_UNSET_BACKREF) != 0)? " match_unset_backref" : "",
   ((options & PCRE2_MULTILINE) != 0)? " multiline" : "",
   ((options & PCRE2_NEVER_BACKSLASH_C) != 0)? " never_backslash_c" : "",
@@ -3717,6 +4072,35 @@
 }
 
 
+/*************************************************
+*           Show compile extra options           *
+*************************************************/
+
+/* Called from show_pattern_info() and for unsupported POSIX options.
+
+Arguments:
+  options     an options word
+  before      text to print before
+  after       text to print after
+
+Returns:      nothing
+*/
+
+static void
+show_compile_extra_options(uint32_t options, const char *before,
+  const char *after)
+{
+if (options == 0) fprintf(outfile, "%s <none>%s", before, after);
+else fprintf(outfile, "%s%s%s%s%s%s",
+  before,
+  ((options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) != 0)? " allow_surrogate_escapes" : "",
+  ((options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) != 0)? " bad_escape_is_literal" : "",
+  ((options & PCRE2_EXTRA_MATCH_WORD) != 0)? " match_word" : "",
+  ((options & PCRE2_EXTRA_MATCH_LINE) != 0)? " match_line" : "",
+  after);
+}
+
+
 
 #ifdef SUPPORT_PCRE2_8
 /*************************************************
@@ -3728,10 +4112,11 @@
 static void
 show_match_options(uint32_t options)
 {
-fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s",
+fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s",
   ((options & PCRE2_ANCHORED) != 0)? " anchored" : "",
   ((options & PCRE2_DFA_RESTART) != 0)? " dfa_restart" : "",
   ((options & PCRE2_DFA_SHORTEST) != 0)? " dfa_shortest" : "",
+  ((options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",
   ((options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",
   ((options & PCRE2_NOTBOL) != 0)? " notbol" : "",
   ((options & PCRE2_NOTEMPTY) != 0)? " notempty" : "",
@@ -3759,13 +4144,13 @@
 
 cblock_size = 0;
 #ifdef SUPPORT_PCRE2_8
-if (test_mode == 8) cblock_size = sizeof(pcre2_real_code_8);
+if (test_mode == PCRE8_MODE) cblock_size = sizeof(pcre2_real_code_8);
 #endif
 #ifdef SUPPORT_PCRE2_16
-if (test_mode == 16) cblock_size = sizeof(pcre2_real_code_16);
+if (test_mode == PCRE16_MODE) cblock_size = sizeof(pcre2_real_code_16);
 #endif
 #ifdef SUPPORT_PCRE2_32
-if (test_mode == 32) cblock_size = sizeof(pcre2_real_code_32);
+if (test_mode == PCRE32_MODE) cblock_size = sizeof(pcre2_real_code_32);
 #endif
 
 (void)pattern_info(PCRE2_INFO_SIZE, &size, FALSE);
@@ -3783,6 +4168,44 @@
 
 
 /*************************************************
+*       Show frame size info for a pattern       *
+*************************************************/
+
+static void
+show_framesize(void)
+{
+size_t frame_size;
+(void)pattern_info(PCRE2_INFO_FRAMESIZE, &frame_size, FALSE);
+fprintf(outfile, "Frame size for pcre2_match(): %d\n", (int)frame_size);
+}
+
+
+
+/*************************************************
+*         Get and output an error message        *
+*************************************************/
+
+static BOOL
+print_error_message(int errorcode, const char *before, const char *after)
+{
+int len;
+PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer);
+if (len < 0)
+  {
+  fprintf(outfile, "\n** pcre2test internal error: cannot interpret error "
+    "number\n** Unexpected return (%d) from pcre2_get_error_message()\n", len);
+  }
+else
+  {
+  fprintf(outfile, "%s", before);
+  PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile);
+  fprintf(outfile, "%s", after);
+  }
+return len >= 0;
+}
+
+
+/*************************************************
 *     Callback function for callout enumeration  *
 *************************************************/
 
@@ -3849,7 +4272,7 @@
 static int
 show_pattern_info(void)
 {
-uint32_t compile_options, overall_options;
+uint32_t compile_options, overall_options, extra_options;
 
 if ((pat_patctl.control & (CTL_BINCODE|CTL_FULLBINCODE)) != 0)
   {
@@ -3859,16 +4282,36 @@
 
 if ((pat_patctl.control & CTL_INFO) != 0)
   {
+  int rc;
   void *nametable;
   uint8_t *start_bits;
-  BOOL match_limit_set, recursion_limit_set;
+  BOOL heap_limit_set, match_limit_set, depth_limit_set;
   uint32_t backrefmax, bsr_convention, capture_count, first_ctype, first_cunit,
     hasbackslashc, hascrorlf, jchanged, last_ctype, last_cunit, match_empty,
-    match_limit, minlength, nameentrysize, namecount, newline_convention,
-    recursion_limit;
+    depth_limit, heap_limit, match_limit, minlength, nameentrysize, namecount,
+    newline_convention;
+
+  /* Exercise the error route. */
+
+  PCRE2_PATTERN_INFO(rc, compiled_code, 999, NULL);
+  (void)rc;
 
   /* These info requests may return PCRE2_ERROR_UNSET. */
 
+  switch(pattern_info(PCRE2_INFO_HEAPLIMIT, &heap_limit, TRUE))
+    {
+    case 0:
+    heap_limit_set = TRUE;
+    break;
+
+    case PCRE2_ERROR_UNSET:
+    heap_limit_set = FALSE;
+    break;
+
+    default:
+    return PR_ABEND;
+    }
+
   switch(pattern_info(PCRE2_INFO_MATCHLIMIT, &match_limit, TRUE))
     {
     case 0:
@@ -3883,14 +4326,14 @@
     return PR_ABEND;
     }
 
-  switch(pattern_info(PCRE2_INFO_RECURSIONLIMIT, &recursion_limit, TRUE))
+  switch(pattern_info(PCRE2_INFO_DEPTHLIMIT, &depth_limit, TRUE))
     {
     case 0:
-    recursion_limit_set = TRUE;
+    depth_limit_set = TRUE;
     break;
 
     case PCRE2_ERROR_UNSET:
-    recursion_limit_set = FALSE;
+    depth_limit_set = FALSE;
     break;
 
     default:
@@ -3927,11 +4370,14 @@
   if (maxlookbehind > 0)
     fprintf(outfile, "Max lookbehind = %d\n", maxlookbehind);
 
+  if (heap_limit_set)
+    fprintf(outfile, "Heap limit = %u\n", heap_limit);
+
   if (match_limit_set)
     fprintf(outfile, "Match limit = %u\n", match_limit);
 
-  if (recursion_limit_set)
-    fprintf(outfile, "Recursion limit = %u\n", recursion_limit);
+  if (depth_limit_set)
+    fprintf(outfile, "Depth limit = %u\n", depth_limit);
 
   if (namecount > 0)
     {
@@ -3966,6 +4412,7 @@
 
   pattern_info(PCRE2_INFO_ARGOPTIONS, &compile_options, FALSE);
   pattern_info(PCRE2_INFO_ALLOPTIONS, &overall_options, FALSE);
+  pattern_info(PCRE2_INFO_EXTRAOPTIONS, &extra_options, FALSE);
 
   /* Remove UTF/UCP if they were there only because of forbid_utf. This saves
   cluttering up the verification output of non-UTF test files. */
@@ -3993,9 +4440,12 @@
       }
     }
 
+  if (extra_options != 0)
+    show_compile_extra_options(extra_options, "Extra options:", "\n");
+
   if (jchanged) fprintf(outfile, "Duplicate name status changes\n");
 
-  if ((pat_patctl.control & CTL_BSR_SET) != 0 ||
+  if ((pat_patctl.control2 & CTL2_BSR_SET) != 0 ||
       (FLD(compiled_code, flags) & PCRE2_BSR_SET) != 0)
     fprintf(outfile, "\\R matches %s\n", (bsr_convention == PCRE2_BSR_UNICODE)?
       "any Unicode newline" : "CR, LF, or CRLF");
@@ -4024,6 +4474,10 @@
       fprintf(outfile, "Forced newline is any Unicode newline\n");
       break;
 
+      case PCRE2_NEWLINE_NUL:
+      fprintf(outfile, "Forced newline is NUL\n");
+      break;
+
       default:
       break;
       }
@@ -4100,15 +4554,9 @@
     else
       {
 #ifdef SUPPORT_JIT
-      int len;
       fprintf(outfile, "JIT compilation was not successful");
-      if (jitrc != 0)
-        {
-        fprintf(outfile, " (");
-        PCRE2_GET_ERROR_MESSAGE(len, jitrc, pbuffer);
-        PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile);
-        fprintf(outfile, ")");
-        }
+      if (jitrc != 0 && !print_error_message(jitrc, " (", ")"))
+        return PR_ABEND;
       fprintf(outfile, "\n");
 #else
       fprintf(outfile, "JIT support is not available in this version of PCRE2\n");
@@ -4123,14 +4571,9 @@
   PCRE2_CALLOUT_ENUMERATE(errorcode, callout_callback, 0);
   if (errorcode != 0)
     {
-    int len;
     fprintf(outfile, "Callout enumerate failed: error %d: ", errorcode);
-    if (errorcode < 0)
-      {
-      PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer);
-      PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile);
-      }
-    fprintf(outfile, "\n");
+    if (errorcode < 0 && !print_error_message(errorcode, "", "\n"))
+      return PR_ABEND;
     return PR_SKIP;
     }
   }
@@ -4150,16 +4593,14 @@
   rc         the error code
   msg        an initial message for what failed
 
-Returns:     nothing
+Returns:     FALSE if print_error_message() fails
 */
 
-static void
+static BOOL
 serial_error(int rc, const char *msg)
 {
 fprintf(outfile, "%s failed: error %d: ", msg, rc);
-PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-fprintf(outfile, "\n");
+return print_error_message(rc, "", "\n");
 }
 
 
@@ -4197,7 +4638,7 @@
 *fptr = fopen((const char *)filename, mode);
 if (*fptr == NULL)
   {
-  fprintf(outfile, "** Failed to open '%s'\n", filename);
+  fprintf(outfile, "** Failed to open '%s': %s\n", filename, strerror(errno));
   return PR_ABEND;
   }
 
@@ -4227,7 +4668,7 @@
 FILE *f;
 PCRE2_SIZE serial_size;
 size_t i;
-int rc, cmd, cmdlen;
+int rc, cmd, cmdlen, yield;
 uint16_t first_listed_newline;
 const char *cmdname;
 uint8_t *argptr, *serial;
@@ -4238,6 +4679,7 @@
   return PR_ABEND;
   }
 
+yield = PR_OK;
 cmd = CMD_UNKNOWN;
 cmdlen = 0;
 
@@ -4337,6 +4779,7 @@
     PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
     }
   if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
+  if ((pat_patctl.control & CTL_FRAMESIZE) != 0) show_framesize();
   if ((pat_patctl.control & CTL_ANYINFO) != 0)
     {
     rc = show_pattern_info();
@@ -4360,7 +4803,8 @@
     general_context);
   if (rc < 0)
     {
-    serial_error(rc, "Serialization");
+    fclose(f);
+    if (!serial_error(rc, "Serialization")) return PR_ABEND;
     break;
     }
 
@@ -4374,6 +4818,7 @@
   if (fwrite(serial, 1, serial_size, f) != serial_size)
     {
     fprintf(outfile, "** Wrong return from fwrite()\n");
+    fclose(f);
     return PR_ABEND;
     }
 
@@ -4401,38 +4846,50 @@
     {
     fprintf(outfile, "** Failed to get memory (size %lu) for #load\n",
       (unsigned long int)serial_size);
+    fclose(f);
     return PR_ABEND;
     }
 
-  if (fread(serial, 1, serial_size, f) != serial_size)
-    {
-    fprintf(outfile, "** Wrong return from fread()\n");
-    return PR_ABEND;
-    }
+  i = fread(serial, 1, serial_size, f);
   fclose(f);
 
-  PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(rc, serial);
-  if (rc < 0) serial_error(rc, "Get number of codes"); else
+  if (i != serial_size)
     {
-    if (rc + patstacknext > PATSTACKSIZE)
+    fprintf(outfile, "** Wrong return from fread()\n");
+    yield = PR_ABEND;
+    }
+  else
+    {
+    PCRE2_SERIALIZE_GET_NUMBER_OF_CODES(rc, serial);
+    if (rc < 0)
       {
-      fprintf(outfile, "** Not enough space on pattern stack for %d pattern%s\n",
-        rc, (rc == 1)? "" : "s");
-      rc = PATSTACKSIZE - patstacknext;
-      fprintf(outfile, "** Decoding %d pattern%s\n", rc,
-        (rc == 1)? "" : "s");
+      if (!serial_error(rc, "Get number of codes")) yield = PR_ABEND;
       }
-    PCRE2_SERIALIZE_DECODE(rc, patstack + patstacknext, rc, serial,
-      general_context);
-    if (rc < 0) serial_error(rc, "Deserialization");
+    else
+      {
+      if (rc + patstacknext > PATSTACKSIZE)
+        {
+        fprintf(outfile, "** Not enough space on pattern stack for %d pattern%s\n",
+          rc, (rc == 1)? "" : "s");
+        rc = PATSTACKSIZE - patstacknext;
+        fprintf(outfile, "** Decoding %d pattern%s\n", rc,
+          (rc == 1)? "" : "s");
+        }
+      PCRE2_SERIALIZE_DECODE(rc, patstack + patstacknext, rc, serial,
+        general_context);
+      if (rc < 0)
+        {
+        if (!serial_error(rc, "Deserialization")) yield = PR_ABEND;
+        }
       else patstacknext += rc;
+      }
     }
 
   free(serial);
   break;
   }
 
-return PR_OK;
+return yield;
 }
 
 
@@ -4459,11 +4916,12 @@
 BOOL utf;
 uint32_t k;
 uint8_t *p = buffer;
-const uint8_t *use_tables;
 unsigned int delimiter = *p++;
 int errorcode;
 void *use_pat_context;
+uint32_t use_forbid_utf = forbid_utf;
 PCRE2_SIZE patlen;
+PCRE2_SIZE valgrind_access_length;
 PCRE2_SIZE erroroffset;
 
 /* Initialize the context and pattern/data controls for this test from the
@@ -4507,8 +4965,34 @@
 if (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP;
 utf = (pat_patctl.options & PCRE2_UTF) != 0;
 
-/* Check for mutually exclusive modifiers. At present, these are all in the
-first control word. */
+/* The utf8_input modifier is not allowed in 8-bit mode, and is mutually
+exclusive with the utf modifier. */
+
+if ((pat_patctl.control & CTL_UTF8_INPUT) != 0)
+  {
+  if (test_mode == PCRE8_MODE)
+    {
+    fprintf(outfile, "** The utf8_input modifier is not allowed in 8-bit mode\n");
+    return PR_SKIP;
+    }
+  if (utf)
+    {
+    fprintf(outfile, "** The utf and utf8_input modifiers are mutually exclusive\n");
+    return PR_SKIP;
+    }
+  }
+
+/* The convert and posix modifiers are mutually exclusive. */
+
+if (pat_patctl.convert_type != CONVERT_UNSET &&
+    (pat_patctl.control & CTL_POSIX) != 0)
+  {
+  fprintf(outfile, "** The convert and posix modifiers are mutually exclusive\n");
+  return PR_SKIP;
+  }
+
+/* Check for mutually exclusive control modifiers. At present, these are all in
+the first control word. */
 
 for (k = 0; k < sizeof(exclusive_pat_controls)/sizeof(uint32_t); k++)
   {
@@ -4548,12 +5032,14 @@
 
     if (c == '\'' || c == '"')
       {
+      uint8_t *pq = pp;
       for (;; pp++)
         {
         d = *pp;
         if (d == 0)
           {
-          fprintf(outfile, "** Missing closing quote in hex pattern\n");
+          fprintf(outfile, "** Missing closing quote in hex pattern: "
+            "opening quote is at offset " PTR_SPEC ".\n", pq - buffer - 2);
           return PR_SKIP;
           }
         if (d == c) break;
@@ -4567,8 +5053,8 @@
       {
       if (!isxdigit(c))
         {
-        fprintf(outfile, "** Unexpected non-hex-digit '%c' in hex pattern: "
-          "quote missing?\n", c);
+        fprintf(outfile, "** Unexpected non-hex-digit '%c' at offset "
+          PTR_SPEC " in hex pattern: quote missing?\n", c, pp - buffer - 2);
         return PR_SKIP;
         }
       if (*pp == 0)
@@ -4579,8 +5065,8 @@
       d = *pp;
       if (!isxdigit(d))
         {
-        fprintf(outfile, "** Unexpected non-hex-digit '%c' in hex pattern: "
-          "quote missing?\n", d);
+        fprintf(outfile, "** Unexpected non-hex-digit '%c' at offset "
+          PTR_SPEC " in hex pattern: quote missing?\n", d, pp - buffer - 1);
         return PR_SKIP;
         }
       c = toupper(c);
@@ -4738,7 +5224,7 @@
   const char *msg = "** Ignored with POSIX interface:";
 #endif
 
-  if (test_mode != 8)
+  if (test_mode != PCRE8_MODE)
     {
     fprintf(outfile, "** The POSIX interface is available only in 8-bit mode\n");
     return PR_SKIP;
@@ -4760,6 +5246,16 @@
       pat_patctl.options & ~POSIX_SUPPORTED_COMPILE_OPTIONS, msg, "");
     msg = "";
     }
+
+  if ((FLD(pat_context, extra_options) &
+       ~POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS) != 0)
+    {
+    show_compile_extra_options(
+      FLD(pat_context, extra_options) & ~POSIX_SUPPORTED_COMPILE_EXTRA_OPTIONS,
+        msg, "");
+    msg = "";
+    }
+
   if ((pat_patctl.control & ~POSIX_SUPPORTED_COMPILE_CONTROLS) != 0 ||
       (pat_patctl.control2 & ~POSIX_SUPPORTED_COMPILE_CONTROLS2) != 0)
     {
@@ -4769,6 +5265,10 @@
     }
 
   if (local_newline_default != 0) prmsg(&msg, "#newline_default");
+  if (FLD(pat_context, max_pattern_length) != PCRE2_UNSET)
+    prmsg(&msg, "max_pattern_length");
+  if (FLD(pat_context, parens_nest_limit) != PARENS_NEST_DEFAULT)
+    prmsg(&msg, "parens_nest_limit");
 
   if (msg[0] == 0) fprintf(outfile, "\n");
 
@@ -4778,10 +5278,17 @@
   if ((pat_patctl.control & CTL_POSIX_NOSUB) != 0) cflags |= REG_NOSUB;
   if ((pat_patctl.options & PCRE2_UCP) != 0) cflags |= REG_UCP;
   if ((pat_patctl.options & PCRE2_CASELESS) != 0) cflags |= REG_ICASE;
+  if ((pat_patctl.options & PCRE2_LITERAL) != 0) cflags |= REG_NOSPEC;
   if ((pat_patctl.options & PCRE2_MULTILINE) != 0) cflags |= REG_NEWLINE;
   if ((pat_patctl.options & PCRE2_DOTALL) != 0) cflags |= REG_DOTALL;
   if ((pat_patctl.options & PCRE2_UNGREEDY) != 0) cflags |= REG_UNGREEDY;
 
+  if ((pat_patctl.control & (CTL_HEXPAT|CTL_USE_LENGTH)) != 0)
+    {
+    preg.re_endp = (char *)pbuffer8 + patlen;
+    cflags |= REG_PEND;
+    }
+
   rc = regcomp(&preg, (char *)pbuffer8, cflags);
 
   /* Compiling failed */
@@ -4844,7 +5351,7 @@
 /* Handle compiling via the native interface. Controls that act later are
 ignored with "push". Replacements are locked out. */
 
-if ((pat_patctl.control & (CTL_PUSH|CTL_PUSHCOPY)) != 0)
+if ((pat_patctl.control & (CTL_PUSH|CTL_PUSHCOPY|CTL_PUSHTABLESCOPY)) != 0)
   {
   if (pat_patctl.replacement[0] != 0)
     {
@@ -4902,38 +5409,165 @@
   break;
   }
 
-/* The pattern is now in pbuffer[8|16|32], with the length in patlen. By
-default, however, we pass a zero-terminated pattern. The length is passed only
-if we had a hex pattern. */
+/* The pattern is now in pbuffer[8|16|32], with the length in code units in
+patlen. If it is to be converted, copy the result back afterwards so that it
+it ends up back in the usual place. */
 
-if ((pat_patctl.control & CTL_HEXPAT) == 0) patlen = PCRE2_ZERO_TERMINATED;
+if (pat_patctl.convert_type != CONVERT_UNSET)
+  {
+  int rc;
+  int convert_return = PR_OK;
+  uint32_t convert_options = pat_patctl.convert_type;
+  void *converted_pattern;
+  PCRE2_SIZE converted_length;
+
+  if (pat_patctl.convert_length != 0)
+    {
+    converted_length = pat_patctl.convert_length;
+    converted_pattern = malloc(converted_length * code_unit_size);
+    if (converted_pattern == NULL)
+      {
+      fprintf(outfile, "** Failed: malloc failed for converted pattern\n");
+      return PR_SKIP;
+      }
+    }
+  else converted_pattern = NULL;  /* Let the library allocate */
+
+  if (utf) convert_options |= PCRE2_CONVERT_UTF;
+  if ((pat_patctl.options & PCRE2_NO_UTF_CHECK) != 0)
+    convert_options |= PCRE2_CONVERT_NO_UTF_CHECK;
+
+  CONCTXCPY(con_context, default_con_context);
+
+  if (pat_patctl.convert_glob_escape != 0)
+    {
+    uint32_t escape = (pat_patctl.convert_glob_escape == '0')? 0 :
+      pat_patctl.convert_glob_escape;
+    PCRE2_SET_GLOB_ESCAPE(rc, con_context, escape);
+    if (rc != 0)
+      {
+      fprintf(outfile, "** Invalid glob escape '%c'\n",
+        pat_patctl.convert_glob_escape);
+      convert_return = PR_SKIP;
+      goto CONVERT_FINISH;
+      }
+    }
+
+  if (pat_patctl.convert_glob_separator != 0)
+    {
+    PCRE2_SET_GLOB_SEPARATOR(rc, con_context, pat_patctl.convert_glob_separator);
+    if (rc != 0)
+      {
+      fprintf(outfile, "** Invalid glob separator '%c'\n",
+        pat_patctl.convert_glob_separator);
+      convert_return = PR_SKIP;
+      goto CONVERT_FINISH;
+      }
+    }
+
+  PCRE2_PATTERN_CONVERT(rc, pbuffer, patlen, convert_options,
+    &converted_pattern, &converted_length, con_context);
+
+  if (rc != 0)
+    {
+    fprintf(outfile, "** Pattern conversion error at offset %zu: ",
+      converted_length);
+    convert_return = print_error_message(rc, "", "\n")? PR_SKIP:PR_ABEND;
+    }
+
+  /* Output the converted pattern, then copy it. */
+
+  else
+    {
+    PCHARSV(converted_pattern, 0, converted_length, utf, outfile);
+    fprintf(outfile, "\n");
+    patlen = converted_length;
+    CONVERT_COPY(pbuffer, converted_pattern, converted_length + 1);
+    }
+
+  /* Free the converted pattern. */
+
+  CONVERT_FINISH:
+  if (pat_patctl.convert_length != 0)
+    free(converted_pattern);
+  else
+    PCRE2_CONVERTED_PATTERN_FREE(converted_pattern);
+
+  /* Return if conversion was unsuccessful. */
+
+  if (convert_return != PR_OK) return convert_return;
+  }
+
+/* By default we pass a zero-terminated pattern, but a length is passed if
+"use_length" was specified or this is a hex pattern (which might contain binary
+zeros). When valgrind is supported, arrange for the unused part of the buffer
+to be marked as no access. */
+
+valgrind_access_length = patlen;
+if ((pat_patctl.control & (CTL_HEXPAT|CTL_USE_LENGTH)) == 0)
+  {
+  patlen = PCRE2_ZERO_TERMINATED;
+  valgrind_access_length += 1;  /* For the terminating zero */
+  }
+
+#ifdef SUPPORT_VALGRIND
+#ifdef SUPPORT_PCRE2_8
+if (test_mode == PCRE8_MODE && pbuffer8 != NULL)
+  {
+  VALGRIND_MAKE_MEM_NOACCESS(pbuffer8 + valgrind_access_length,
+    pbuffer8_size - valgrind_access_length);
+  }
+#endif
+#ifdef SUPPORT_PCRE2_16
+if (test_mode == PCRE16_MODE && pbuffer16 != NULL)
+  {
+  VALGRIND_MAKE_MEM_NOACCESS(pbuffer16 + valgrind_access_length,
+    pbuffer16_size - valgrind_access_length*sizeof(uint16_t));
+  }
+#endif
+#ifdef SUPPORT_PCRE2_32
+if (test_mode == PCRE32_MODE && pbuffer32 != NULL)
+  {
+  VALGRIND_MAKE_MEM_NOACCESS(pbuffer32 + valgrind_access_length,
+    pbuffer32_size - valgrind_access_length*sizeof(uint32_t));
+  }
+#endif
+#else  /* Valgrind not supported */
+(void)valgrind_access_length;  /* Avoid compiler warning */
+#endif
 
 /* If #newline_default has been used and the library was not compiled with an
 appropriate default newline setting, local_newline_default will be non-zero. We
 use this if there is no explicit newline modifier. */
 
-if ((pat_patctl.control & CTL_NL_SET) == 0 && local_newline_default != 0)
+if ((pat_patctl.control2 & CTL2_NL_SET) == 0 && local_newline_default != 0)
   {
   SETFLD(pat_context, newline_convention, local_newline_default);
   }
 
-/* The nullcontext modifier is used to test calling pcre2_compile() with a NULL
-context. */
+/* The null_context modifier is used to test calling pcre2_compile() with a
+NULL context. */
 
 use_pat_context = ((pat_patctl.control & CTL_NULLCONTEXT) != 0)?
   NULL : PTR(pat_context);
 
+/* If PCRE2_LITERAL is set, set use_forbid_utf zero because PCRE2_NEVER_UTF
+and PCRE2_NEVER_UCP are invalid with it. */
+
+if ((pat_patctl.options & PCRE2_LITERAL) != 0) use_forbid_utf = 0;
+
 /* Compile many times when timing. */
 
 if (timeit > 0)
   {
-  register int i;
+  int i;
   clock_t time_taken = 0;
   for (i = 0; i < timeit; i++)
     {
     clock_t start_time = clock();
     PCRE2_COMPILE(compiled_code, pbuffer, patlen,
-      pat_patctl.options|forbid_utf, &errorcode, &erroroffset, use_pat_context);
+      pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset,
+        use_pat_context);
     time_taken += clock() - start_time;
     if (TEST(compiled_code, !=, NULL))
       { SUB1(pcre2_code_free, compiled_code); }
@@ -4946,20 +5580,76 @@
 
 /* A final compile that is used "for real". */
 
-PCRE2_COMPILE(compiled_code, pbuffer, patlen, pat_patctl.options|forbid_utf,
+PCRE2_COMPILE(compiled_code, pbuffer, patlen, pat_patctl.options|use_forbid_utf,
   &errorcode, &erroroffset, use_pat_context);
 
+/* Call the JIT compiler if requested. When timing, we must free and recompile
+the pattern each time because that is the only way to free the JIT compiled
+code. We know that compilation will always succeed. */
+
+if (TEST(compiled_code, !=, NULL) && pat_patctl.jit != 0)
+  {
+  if (timeit > 0)
+    {
+    int i;
+    clock_t time_taken = 0;
+    for (i = 0; i < timeit; i++)
+      {
+      clock_t start_time;
+      SUB1(pcre2_code_free, compiled_code);
+      PCRE2_COMPILE(compiled_code, pbuffer, patlen,
+        pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset,
+        use_pat_context);
+      start_time = clock();
+      PCRE2_JIT_COMPILE(jitrc,compiled_code, pat_patctl.jit);
+      time_taken += clock() - start_time;
+      }
+    total_jit_compile_time += time_taken;
+    fprintf(outfile, "JIT compile  %.4f milliseconds\n",
+      (((double)time_taken * 1000.0) / (double)timeit) /
+        (double)CLOCKS_PER_SEC);
+    }
+  else
+    {
+    PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
+    }
+  }
+
+/* If valgrind is supported, mark the pbuffer as accessible again. The 16-bit
+and 32-bit buffers can be marked completely undefined, but we must leave the
+pattern in the 8-bit buffer defined because it may be read from a callout
+during matching. */
+
+#ifdef SUPPORT_VALGRIND
+#ifdef SUPPORT_PCRE2_8
+if (test_mode == PCRE8_MODE)
+  {
+  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer8 + valgrind_access_length,
+    pbuffer8_size - valgrind_access_length);
+  }
+#endif
+#ifdef SUPPORT_PCRE2_16
+if (test_mode == PCRE16_MODE)
+  {
+  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer16, pbuffer16_size);
+  }
+#endif
+#ifdef SUPPORT_PCRE2_32
+if (test_mode == PCRE32_MODE)
+  {
+  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer32, pbuffer32_size);
+  }
+#endif
+#endif
+
 /* Compilation failed; go back for another re, skipping to blank line
 if non-interactive. */
 
 if (TEST(compiled_code, ==, NULL))
   {
-  int len;
   fprintf(outfile, "Failed: error %d at offset %d: ", errorcode,
     (int)erroroffset);
-  PCRE2_GET_ERROR_MESSAGE(len, errorcode, pbuffer);
-  PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile);
-  fprintf(outfile, "\n");
+  if (!print_error_message(errorcode, "", "\n")) return PR_ABEND;
   return PR_SKIP;
   }
 
@@ -4982,42 +5672,10 @@
 if (pattern_info(PCRE2_INFO_MAXLOOKBEHIND, &maxlookbehind, FALSE) != 0)
   return PR_ABEND;
 
-/* Call the JIT compiler if requested. When timing, we must free and recompile
-the pattern each time because that is the only way to free the JIT compiled
-code. We know that compilation will always succeed. */
-
-if (pat_patctl.jit != 0)
-  {
-  if (timeit > 0)
-    {
-    register int i;
-    clock_t time_taken = 0;
-    for (i = 0; i < timeit; i++)
-      {
-      clock_t start_time;
-      SUB1(pcre2_code_free, compiled_code);
-      PCRE2_COMPILE(compiled_code, pbuffer, patlen,
-        pat_patctl.options|forbid_utf, &errorcode, &erroroffset,
-        use_pat_context);
-      start_time = clock();
-      PCRE2_JIT_COMPILE(jitrc,compiled_code, pat_patctl.jit);
-      time_taken += clock() - start_time;
-      }
-    total_jit_compile_time += time_taken;
-    fprintf(outfile, "JIT compile  %.4f milliseconds\n",
-      (((double)time_taken * 1000.0) / (double)timeit) /
-        (double)CLOCKS_PER_SEC);
-    }
-  else
-    {
-    PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
-    }
-  }
-
 /* If an explicit newline modifier was given, set the information flag in the
 pattern so that it is preserved over push/pop. */
 
-if ((pat_patctl.control & CTL_NL_SET) != 0)
+if ((pat_patctl.control2 & CTL2_NL_SET) != 0)
   {
   SETFLD(compiled_code, flags, FLD(compiled_code, flags) | PCRE2_NL_SET);
   }
@@ -5025,6 +5683,7 @@
 /* Output code size and other information if requested. */
 
 if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
+if ((pat_patctl.control & CTL_FRAMESIZE) != 0) show_framesize();
 if ((pat_patctl.control & CTL_ANYINFO) != 0)
   {
   int rc = show_pattern_info();
@@ -5045,17 +5704,25 @@
   SET(compiled_code, NULL);
   }
 
-/* The "pushcopy" control is similar, but pushes a copy of the pattern. This
-tests the pcre2_code_copy() function. */
+/* The "pushcopy" and "pushtablescopy" controls are similar, but push a
+copy of the pattern, the latter with a copy of its character tables. This tests
+the pcre2_code_copy() and pcre2_code_copy_with_tables() functions. */
 
-if ((pat_patctl.control & CTL_PUSHCOPY) != 0)
+if ((pat_patctl.control & (CTL_PUSHCOPY|CTL_PUSHTABLESCOPY)) != 0)
   {
   if (patstacknext >= PATSTACKSIZE)
     {
     fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE);
     return PR_ABEND;
     }
-  PCRE2_CODE_COPY_TO_VOID(patstack[patstacknext++], compiled_code);
+  if ((pat_patctl.control & CTL_PUSHCOPY) != 0)
+    {
+    PCRE2_CODE_COPY_TO_VOID(patstack[patstacknext++], compiled_code);
+    }
+  else
+    {
+    PCRE2_CODE_COPY_WITH_TABLES_TO_VOID(patstack[patstacknext++],
+      compiled_code); }
   }
 
 return PR_OK;
@@ -5064,11 +5731,23 @@
 
 
 /*************************************************
-*        Check match or recursion limit          *
+*          Check heap, match or depth limit      *
 *************************************************/
 
+/* This is used for DFA, normal, and JIT fast matching. For DFA matching it
+should only called with the third argument set to PCRE2_ERROR_DEPTHLIMIT.
+
+Arguments:
+  pp        the subject string
+  ulen      length of subject or PCRE2_ZERO_TERMINATED
+  errnumber defines which limit to test
+  msg       string to include in final message
+
+Returns:    the return from the final match function call
+*/
+
 static int
-check_match_limit(uint8_t *pp, size_t ulen, int errnumber, const char *msg)
+check_match_limit(uint8_t *pp, PCRE2_SIZE ulen, int errnumber, const char *msg)
 {
 int capcount;
 uint32_t min = 0;
@@ -5076,22 +5755,39 @@
 uint32_t max = UINT32_MAX;
 
 PCRE2_SET_MATCH_LIMIT(dat_context, max);
-PCRE2_SET_RECURSION_LIMIT(dat_context, max);
+PCRE2_SET_DEPTH_LIMIT(dat_context, max);
+PCRE2_SET_HEAP_LIMIT(dat_context, max);
 
 for (;;)
   {
-  if (errnumber == PCRE2_ERROR_MATCHLIMIT)
+  if (errnumber == PCRE2_ERROR_HEAPLIMIT)
+    {
+    PCRE2_SET_HEAP_LIMIT(dat_context, mid);
+    }
+  else if (errnumber == PCRE2_ERROR_MATCHLIMIT)
     {
     PCRE2_SET_MATCH_LIMIT(dat_context, mid);
     }
   else
     {
-    PCRE2_SET_RECURSION_LIMIT(dat_context, mid);
+    PCRE2_SET_DEPTH_LIMIT(dat_context, mid);
     }
 
-  if ((pat_patctl.control & CTL_JITFAST) != 0)
+  if ((dat_datctl.control & CTL_DFA) != 0)
+    {
+    if (dfa_workspace == NULL)
+      dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));
+    if (dfa_matched++ == 0)
+      dfa_workspace[0] = -1;  /* To catch bad restart */
+    PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
+      dat_datctl.options, match_data,
+      PTR(dat_context), dfa_workspace, DFA_WS_DIMENSION);
+    }
+
+  else if ((pat_patctl.control & CTL_JITFAST) != 0)
     PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
       dat_datctl.options, match_data, PTR(dat_context));
+
   else
     PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
       dat_datctl.options, match_data, PTR(dat_context));
@@ -5105,13 +5801,23 @@
            capcount == PCRE2_ERROR_NOMATCH ||
            capcount == PCRE2_ERROR_PARTIAL)
     {
+    /* If we've not hit the error with a heap limit less than the size of the
+    initial stack frame vector, the heap is not being used, so the minimum
+    limit is zero; there's no need to go on. The other limits are always
+    greater than zero. */
+
+    if (errnumber == PCRE2_ERROR_HEAPLIMIT && mid < START_FRAMES_SIZE/1024)
+      {
+      fprintf(outfile, "Minimum %s limit = 0\n", msg);
+      break;
+      }
     if (mid == min + 1)
       {
       fprintf(outfile, "Minimum %s limit = %d\n", msg, mid);
       break;
       }
     max = mid;
-    mid = (min + mid)/2;
+    mid = (min + max)/2;
     }
   else break;    /* Some other error */
   }
@@ -5126,11 +5832,11 @@
 *************************************************/
 
 /* Called from a PCRE2 library as a result of the (?C) item. We print out where
-we are in the match. Yield zero unless more callouts than the fail count, or
-the callout data is not zero. The only differences in the callout block for
-different code unit widths are that the pointers to the subject, the most
-recent MARK, and a callout argument string point to strings of the appropriate
-width. Casts can be used to deal with this.
+we are in the match (unless suppressed). Yield zero unless more callouts than
+the fail count, or the callout data is not zero. The only differences in the
+callout block for different code unit widths are that the pointers to the
+subject, the most recent MARK, and a callout argument string point to strings
+of the appropriate width. Casts can be used to deal with this.
 
 Argument:  a pointer to a callout block
 Return:
@@ -5139,16 +5845,43 @@
 static int
 callout_function(pcre2_callout_block_8 *cb, void *callout_data_ptr)
 {
+FILE *f, *fdefault;
 uint32_t i, pre_start, post_start, subject_length;
 PCRE2_SIZE current_position;
 BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
 BOOL callout_capture = (dat_datctl.control & CTL_CALLOUT_CAPTURE) != 0;
+BOOL callout_where = (dat_datctl.control2 & CTL2_CALLOUT_NO_WHERE) == 0;
 
-/* This FILE is used for echoing the subject. This is done only once in simple
-cases. */
+/* The FILE f is used for echoing the subject string if it is non-NULL. This
+happens only once in simple cases, but we want to repeat after any additional
+output caused by CALLOUT_EXTRA. */
 
-FILE *f = (first_callout || callout_capture || cb->callout_string != NULL)?
-  outfile : NULL;
+fdefault = (!first_callout && !callout_capture && cb->callout_string == NULL)?
+  NULL : outfile;
+
+if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0)
+  {
+  f = outfile;
+  switch (cb->callout_flags)
+    {
+    case PCRE2_CALLOUT_BACKTRACK:
+    fprintf(f, "Backtrack\n");
+    break;
+
+    case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK:
+    fprintf(f, "Backtrack\nNo other matching paths\n");
+    /* Fall through */
+
+    case PCRE2_CALLOUT_STARTMATCH:
+    fprintf(f, "New match attempt\n");
+    break;
+
+    default:
+    f = fdefault;
+    break;
+    }
+  }
+else f = fdefault;
 
 /* For a callout with a string argument, show the string first because there
 isn't a tidy way to fit it in the rest of the data. */
@@ -5177,7 +5910,7 @@
   if (cb->callout_string == NULL)
     fprintf(outfile, "Callout %d:", cb->callout_number);
   fprintf(outfile, " last capture = %d\n", cb->capture_last);
-  for (i = 0; i < cb->capture_top * 2; i += 2)
+  for (i = 2; i < cb->capture_top * 2; i += 2)
     {
     fprintf(outfile, "%2d: ", i/2);
     if (cb->offset_vector[i] == PCRE2_UNSET)
@@ -5191,75 +5924,84 @@
     }
   }
 
-/* Re-print the subject in canonical form (with escapes for non-printing
-characters), the first time, or if giving full details. On subsequent calls in
-the same match, we use PCHARS() just to find the printed lengths of the
-substrings. */
+/* Unless suppressed, re-print the subject in canonical form (with escapes for
+non-printing characters), the first time, or if giving full details. On
+subsequent calls in the same match, we use PCHARS() just to find the printed
+lengths of the substrings. */
 
-if (f != NULL) fprintf(f, "--->");
-
-/* The subject before the match start. */
-
-PCHARS(pre_start, cb->subject, 0, cb->start_match, utf, f);
-
-/* If a lookbehind is involved, the current position may be earlier than the
-match start. If so, use the match start instead. */
-
-current_position = (cb->current_position >= cb->start_match)?
-  cb->current_position : cb->start_match;
-
-/* The subject between the match start and the current position. */
-
-PCHARS(post_start, cb->subject, cb->start_match,
-  current_position - cb->start_match, utf, f);
-
-/* Print from the current position to the end. */
-
-PCHARSV(cb->subject, current_position, cb->subject_length - current_position,
-  utf, f);
-
-/* Calculate the total subject printed length (no print). */
-
-PCHARS(subject_length, cb->subject, 0, cb->subject_length, utf, NULL);
-
-if (f != NULL) fprintf(f, "\n");
-
-/* For automatic callouts, show the pattern offset. Otherwise, for a numerical
-callout whose number has not already been shown with captured strings, show the
-number here. A callout with a string argument has been displayed above. */
-
-if (cb->callout_number == 255)
+if (callout_where)
   {
-  fprintf(outfile, "%+3d ", (int)cb->pattern_position);
-  if (cb->pattern_position > 99) fprintf(outfile, "\n    ");
-  }
-else
-  {
-  if (callout_capture || cb->callout_string != NULL) fprintf(outfile, "    ");
-    else fprintf(outfile, "%3d ", cb->callout_number);
-  }
+  if (f != NULL) fprintf(f, "--->");
 
-/* Now show position indicators */
+  /* The subject before the match start. */
 
-for (i = 0; i < pre_start; i++) fprintf(outfile, " ");
-fprintf(outfile, "^");
+  PCHARS(pre_start, cb->subject, 0, cb->start_match, utf, f);
 
-if (post_start > 0)
-  {
-  for (i = 0; i < post_start - 1; i++) fprintf(outfile, " ");
+  /* If a lookbehind is involved, the current position may be earlier than the
+  match start. If so, use the match start instead. */
+
+  current_position = (cb->current_position >= cb->start_match)?
+    cb->current_position : cb->start_match;
+
+  /* The subject between the match start and the current position. */
+
+  PCHARS(post_start, cb->subject, cb->start_match,
+    current_position - cb->start_match, utf, f);
+
+  /* Print from the current position to the end. */
+
+  PCHARSV(cb->subject, current_position, cb->subject_length - current_position,
+    utf, f);
+
+  /* Calculate the total subject printed length (no print). */
+
+  PCHARS(subject_length, cb->subject, 0, cb->subject_length, utf, NULL);
+
+  if (f != NULL) fprintf(f, "\n");
+
+  /* For automatic callouts, show the pattern offset. Otherwise, for a
+  numerical callout whose number has not already been shown with captured
+  strings, show the number here. A callout with a string argument has been
+  displayed above. */
+
+  if (cb->callout_number == 255)
+    {
+    fprintf(outfile, "%+3d ", (int)cb->pattern_position);
+    if (cb->pattern_position > 99) fprintf(outfile, "\n    ");
+    }
+  else
+    {
+    if (callout_capture || cb->callout_string != NULL) fprintf(outfile, "    ");
+      else fprintf(outfile, "%3d ", cb->callout_number);
+    }
+
+  /* Now show position indicators */
+
+  for (i = 0; i < pre_start; i++) fprintf(outfile, " ");
   fprintf(outfile, "^");
+
+  if (post_start > 0)
+    {
+    for (i = 0; i < post_start - 1; i++) fprintf(outfile, " ");
+    fprintf(outfile, "^");
+    }
+
+  for (i = 0; i < subject_length - pre_start - post_start + 4; i++)
+    fprintf(outfile, " ");
+
+  if (cb->next_item_length != 0)
+    fprintf(outfile, "%.*s", (int)(cb->next_item_length),
+      pbuffer8 + cb->pattern_position);
+  else
+    fprintf(outfile, "End of pattern");
+
+  fprintf(outfile, "\n");
   }
 
-for (i = 0; i < subject_length - pre_start - post_start + 4; i++)
-  fprintf(outfile, " ");
-
-fprintf(outfile, "%.*s",
-  (int)((cb->next_item_length == 0)? 1 : cb->next_item_length),
-  pbuffer8 + cb->pattern_position);
-
-fprintf(outfile, "\n");
 first_callout = FALSE;
 
+/* Show any mark info */
+
 if (cb->mark != last_callout_mark)
   {
   if (cb->mark == NULL)
@@ -5273,6 +6015,8 @@
   last_callout_mark = cb->mark;
   }
 
+/* Show callout data */
+
 if (callout_data_ptr != NULL)
   {
   int callout_data = *((int32_t *)callout_data_ptr);
@@ -5283,8 +6027,19 @@
     }
   }
 
-return (cb->callout_number != dat_datctl.cfail[0])? 0 :
-       (++callout_count >= dat_datctl.cfail[1])? 1 : 0;
+/* Keep count and give the appropriate return code */
+
+callout_count++;
+
+if (cb->callout_number == dat_datctl.cerror[0] &&
+    callout_count >= dat_datctl.cerror[1])
+  return PCRE2_ERROR_CALLOUT;
+
+if (cb->callout_number == dat_datctl.cfail[0] &&
+    callout_count >= dat_datctl.cfail[1])
+  return 1;
+
+return 0;
 }
 
 
@@ -5300,10 +6055,10 @@
   utf       TRUE for utf
   capcount  return from pcre2_match()
 
-Returns:    nothing
+Returns:    FALSE if print_error_message() fails
 */
 
-static void
+static BOOL
 copy_and_get(BOOL utf, int capcount)
 {
 int i;
@@ -5322,9 +6077,7 @@
   if (rc < 0)
     {
     fprintf(outfile, "Copy substring %d failed (%d): ", n, rc);
-    PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-    PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-    fprintf(outfile, "\n");
+    if (!print_error_message(rc, "", "\n")) return FALSE;
     }
   else
     {
@@ -5332,9 +6085,7 @@
     if (rc < 0)
       {
       fprintf(outfile, "Get substring %d length failed (%d): ", n, rc);
-      PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-      PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-      fprintf(outfile, "\n");
+      if (!print_error_message(rc, "", "\n")) return FALSE;
       }
     else if (length2 != length)
       {
@@ -5381,9 +6132,7 @@
   if (rc < 0)
     {
     fprintf(outfile, "Copy substring '%s' failed (%d): ", nptr, rc);
-    PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-    PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-    fprintf(outfile, "\n");
+    if (!print_error_message(rc, "", "\n")) return FALSE;
     }
   else
     {
@@ -5391,9 +6140,7 @@
     if (rc < 0)
       {
       fprintf(outfile, "Get substring '%s' length failed (%d): ", nptr, rc);
-      PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-      PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-      fprintf(outfile, "\n");
+      if (!print_error_message(rc, "", "\n")) return FALSE;
       }
     else if (length2 != length)
       {
@@ -5421,9 +6168,7 @@
   if (rc < 0)
     {
     fprintf(outfile, "Get substring %d failed (%d): ", n, rc);
-    PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-    PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-    fprintf(outfile, "\n");
+    if (!print_error_message(rc, "", "\n")) return FALSE;
     }
   else
     {
@@ -5467,9 +6212,7 @@
   if (rc < 0)
     {
     fprintf(outfile, "Get substring '%s' failed (%d): ", nptr, rc);
-    PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-    PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-    fprintf(outfile, "\n");
+    if (!print_error_message(rc, "", "\n")) return FALSE;
     }
   else
     {
@@ -5494,9 +6237,7 @@
   if (rc < 0)
     {
     fprintf(outfile, "get substring list failed (%d): ", rc);
-    PCRE2_GET_ERROR_MESSAGE(rc, rc, pbuffer);
-    PCHARSV(CASTVAR(void *, pbuffer), 0, rc, FALSE, outfile);
-    fprintf(outfile, "\n");
+    if (!print_error_message(rc, "", "\n")) return FALSE;
     }
   else
     {
@@ -5511,6 +6252,8 @@
     PCRE2_SUBSTRING_LIST_FREE(stringlist);
     }
   }
+
+return TRUE;
 }
 
 
@@ -5531,7 +6274,7 @@
 static int
 process_data(void)
 {
-PCRE2_SIZE len, ulen;
+PCRE2_SIZE len, ulen, arg_ulen;
 uint32_t gmatched;
 uint32_t c, k;
 uint32_t g_notempty = 0;
@@ -5539,6 +6282,7 @@
 size_t needlen;
 void *use_dat_context;
 BOOL utf;
+BOOL subject_literal;
 
 #ifdef SUPPORT_PCRE2_8
 uint8_t *q8 = NULL;
@@ -5550,6 +6294,8 @@
 uint32_t *q32 = NULL;
 #endif
 
+subject_literal = (pat_patctl.control2 & CTL2_SUBJECT_LITERAL) != 0;
+
 /* Copy the default context and data control blocks to the active ones. Then
 copy from the pattern the controls that can be set in either the pattern or the
 data. This allows them to be overridden in the data line. We do not do this for
@@ -5561,6 +6307,7 @@
 dat_datctl.control |= (pat_patctl.control & CTL_ALLPD);
 dat_datctl.control2 |= (pat_patctl.control2 & CTL2_ALLPD);
 strcpy((char *)dat_datctl.replacement, (char *)pat_patctl.replacement);
+if (dat_datctl.jitstack == 0) dat_datctl.jitstack = pat_patctl.jitstack;
 
 /* Initialize for scanning the data line. */
 
@@ -5622,7 +6369,9 @@
 SETCASTPTR(q, dbuffer);  /* Sets q8, q16, or q32, as appropriate. */
 
 /* Scan the data line, interpreting data escapes, and put the result into a
-buffer of the appropriate width. In UTF mode, input can be UTF-8. */
+buffer of the appropriate width. In UTF mode, input is always UTF-8; otherwise,
+in 16- and 32-bit modes, it can be forced to UTF-8 by the utf8_input modifier.
+*/
 
 while ((c = *p++) != 0)
   {
@@ -5691,11 +6440,20 @@
     continue;
     }
 
-  /* Handle a non-escaped character */
+  /* Handle a non-escaped character. In non-UTF 32-bit mode with utf8_input
+  set, do the fudge for setting the top bit. */
 
-  if (c != '\\')
+  if (c != '\\' || subject_literal)
     {
-    if (utf && HASUTF8EXTRALEN(c)) { GETUTF8INC(c, p); }
+    uint32_t topbit = 0;
+    if (test_mode == PCRE32_MODE && c == 0xff && *p != 0)
+      {
+      topbit = 0x80000000;
+      c = *p++;
+      }
+    if ((utf || (pat_patctl.control & CTL_UTF8_INPUT) != 0) &&
+      HASUTF8EXTRALEN(c)) { GETUTF8INC(c, p); }
+    c |= topbit;
     }
 
   /* Handle backslash escapes */
@@ -5883,6 +6641,7 @@
 SET(*q, 0);
 len = CASTVAR(uint8_t *, q) - dbuffer;    /* Length in bytes */
 ulen = len/code_unit_size;                /* Length in code units */
+arg_ulen = ulen;                          /* Value to use in match arg */
 
 /* If the string was terminated by \= we must now interpret modifiers. */
 
@@ -5911,11 +6670,15 @@
   }
 
 /* We now have the subject in dbuffer, with len containing the byte length, and
-ulen containing the code unit length. Move the data to the end of the buffer so
-that a read over the end can be caught by valgrind or other means. If we have
-explicit valgrind support, mark the unused start of the buffer unaddressable.
-If we are using the POSIX interface, or testing zero-termination, we must
-include the terminating zero in the usable data. */
+ulen containing the code unit length, with a copy in arg_ulen for use in match
+function arguments (this gets changed to PCRE2_ZERO_TERMINATED when the
+zero_terminate modifier is present).
+
+Move the data to the end of the buffer so that a read over the end can be
+caught by valgrind or other means. If we have explicit valgrind support, mark
+the unused start of the buffer unaddressable. If we are using the POSIX
+interface, or testing zero-termination, we must include the terminating zero in
+the usable data. */
 
 c = code_unit_size * (((pat_patctl.control & CTL_POSIX) +
                        (dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? 1:0);
@@ -5936,13 +6699,16 @@
   regmatch_t *pmatch = NULL;
   const char *msg = "** Ignored with POSIX interface:";
 
-  if (dat_datctl.cfail[0] != CFAIL_UNSET || dat_datctl.cfail[1] != CFAIL_UNSET)
+  if (dat_datctl.cerror[0] != CFORE_UNSET || dat_datctl.cerror[1] != CFORE_UNSET)
+    prmsg(&msg, "callout_error");
+  if (dat_datctl.cfail[0] != CFORE_UNSET || dat_datctl.cfail[1] != CFORE_UNSET)
     prmsg(&msg, "callout_fail");
   if (dat_datctl.copy_numbers[0] >= 0 || dat_datctl.copy_names[0] != 0)
     prmsg(&msg, "copy");
   if (dat_datctl.get_numbers[0] >= 0 || dat_datctl.get_names[0] != 0)
     prmsg(&msg, "get");
   if (dat_datctl.jitstack != 0) prmsg(&msg, "jitstack");
+  if (dat_datctl.offset != 0) prmsg(&msg, "offset");
 
   if ((dat_datctl.options & ~POSIX_SUPPORTED_MATCH_OPTIONS) != 0)
     {
@@ -5961,13 +6727,29 @@
   if (msg[0] == 0) fprintf(outfile, "\n");
 
   if (dat_datctl.oveccount > 0)
+    {
     pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * dat_datctl.oveccount);
+    if (pmatch == NULL)
+      {
+      fprintf(outfile, "** Failed to get memory for recording matching "
+        "information (size set = %du)\n", dat_datctl.oveccount);
+      return PR_OK;
+      }
+    }
+
+  if (dat_datctl.startend[0] != CFORE_UNSET)
+    {
+    pmatch[0].rm_so = dat_datctl.startend[0];
+    pmatch[0].rm_eo = (dat_datctl.startend[1] != 0)?
+      dat_datctl.startend[1] : len;
+    eflags |= REG_STARTEND;
+    }
+
   if ((dat_datctl.options & PCRE2_NOTBOL) != 0) eflags |= REG_NOTBOL;
   if ((dat_datctl.options & PCRE2_NOTEOL) != 0) eflags |= REG_NOTEOL;
   if ((dat_datctl.options & PCRE2_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY;
 
-  rc = regexec(&preg, (const char *)pp + dat_datctl.offset,
-    dat_datctl.oveccount, pmatch, eflags);
+  rc = regexec(&preg, (const char *)pp, dat_datctl.oveccount, pmatch, eflags);
   if (rc != 0)
     {
     (void)regerror(rc, &preg, (char *)pbuffer8, pbuffer8_size);
@@ -5984,18 +6766,27 @@
       {
       if (pmatch[i].rm_so >= 0)
         {
+        PCRE2_SIZE start = pmatch[i].rm_so;
+        PCRE2_SIZE end = pmatch[i].rm_eo;
+        if (start > end)
+          {
+          start = pmatch[i].rm_eo;
+          end = pmatch[i].rm_so;
+          fprintf(outfile, "Start of matched string is beyond its end - "
+            "displaying from end to start.\n");
+          }
         fprintf(outfile, "%2d: ", (int)i);
-        PCHARSV(pp, pmatch[i].rm_so,
-          pmatch[i].rm_eo - pmatch[i].rm_so, utf, outfile);
+        PCHARSV(pp, start, end - start, utf, outfile);
         fprintf(outfile, "\n");
+
         if ((i == 0 && (dat_datctl.control & CTL_AFTERTEXT) != 0) ||
             (dat_datctl.control & CTL_ALLAFTERTEXT) != 0)
           {
           fprintf(outfile, "%2d+ ", (int)i);
-          PCHARSV(pp, pmatch[i].rm_eo, len - pmatch[i].rm_eo,
-            utf, outfile);
-          fprintf(outfile, "\n");
-          }
+          /* Note: don't use the start/end variables here because we want to
+          show the text from what is reported as the end. */
+          PCHARSV(pp, pmatch[i].rm_eo, len - pmatch[i].rm_eo, utf, outfile);
+          fprintf(outfile, "\n"); }
         }
       }
     }
@@ -6007,11 +6798,8 @@
  /* Handle matching via the native interface. Check for consistency of
 modifiers. */
 
-if ((dat_datctl.control & (CTL_DFA|CTL_FINDLIMITS)) == (CTL_DFA|CTL_FINDLIMITS))
-  {
-  fprintf(outfile, "** Finding match limits is not relevant for DFA matching: ignored\n");
-  dat_datctl.control &= ~CTL_FINDLIMITS;
-  }
+if (dat_datctl.startend[0] != CFORE_UNSET)
+  fprintf(outfile, "** \\=posix_startend ignored for non-POSIX matching\n");
 
 /* ALLUSEDTEXT is not supported with JIT, but JIT is not used with DFA
 matching, even if the JIT compiler was used. */
@@ -6026,7 +6814,7 @@
 /* Handle passing the subject as zero-terminated. */
 
 if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)
-  ulen = PCRE2_ZERO_TERMINATED;
+  arg_ulen = PCRE2_ZERO_TERMINATED;
 
 /* The nullcontext modifier is used to test calling pcre2_[jit_]match() with a
 NULL context. */
@@ -6034,10 +6822,16 @@
 use_dat_context = ((dat_datctl.control & CTL_NULLCONTEXT) != 0)?
   NULL : PTR(dat_context);
 
-/* Enable display of malloc/free if wanted. */
+/* Enable display of malloc/free if wanted. We can do this only if either the
+pattern or the subject is processed with a context. */
 
 show_memory = (dat_datctl.control & CTL_MEMORY) != 0;
 
+if (show_memory &&
+    (pat_patctl.control & dat_datctl.control & CTL_NULLCONTEXT) != 0)
+  fprintf(outfile, "** \\=memory requires either a pattern or a subject "
+    "context: ignored\n");
+
 /* Create and assign a JIT stack if requested. */
 
 if (dat_datctl.jitstack != 0)
@@ -6089,6 +6883,14 @@
   PCRE2_MATCH_DATA_CREATE(match_data, max_oveccount, NULL);
   }
 
+if (CASTVAR(void *, match_data) == NULL)
+  {
+  fprintf(outfile, "** Failed to get memory for recording matching "
+    "information (size requested: %d)\n", dat_datctl.oveccount);
+  max_oveccount = 0;
+  return PR_OK;
+  }
+
 /* Replacement processing is ignored for DFA matching. */
 
 if (dat_datctl.replacement[0] != 0 && (dat_datctl.control & CTL_DFA) != 0)
@@ -6220,19 +7022,17 @@
     rlen = PCRE2_ZERO_TERMINATED;
   else
     rlen = (CASTVAR(uint8_t *, r) - rbuffer)/code_unit_size;
-  PCRE2_SUBSTITUTE(rc, compiled_code, pp, ulen, dat_datctl.offset,
+  PCRE2_SUBSTITUTE(rc, compiled_code, pp, arg_ulen, dat_datctl.offset,
     dat_datctl.options|xoptions, match_data, dat_context,
     rbuffer, rlen, nbuffer, &nsize);
 
   if (rc < 0)
     {
-    PCRE2_SIZE msize;
     fprintf(outfile, "Failed: error %d", rc);
     if (rc != PCRE2_ERROR_NOMEMORY && nsize != PCRE2_UNSET)
       fprintf(outfile, " at offset %ld in replacement", (long int)nsize);
     fprintf(outfile, ": ");
-    PCRE2_GET_ERROR_MESSAGE(msize, rc, pbuffer);
-    PCHARSV(CASTVAR(void *, pbuffer), 0, msize, FALSE, outfile);
+    if (!print_error_message(rc, "", "")) return PR_ABEND;
     if (rc == PCRE2_ERROR_NOMEMORY &&
         (xoptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)
       fprintf(outfile, ": %ld code units are needed", (long int)nsize);
@@ -6287,7 +7087,7 @@
 
   if (timeitm > 0)
     {
-    register int i;
+    int i;
     clock_t start_time, time_taken;
 
     if ((dat_datctl.control & CTL_DFA) != 0)
@@ -6302,7 +7102,7 @@
       start_time = clock();
       for (i = 0; i < timeitm; i++)
         {
-        PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen,
+        PCRE2_DFA_MATCH(capcount, compiled_code, pp, arg_ulen,
           dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
           use_dat_context, dfa_workspace, DFA_WS_DIMENSION);
         }
@@ -6313,7 +7113,7 @@
       start_time = clock();
       for (i = 0; i < timeitm; i++)
         {
-        PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen,
+        PCRE2_JIT_MATCH(capcount, compiled_code, pp, arg_ulen,
           dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
           use_dat_context);
         }
@@ -6324,7 +7124,7 @@
       start_time = clock();
       for (i = 0; i < timeitm; i++)
         {
-        PCRE2_MATCH(capcount, compiled_code, pp, ulen,
+        PCRE2_MATCH(capcount, compiled_code, pp, arg_ulen,
           dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
           use_dat_context);
         }
@@ -6335,19 +7135,36 @@
         (double)CLOCKS_PER_SEC);
     }
 
-  /* Find the match and recursion limits if requested. The recursion limit
-  is not relevant for JIT. */
+  /* Find the heap, match and depth limits if requested. The match and heap
+  limits are not relevant for DFA matching and the depth and heap limits are
+  not relevant for JIT. The return from check_match_limit() is the return from
+  the final call to pcre2_match() or pcre2_dfa_match(). */
 
   if ((dat_datctl.control & CTL_FINDLIMITS) != 0)
     {
-    capcount = check_match_limit(pp, ulen, PCRE2_ERROR_MATCHLIMIT, "match");
-    if (FLD(compiled_code, executable_jit) == NULL)
-      (void)check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT,
-        "recursion");
+    capcount = 0;  /* This stops compiler warnings */
+
+    if ((dat_datctl.control & CTL_DFA) == 0 &&
+        (FLD(compiled_code, executable_jit) == NULL ||
+          (dat_datctl.options & PCRE2_NO_JIT) != 0))
+      {
+      (void)check_match_limit(pp, arg_ulen, PCRE2_ERROR_HEAPLIMIT, "heap");
+      }
+
+    capcount = check_match_limit(pp, arg_ulen, PCRE2_ERROR_MATCHLIMIT,
+      "match");
+
+    if (FLD(compiled_code, executable_jit) == NULL ||
+        (dat_datctl.options & PCRE2_NO_JIT) != 0 ||
+        (dat_datctl.control & CTL_DFA) != 0)
+      {
+      capcount = check_match_limit(pp, arg_ulen, PCRE2_ERROR_DEPTHLIMIT,
+        "depth");
+      }
     }
 
   /* Otherwise just run a single match, setting up a callout if required (the
-  default). */
+  default). There is a copy of the pattern in pbuffer8 for use by callouts. */
 
   else
     {
@@ -6372,7 +7189,7 @@
         dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int));
       if (dfa_matched++ == 0)
         dfa_workspace[0] = -1;  /* To catch bad restart */
-      PCRE2_DFA_MATCH(capcount, compiled_code, pp, ulen,
+      PCRE2_DFA_MATCH(capcount, compiled_code, pp, arg_ulen,
         dat_datctl.offset, dat_datctl.options | g_notempty, match_data,
         use_dat_context, dfa_workspace, DFA_WS_DIMENSION);
       if (capcount == 0)
@@ -6384,10 +7201,10 @@
     else
       {
       if ((pat_patctl.control & CTL_JITFAST) != 0)
-        PCRE2_JIT_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
+        PCRE2_JIT_MATCH(capcount, compiled_code, pp, arg_ulen, dat_datctl.offset,
           dat_datctl.options | g_notempty, match_data, use_dat_context);
       else
-        PCRE2_MATCH(capcount, compiled_code, pp, ulen, dat_datctl.offset,
+        PCRE2_MATCH(capcount, compiled_code, pp, arg_ulen, dat_datctl.offset,
           dat_datctl.options | g_notempty, match_data, use_dat_context);
       if (capcount == 0)
         {
@@ -6588,7 +7405,7 @@
 
     /* Process copy/get strings */
 
-    copy_and_get(utf, capcount);
+    if (!copy_and_get(utf, capcount)) return PR_ABEND;
 
     }    /* End of handling a successful match */
 
@@ -6631,7 +7448,7 @@
 
     /* Process copy/get strings */
 
-    copy_and_get(utf, 1);
+    if (!copy_and_get(utf, 1)) return PR_ABEND;
 
     break;  /* Out of the /g loop */
     }       /* End of handling partial match */
@@ -6687,8 +7504,6 @@
 
   else
     {
-    int mlen;
-
     switch(capcount)
       {
       case PCRE2_ERROR_NOMATCH:
@@ -6713,8 +7528,7 @@
 
       default:
       fprintf(outfile, "Failed: error %d: ", capcount);
-      PCRE2_GET_ERROR_MESSAGE(mlen, capcount, pbuffer);
-      PCHARSV(CASTVAR(void *, pbuffer), 0, mlen, FALSE, outfile);
+      if (!print_error_message(capcount, "", "")) return PR_ABEND;
       if (capcount <= PCRE2_ERROR_UTF8_ERR1 &&
           capcount >= PCRE2_ERROR_UTF32_ERR2)
         {
@@ -6800,6 +7614,7 @@
       pp += end_offset * code_unit_size;
       len -= end_offset * code_unit_size;
       ulen -= end_offset;
+      if (arg_ulen != PCRE2_ZERO_TERMINATED) arg_ulen -= end_offset;
       }
     }
   }  /* End of global loop */
@@ -6901,7 +7716,9 @@
 #ifdef SUPPORT_PCRE2_32
 printf("  -32           use the 32-bit library\n");
 #endif
-printf("  -b            set default pattern control 'fullbincode'\n");
+printf("  -ac           set default pattern modifier PCRE2_AUTO_CALLOUT\n");
+printf("  -AC           as -ac, but also set subject 'callout_extra' modifier\n");
+printf("  -b            set default pattern modifier 'fullbincode'\n");
 printf("  -C            show PCRE2 compile-time options and exit\n");
 printf("  -C arg        show a specific compile-time option and exit with its\n");
 printf("                  value if numeric (else 0). The arg can be:\n");
@@ -6911,20 +7728,22 @@
 printf("     ebcdic-nl      NL code if compiled for EBCDIC\n");
 printf("     jit            just-in-time compiler supported [0, 1]\n");
 printf("     linksize       internal link size [2, 3, 4]\n");
-printf("     newline        newline type [CR, LF, CRLF, ANYCRLF, ANY]\n");
+printf("     newline        newline type [CR, LF, CRLF, ANYCRLF, ANY, NUL]\n");
 printf("     pcre2-8        8 bit library support enabled [0, 1]\n");
 printf("     pcre2-16       16 bit library support enabled [0, 1]\n");
 printf("     pcre2-32       32 bit library support enabled [0, 1]\n");
 printf("     unicode        Unicode and UTF support enabled [0, 1]\n");
-printf("  -d            set default pattern control 'debug'\n");
-printf("  -dfa          set default subject control 'dfa'\n");
+printf("  -d            set default pattern modifier 'debug'\n");
+printf("  -dfa          set default subject modifier 'dfa'\n");
 printf("  -error <n,m,..>  show messages for error numbers, then exit\n");
 printf("  -help         show usage information\n");
-printf("  -i            set default pattern control 'info'\n");
-printf("  -jit          set default pattern control 'jit'\n");
+printf("  -i            set default pattern modifier 'info'\n");
+printf("  -jit          set default pattern modifier 'jit'\n");
+printf("  -jitverify    set default pattern modifier 'jitverify'\n");
+printf("  -LM           list pattern and subject modifiers, then exit\n");
 printf("  -q            quiet: do not output PCRE2 version number at start\n");
-printf("  -pattern <s>  set default pattern control fields\n");
-printf("  -subject <s>  set default subject control fields\n");
+printf("  -pattern <s>  set default pattern modifier fields\n");
+printf("  -subject <s>  set default subject modifier fields\n");
 printf("  -S <n>        set stack size to <n> megabytes\n");
 printf("  -t [<n>]      time compilation and execution, repeating <n> times\n");
 printf("  -tm [<n>]     time execution (matching) only, repeating <n> times\n");
@@ -6952,19 +7771,18 @@
 c_option(const char *arg)
 {
 uint32_t optval;
+unsigned int i = COPTLISTCOUNT;
 int yield = 0;
 
-if (arg != NULL)
+if (arg != NULL && arg[0] != CHAR_MINUS)
   {
-  unsigned int i;
-
   for (i = 0; i < COPTLISTCOUNT; i++)
     if (strcmp(arg, coptlist[i].name) == 0) break;
 
   if (i >= COPTLISTCOUNT)
     {
     fprintf(stderr, "** Unknown -C option '%s'\n", arg);
-    return -1;
+    return 0;
     }
 
   switch (coptlist[i].type)
@@ -7002,7 +7820,7 @@
     {
     char ucname[16];
     strcpy(ucname, coptlist[i].name);
-    for (i = 0; ucname[i] != 0; i++) ucname[i] = toupper[ucname[i];
+    for (i = 0; ucname[i] != 0; i++) ucname[i] = toupper[ucname[i]];
     vms_setsymbol(ucname, 0, optval);
     }
 #endif
@@ -7022,14 +7840,13 @@
 #endif
 #endif
 
-#ifdef SUPPORT_PCRE2_8
-printf("  8-bit support\n");
-#endif
-#ifdef SUPPORT_PCRE2_16
-printf("  16-bit support\n");
-#endif
-#ifdef SUPPORT_PCRE2_32
-printf("  32-bit support\n");
+(void)PCRE2_CONFIG(PCRE2_CONFIG_COMPILED_WIDTHS, &optval);
+if (optval & 1) printf("  8-bit support\n");
+if (optval & 2) printf("  16-bit support\n");
+if (optval & 4) printf("  32-bit support\n");
+
+#ifdef SUPPORT_VALGRIND
+printf("  Valgrind support\n");
 #endif
 
 (void)PCRE2_CONFIG(PCRE2_CONFIG_UNICODE, &optval);
@@ -7058,38 +7875,141 @@
 (void)PCRE2_CONFIG(PCRE2_CONFIG_BSR, &optval);
 printf("  \\R matches %s\n", optval? "CR, LF, or CRLF only" :
                                  "all Unicode newlines");
-#ifdef NEVER_BACKSLASH_C
-printf("  \\C is not supported\n");
-#else
-printf("  \\C is supported\n");
-#endif
+(void)PCRE2_CONFIG(PCRE2_CONFIG_NEVER_BACKSLASH_C, &optval);
+printf("  \\C is %ssupported\n", optval? "not ":"");
 (void)PCRE2_CONFIG(PCRE2_CONFIG_LINKSIZE, &optval);
 printf("  Internal link size = %d\n", optval);
 (void)PCRE2_CONFIG(PCRE2_CONFIG_PARENSLIMIT, &optval);
 printf("  Parentheses nest limit = %d\n", optval);
+(void)PCRE2_CONFIG(PCRE2_CONFIG_HEAPLIMIT, &optval);
+printf("  Default heap limit = %d\n", optval);
 (void)PCRE2_CONFIG(PCRE2_CONFIG_MATCHLIMIT, &optval);
 printf("  Default match limit = %d\n", optval);
-(void)PCRE2_CONFIG(PCRE2_CONFIG_RECURSIONLIMIT, &optval);
-printf("  Default recursion depth limit = %d\n", optval);
-(void)PCRE2_CONFIG(PCRE2_CONFIG_STACKRECURSE, &optval);
-printf("  Match recursion uses %s", optval? "stack" : "heap");
-
-printf("\n");
+(void)PCRE2_CONFIG(PCRE2_CONFIG_DEPTHLIMIT, &optval);
+printf("  Default depth limit = %d\n", optval);
 return 0;
 }
 
 
 
 /*************************************************
+*              Display one modifier              *
+*************************************************/
+
+static void
+display_one_modifier(modstruct *m, BOOL for_pattern)
+{
+uint32_t c = (!for_pattern && (m->which == MOD_PND || m->which == MOD_PNDP))?
+  '*' : ' ';
+printf("%c%s", c, m->name);
+}
+
+
+
+/*************************************************
+*       Display pattern or subject modifiers     *
+*************************************************/
+
+/* In order to print in two columns, first scan without printing to get a list
+of the modifiers that are required.
+
+Arguments:
+  for_pattern   TRUE for pattern modifiers, FALSE for subject modifiers
+  title         string to be used in title
+
+Returns:        nothing
+*/
+
+static void
+display_selected_modifiers(BOOL for_pattern, const char *title)
+{
+uint32_t i, j;
+uint32_t n = 0;
+uint32_t list[MODLISTCOUNT];
+
+for (i = 0; i < MODLISTCOUNT; i++)
+  {
+  BOOL is_pattern = TRUE;
+  modstruct *m = modlist + i;
+
+  switch (m->which)
+    {
+    case MOD_CTC:       /* Compile context */
+    case MOD_PAT:       /* Pattern */
+    case MOD_PATP:      /* Pattern, OK for Perl-compatible test */
+    break;
+
+    /* The MOD_PND and MOD_PNDP modifiers are precisely those that affect
+    subjects, but can be given with a pattern. We list them as subject
+    modifiers, but marked with an asterisk.*/
+
+    case MOD_CTM:       /* Match context */
+    case MOD_DAT:       /* Subject line */
+    case MOD_PND:       /* As PD, but not default pattern */
+    case MOD_PNDP:      /* As PND, OK for Perl-compatible test */
+    is_pattern = FALSE;
+    break;
+
+    default: printf("** Unknown type for modifier '%s'\n", m->name);
+    /* Fall through */
+    case MOD_PD:        /* Pattern or subject */
+    case MOD_PDP:       /* As PD, OK for Perl-compatible test */
+    is_pattern = for_pattern;
+    break;
+    }
+
+  if (for_pattern == is_pattern) list[n++] = i;
+  }
+
+/* Now print from the list in two columns. */
+
+printf("-------------- %s MODIFIERS --------------\n", title);
+
+for (i = 0, j = (n+1)/2; i < (n+1)/2; i++, j++)
+  {
+  modstruct *m = modlist + list[i];
+  display_one_modifier(m, for_pattern);
+  if (j < n)
+    {
+    uint32_t k = 27 - strlen(m->name);
+    while (k-- > 0) printf(" ");
+    display_one_modifier(modlist + list[j], for_pattern);
+    }
+  printf("\n");
+  }
+}
+
+
+
+/*************************************************
+*          Display the list of modifiers         *
+*************************************************/
+
+static void
+display_modifiers(void)
+{
+printf(
+  "An asterisk on a subject modifier means that it may be given on a pattern\n"
+  "line, in order to apply to all subjects matched by that pattern. Modifiers\n"
+  "that are listed for both patterns and subjects have different effects in\n"
+  "each case.\n\n");
+display_selected_modifiers(TRUE, "PATTERN");
+printf("\n");
+display_selected_modifiers(FALSE, "SUBJECT");
+}
+
+
+
+/*************************************************
 *                Main Program                    *
 *************************************************/
 
 int
 main(int argc, char **argv)
 {
+uint32_t temp;
 uint32_t yield = 0;
 uint32_t op = 1;
-uint32_t stack_size;
 BOOL notdone = TRUE;
 BOOL quiet = FALSE;
 BOOL showtotaltimes = FALSE;
@@ -7132,6 +8052,20 @@
   return 1;
   }
 
+/* Check that bad options are diagnosed. */
+
+if (PCRE2_CONFIG(999, NULL) != PCRE2_ERROR_BADOPTION ||
+    PCRE2_CONFIG(999, &temp) != PCRE2_ERROR_BADOPTION)
+  {
+  fprintf(stderr, "** Error in pcre2_config(): bad option not diagnosed\n");
+  return 1;
+  }
+
+/* This configuration option is now obsolete, but running a quick check ensures
+that its code is covered. */
+
+(void)PCRE2_CONFIG(PCRE2_CONFIG_STACKRECURSE, &temp);
+
 /* Get buffers from malloc() so that valgrind will check their misuse when
 debugging. They grow automatically when very long lines are read. The 16-
 and 32-bit buffers (pbuffer16, pbuffer32) are obtained only if needed. */
@@ -7151,12 +8085,17 @@
 /* Initialization that does not depend on the running mode. */
 
 locale_name[0] = 0;
+
 memset(&def_patctl, 0, sizeof(patctl));
+def_patctl.convert_type = CONVERT_UNSET;
+
 memset(&def_datctl, 0, sizeof(datctl));
 def_datctl.oveccount = DEFAULT_OVECCOUNT;
 def_datctl.copy_numbers[0] = -1;
 def_datctl.get_numbers[0] = -1;
-def_datctl.cfail[0] = def_datctl.cfail[1] = CFAIL_UNSET;
+def_datctl.startend[0] = def_datctl.startend[1] = CFORE_UNSET;
+def_datctl.cerror[0] = def_datctl.cerror[1] = CFORE_UNSET;
+def_datctl.cfail[0] = def_datctl.cfail[1] = CFORE_UNSET;
 
 /* Scan command line options. */
 
@@ -7166,6 +8105,14 @@
   char *arg = argv[op];
   unsigned long uli;
 
+  /* List modifiers and exit. */
+
+  if (strcmp(arg, "-LM") == 0)
+    {
+    display_modifiers();
+    goto EXIT;
+    }
+
   /* Display and/or set return code for configuration options. */
 
   if (strcmp(arg, "-C") == 0)
@@ -7174,32 +8121,45 @@
     goto EXIT;
     }
 
-  /* Select operating mode */
+  /* Select operating mode. Ensure that pcre2_config() is called in 16-bit
+  and 32-bit modes because that won't happen naturally when 8-bit is also
+  configured. Also call some other functions that are not otherwise used. This
+  means that a coverage report won't claim there are uncalled functions. */
 
   if (strcmp(arg, "-8") == 0)
     {
 #ifdef SUPPORT_PCRE2_8
     test_mode = PCRE8_MODE;
+    (void)pcre2_set_bsr_8(pat_context8, 999);
+    (void)pcre2_set_newline_8(pat_context8, 999);
 #else
     fprintf(stderr,
       "** This version of PCRE2 was built without 8-bit support\n");
     exit(1);
 #endif
     }
+
   else if (strcmp(arg, "-16") == 0)
     {
 #ifdef SUPPORT_PCRE2_16
     test_mode = PCRE16_MODE;
+    (void)pcre2_config_16(PCRE2_CONFIG_VERSION, NULL);
+    (void)pcre2_set_bsr_16(pat_context16, 999);
+    (void)pcre2_set_newline_16(pat_context16, 999);
 #else
     fprintf(stderr,
       "** This version of PCRE2 was built without 16-bit support\n");
     exit(1);
 #endif
     }
+
   else if (strcmp(arg, "-32") == 0)
     {
 #ifdef SUPPORT_PCRE2_32
     test_mode = PCRE32_MODE;
+    (void)pcre2_config_32(PCRE2_CONFIG_VERSION, NULL);
+    (void)pcre2_set_bsr_32(pat_context32, 999);
+    (void)pcre2_set_newline_32(pat_context32, 999);
 #else
     fprintf(stderr,
       "** This version of PCRE2 was built without 32-bit support\n");
@@ -7221,6 +8181,7 @@
     exit(1);
 #else
     int rc;
+    uint32_t stack_size;
     struct rlimit rlim;
     if (U32OVERFLOW(uli))
       {
@@ -7252,16 +8213,23 @@
 
   /* Set some common pattern and subject controls */
 
-  else if (strcmp(arg, "-dfa") == 0) def_datctl.control |= CTL_DFA;
-  else if (strcmp(arg, "-b") == 0) def_patctl.control |= CTL_FULLBINCODE;
-  else if (strcmp(arg, "-d") == 0) def_patctl.control |= CTL_DEBUG;
-  else if (strcmp(arg, "-i") == 0) def_patctl.control |= CTL_INFO;
-  else if (strcmp(arg, "-jit") == 0)
+  else if (strcmp(arg, "-AC") == 0)
     {
+    def_patctl.options |= PCRE2_AUTO_CALLOUT;
+    def_datctl.control2 |= CTL2_CALLOUT_EXTRA;
+    }
+  else if (strcmp(arg, "-ac") == 0)  def_patctl.options |= PCRE2_AUTO_CALLOUT;
+  else if (strcmp(arg, "-b") == 0)   def_patctl.control |= CTL_FULLBINCODE;
+  else if (strcmp(arg, "-d") == 0)   def_patctl.control |= CTL_DEBUG;
+  else if (strcmp(arg, "-dfa") == 0) def_datctl.control |= CTL_DFA;
+  else if (strcmp(arg, "-i") == 0)   def_patctl.control |= CTL_INFO;
+  else if (strcmp(arg, "-jit") == 0 || strcmp(arg, "-jitverify") == 0)
+    {
+    if (arg[4] != 0) def_patctl.control |= CTL_JITVERIFY;
     def_patctl.jit = 7;  /* full & partial */
 #ifndef SUPPORT_JIT
     fprintf(stderr, "** Warning: JIT support is not available: "
-                    "-jit calls functions that do nothing.\n");
+                    "-jit[verify] calls functions that do nothing.\n");
 #endif
     }
 
@@ -7356,7 +8324,8 @@
   int errcode;
   char *endptr;
 
-/* Ensure the relevant non-8-bit buffer is available. */
+/* Ensure the relevant non-8-bit buffer is available. Ensure that it is at
+least 128 code units, because it is used for retrieving error messages. */
 
 #ifdef SUPPORT_PCRE2_16
   if (test_mode == PCRE16_MODE)
@@ -7376,7 +8345,7 @@
 #ifdef SUPPORT_PCRE2_32
   if (test_mode == PCRE32_MODE)
     {
-    pbuffer32_size = 256;
+    pbuffer32_size = 512;
     pbuffer32 = (uint32_t *)malloc(pbuffer32_size);
     if (pbuffer32 == NULL)
       {
@@ -7430,9 +8399,8 @@
   }  /* End of -error handling */
 
 /* Initialize things that cannot be done until we know which test mode we are
-running in. When HEAP_MATCH_RECURSE is undefined, calling pcre2_set_recursion_
-memory_management() is a no-op, but we call it in order to exercise it. Also
-exercise the general context copying function, which is not otherwise used. */
+running in. Exercise the general context copying function, which is not
+otherwise used. */
 
 code_unit_size = test_mode/8;
 max_oveccount = DEFAULT_OVECCOUNT;
@@ -7446,19 +8414,18 @@
   G(pat_context,BITS) = G(pcre2_compile_context_copy_,BITS)(G(default_pat_context,BITS)); \
   G(default_dat_context,BITS) = G(pcre2_match_context_create_,BITS)(G(general_context,BITS)); \
   G(dat_context,BITS) = G(pcre2_match_context_copy_,BITS)(G(default_dat_context,BITS)); \
+  G(default_con_context,BITS) = G(pcre2_convert_context_create_,BITS)(G(general_context,BITS)); \
+  G(con_context,BITS) = G(pcre2_convert_context_copy_,BITS)(G(default_con_context,BITS)); \
   G(match_data,BITS) = G(pcre2_match_data_create_,BITS)(max_oveccount, G(general_context,BITS))
 
-#ifdef HEAP_MATCH_RECURSE
-#define SETRECURSEMEMMAN \
-  (void)G(pcre2_set_recursion_memory_management_,BITS) \
-    (G(default_dat_context,BITS), \
-    &my_stack_malloc, &my_stack_free, NULL)
-#else
-#define SETRECURSEMEMMAN \
-  (void)G(pcre2_set_recursion_memory_management_,BITS)(NULL, NULL, NULL, NULL)
-#endif
+#define CONTEXTTESTS \
+  (void)G(pcre2_set_compile_extra_options_,BITS)(G(pat_context,BITS), 0); \
+  (void)G(pcre2_set_max_pattern_length_,BITS)(G(pat_context,BITS), 0); \
+  (void)G(pcre2_set_offset_limit_,BITS)(G(dat_context,BITS), 0); \
+  (void)G(pcre2_set_recursion_memory_management_,BITS)(G(dat_context,BITS), my_malloc, my_free, NULL)
 
-/* Call the appropriate functions for the current mode. */
+/* Call the appropriate functions for the current mode, and exercise some
+functions that are not otherwise called. */
 
 #ifdef SUPPORT_PCRE2_8
 #undef BITS
@@ -7466,7 +8433,7 @@
 if (test_mode == PCRE8_MODE)
   {
   CREATECONTEXTS;
-  SETRECURSEMEMMAN;
+  CONTEXTTESTS;
   }
 #endif
 
@@ -7476,7 +8443,7 @@
 if (test_mode == PCRE16_MODE)
   {
   CREATECONTEXTS;
-  SETRECURSEMEMMAN;
+  CONTEXTTESTS;
   }
 #endif
 
@@ -7486,14 +8453,14 @@
 if (test_mode == PCRE32_MODE)
   {
   CREATECONTEXTS;
-  SETRECURSEMEMMAN;
+  CONTEXTTESTS;
   }
 #endif
 
 /* Set a default parentheses nest limit that is large enough to run the
 standard tests (this also exercises the function). */
 
-PCRE2_SET_PARENS_NEST_LIMIT(default_pat_context, 220);
+PCRE2_SET_PARENS_NEST_LIMIT(default_pat_context, PARENS_NEST_DEFAULT);
 
 /* Handle command line modifier settings, sending any error messages to
 stderr. We need to know the mode before modifying the context, and it is tidier
@@ -7519,18 +8486,22 @@
   infile = fopen(argv[op], INPUT_MODE);
   if (infile == NULL)
     {
-    printf("** Failed to open '%s'\n", argv[op]);
+    printf("** Failed to open '%s': %s\n", argv[op], strerror(errno));
     yield = 1;
     goto EXIT;
     }
   }
 
+#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
+if (INTERACTIVE(infile)) using_history();
+#endif
+
 if (argc > 2)
   {
   outfile = fopen(argv[op+1], OUTPUT_MODE);
   if (outfile == NULL)
     {
-    printf("** Failed to open '%s'\n", argv[op+1]);
+    printf("** Failed to open '%s': %s\n", argv[op+1], strerror(errno));
     yield = 1;
     goto EXIT;
     }
@@ -7563,8 +8534,7 @@
   p = buffer;
 
   /* If we have a pattern set up for testing, or we are skipping after a
-  compile failure, a blank line terminates this test; otherwise process the
-  line as a data line. */
+  compile failure, a blank line terminates this test. */
 
   if (expectdata || skipping)
     {
@@ -7587,14 +8557,21 @@
       skipping = FALSE;
       setlocale(LC_CTYPE, "C");
       }
+
+    /* Otherwise, if we are not skipping, and the line is not a data comment
+    line starting with "\=", process a data line. */
+
     else if (!skipping && !(p[0] == '\\' && p[1] == '=' && isspace(p[2])))
+      {
       rc = process_data();
+      }
     }
 
   /* We do not have a pattern set up for testing. Lines starting with # are
   either comments or special commands. Blank lines are ignored. Otherwise, the
   line must start with a valid delimiter. It is then processed as a pattern
-  line. */
+  line. A copy of the pattern is left in pbuffer8 for use by callouts. Under
+  valgrind, make the unused part of the buffer undefined, to catch overruns. */
 
   else if (*p == '#')
     {
@@ -7655,6 +8632,10 @@
 
 EXIT:
 
+#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
+if (infile != NULL && INTERACTIVE(infile)) clear_history();
+#endif
+
 if (infile != NULL && infile != stdin) fclose(infile);
 if (outfile != NULL && outfile != stdout) fclose(outfile);
 
@@ -7684,7 +8665,9 @@
   G(pcre2_compile_context_free_,BITS)(G(pat_context,BITS)); \
   G(pcre2_compile_context_free_,BITS)(G(default_pat_context,BITS)); \
   G(pcre2_match_context_free_,BITS)(G(dat_context,BITS)); \
-  G(pcre2_match_context_free_,BITS)(G(default_dat_context,BITS))
+  G(pcre2_match_context_free_,BITS)(G(default_dat_context,BITS)); \
+  G(pcre2_convert_context_free_,BITS)(G(default_con_context,BITS)); \
+  G(pcre2_convert_context_free_,BITS)(G(con_context,BITS));
 
 #ifdef SUPPORT_PCRE2_8
 #undef BITS
diff --git a/dist2/src/sljit/sljitConfig.h b/dist2/src/sljit/sljitConfig.h
index a548c37..d54b5e6 100644
--- a/dist2/src/sljit/sljitConfig.h
+++ b/dist2/src/sljit/sljitConfig.h
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -90,16 +90,28 @@
 
 /* Executable code allocation:
    If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
-   define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */
+   define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_EXEC_OFFSET. */
 #ifndef SLJIT_EXECUTABLE_ALLOCATOR
 /* Enabled by default. */
 #define SLJIT_EXECUTABLE_ALLOCATOR 1
+
+/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
+   an allocator which does not set writable and executable
+   permission flags at the same time. The trade-of is increased
+   memory consumption and disabled dynamic code modifications. */
+#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
+/* Disabled by default. */
+#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
+#endif
+
 #endif
 
 /* Force cdecl calling convention even if a better calling
    convention (e.g. fastcall) is supported by the C compiler.
-   If this option is enabled, C functions without
-   SLJIT_CALL can also be called from JIT code. */
+   If this option is disabled (this is the default), functions
+   called from JIT should be defined with SLJIT_FUNC attribute.
+   Standard C functions can still be called by using the
+   SLJIT_CALL_CDECL jump type. */
 #ifndef SLJIT_USE_CDECL_CALLING_CONVENTION
 /* Disabled by default */
 #define SLJIT_USE_CDECL_CALLING_CONVENTION 0
diff --git a/dist2/src/sljit/sljitConfigInternal.h b/dist2/src/sljit/sljitConfigInternal.h
index 566c368..e13282c 100644
--- a/dist2/src/sljit/sljitConfigInternal.h
+++ b/dist2/src/sljit/sljitConfigInternal.h
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -60,11 +60,13 @@
                        a single precision floating point array by index
      SLJIT_F64_SHIFT : the shift required to apply when accessing
                        a double precision floating point array by index
+     SLJIT_PREF_SHIFT_REG : x86 systems prefers ecx for shifting by register
+                            the scratch register index of ecx is stored in this variable
      SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
      SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
 
    Other macros:
-     SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
+     SLJIT_FUNC : calling convention attribute for both calling JIT form C and C calling back from JIT
      SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
 */
 
@@ -187,14 +189,6 @@
 /* External function definitions. */
 /**********************************/
 
-#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
-
-/* These libraries are needed for the macros below. */
-#include <stdlib.h>
-#include <string.h>
-
-#endif /* SLJIT_STD_MACROS_DEFINED */
-
 /* General macros:
    Note: SLJIT is designed to be independent from them as possible.
 
@@ -304,6 +298,13 @@
 #define SLJIT_CACHE_FLUSH(from, to) \
 	sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from))
 
+#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+
+/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+	ppc_cache_flush((from), (to))
+#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
+
 #elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
 
 #define SLJIT_CACHE_FLUSH(from, to) \
@@ -316,13 +317,6 @@
 #define SLJIT_CACHE_FLUSH(from, to) \
     cacheflush((long)(from), (long)(to), 0)
 
-#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-
-/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
-#define SLJIT_CACHE_FLUSH(from, to) \
-	ppc_cache_flush((from), (to))
-#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
-
 #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 
 /* The __clear_cache() implementation of GCC is a dummy function on Sparc. */
@@ -401,7 +395,9 @@
 #ifndef SLJIT_W
 
 /* Defining long constants. */
-#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+#define SLJIT_W(w)	(w##l)
+#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
 #define SLJIT_W(w)	(w##ll)
 #else
 #define SLJIT_W(w)	(w)
@@ -477,44 +473,44 @@
 /* Calling convention of functions generated by SLJIT or called from the generated code. */
 /*****************************************************************************************/
 
-#ifndef SLJIT_CALL
+#ifndef SLJIT_FUNC
 
 #if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
 
 /* Force cdecl. */
-#define SLJIT_CALL
+#define SLJIT_FUNC
 
 #elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 
 #if defined(__GNUC__) && !defined(__APPLE__)
 
-#define SLJIT_CALL __attribute__ ((fastcall))
+#define SLJIT_FUNC __attribute__ ((fastcall))
 #define SLJIT_X86_32_FASTCALL 1
 
 #elif defined(_MSC_VER)
 
-#define SLJIT_CALL __fastcall
+#define SLJIT_FUNC __fastcall
 #define SLJIT_X86_32_FASTCALL 1
 
 #elif defined(__BORLANDC__)
 
-#define SLJIT_CALL __msfastcall
+#define SLJIT_FUNC __msfastcall
 #define SLJIT_X86_32_FASTCALL 1
 
 #else /* Unknown compiler. */
 
 /* The cdecl attribute is the default. */
-#define SLJIT_CALL
+#define SLJIT_FUNC
 
 #endif
 
 #else /* Non x86-32 architectures. */
 
-#define SLJIT_CALL
+#define SLJIT_FUNC
 
 #endif /* SLJIT_CONFIG_X86_32 */
 
-#endif /* !SLJIT_CALL */
+#endif /* !SLJIT_FUNC */
 
 #ifndef SLJIT_INDIRECT_CALL
 #if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \
@@ -545,6 +541,14 @@
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
 #define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
 #define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
+
+#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
+SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
+#define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr)
+#else
+#define SLJIT_EXEC_OFFSET(ptr) 0
+#endif
+
 #endif
 
 /**********************************************/
@@ -553,48 +557,44 @@
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 
-#define SLJIT_NUMBER_OF_REGISTERS 10
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
-#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
-#define SLJIT_LOCALS_OFFSET_BASE ((2 + 4) * sizeof(sljit_sw))
-#else
-/* Maximum 3 arguments are passed on the stack, +1 for double alignment. */
-#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1 + 4) * sizeof(sljit_sw))
-#endif /* SLJIT_X86_32_FASTCALL */
+#define SLJIT_NUMBER_OF_REGISTERS 12
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 9
+#define SLJIT_LOCALS_OFFSET_BASE (compiler->locals_offset)
+#define SLJIT_PREF_SHIFT_REG SLJIT_R2
 
 #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 
+#define SLJIT_NUMBER_OF_REGISTERS 13
 #ifndef _WIN64
-#define SLJIT_NUMBER_OF_REGISTERS 12
 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
-#define SLJIT_LOCALS_OFFSET_BASE (sizeof(sljit_sw))
-#else
-#define SLJIT_NUMBER_OF_REGISTERS 12
+#define SLJIT_LOCALS_OFFSET_BASE 0
+#else /* _WIN64 */
 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
-#define SLJIT_LOCALS_OFFSET_BASE ((4 + 2) * sizeof(sljit_sw))
-#endif /* _WIN64 */
+#define SLJIT_LOCALS_OFFSET_BASE (compiler->locals_offset)
+#endif /* !_WIN64 */
+#define SLJIT_PREF_SHIFT_REG SLJIT_R3
 
 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
 
-#define SLJIT_NUMBER_OF_REGISTERS 11
+#define SLJIT_NUMBER_OF_REGISTERS 12
 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
 #define SLJIT_LOCALS_OFFSET_BASE 0
 
 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
 
-#define SLJIT_NUMBER_OF_REGISTERS 11
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
+#define SLJIT_NUMBER_OF_REGISTERS 12
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
 #define SLJIT_LOCALS_OFFSET_BASE 0
 
 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
 
-#define SLJIT_NUMBER_OF_REGISTERS 25
+#define SLJIT_NUMBER_OF_REGISTERS 26
 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
 #define SLJIT_LOCALS_OFFSET_BASE (2 * sizeof(sljit_sw))
 
 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
 
-#define SLJIT_NUMBER_OF_REGISTERS 22
+#define SLJIT_NUMBER_OF_REGISTERS 23
 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
 #define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * sizeof(sljit_sw))
@@ -607,7 +607,7 @@
 
 #elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
 
-#define SLJIT_NUMBER_OF_REGISTERS 17
+#define SLJIT_NUMBER_OF_REGISTERS 21
 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #define SLJIT_LOCALS_OFFSET_BASE (4 * sizeof(sljit_sw))
@@ -620,8 +620,9 @@
 #define SLJIT_NUMBER_OF_REGISTERS 18
 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 14
 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
-/* Add +1 for double alignment. */
-#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
+/* saved registers (16), return struct pointer (1), space for 6 argument words (1),
+   4th double arg (2), double alignment (1). */
+#define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * sizeof(sljit_sw))
 #endif
 
 #elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
@@ -663,7 +664,7 @@
 
 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
 
-#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP)
+#if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)
 
 /* SLJIT_HALT_PROCESS must halt the process. */
 #ifndef SLJIT_HALT_PROCESS
@@ -675,7 +676,7 @@
 
 #include <stdio.h>
 
-#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */
+#endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */
 
 /* Feel free to redefine these two macros. */
 #ifndef SLJIT_ASSERT
@@ -690,34 +691,33 @@
 
 #endif /* !SLJIT_ASSERT */
 
-#ifndef SLJIT_ASSERT_STOP
+#ifndef SLJIT_UNREACHABLE
 
-#define SLJIT_ASSERT_STOP() \
+#define SLJIT_UNREACHABLE() \
 	do { \
 		printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \
 		SLJIT_HALT_PROCESS(); \
 	} while (0)
 
-#endif /* !SLJIT_ASSERT_STOP */
+#endif /* !SLJIT_UNREACHABLE */
 
 #else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
 
 /* Forcing empty, but valid statements. */
 #undef SLJIT_ASSERT
-#undef SLJIT_ASSERT_STOP
+#undef SLJIT_UNREACHABLE
 
 #define SLJIT_ASSERT(x) \
 	do { } while (0)
-#define SLJIT_ASSERT_STOP() \
+#define SLJIT_UNREACHABLE() \
 	do { } while (0)
 
 #endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
 
 #ifndef SLJIT_COMPILE_ASSERT
 
-/* Should be improved eventually. */
 #define SLJIT_COMPILE_ASSERT(x, description) \
-	SLJIT_ASSERT(x)
+	switch(0) { case 0: case ((x) ? 1 : 0): break; }
 
 #endif /* !SLJIT_COMPILE_ASSERT */
 
diff --git a/dist2/src/sljit/sljitExecAllocator.c b/dist2/src/sljit/sljitExecAllocator.c
index 54f05f5..f500978 100644
--- a/dist2/src/sljit/sljitExecAllocator.c
+++ b/dist2/src/sljit/sljitExecAllocator.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -86,7 +86,7 @@
 	return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
 }
 
-static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
+static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
 {
 	SLJIT_UNUSED_ARG(size);
 	VirtualFree(chunk, 0, MEM_RELEASE);
@@ -96,7 +96,7 @@
 
 static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
 {
-	void* retval;
+	void *retval;
 
 #ifdef MAP_ANON
 	retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
@@ -111,7 +111,7 @@
 	return (retval != MAP_FAILED) ? retval : NULL;
 }
 
-static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
+static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
 {
 	munmap(chunk, size);
 }
@@ -180,8 +180,8 @@
 	sljit_uw chunk_size;
 
 	allocator_grab_lock();
-	if (size < sizeof(struct free_block))
-		size = sizeof(struct free_block);
+	if (size < (64 - sizeof(struct block_header)))
+		size = (64 - sizeof(struct block_header));
 	size = ALIGN_SIZE(size);
 
 	free_block = free_blocks;
diff --git a/dist2/src/sljit/sljitLir.c b/dist2/src/sljit/sljitLir.c
index ec1781e..5e435f0 100644
--- a/dist2/src/sljit/sljitLir.c
+++ b/dist2/src/sljit/sljitLir.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -26,6 +26,14 @@
 
 #include "sljitLir.h"
 
+#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
+
+/* These libraries are needed for the macros below. */
+#include <stdlib.h>
+#include <string.h>
+
+#endif /* SLJIT_STD_MACROS_DEFINED */
+
 #define CHECK_ERROR() \
 	do { \
 		if (SLJIT_UNLIKELY(compiler->error)) \
@@ -76,17 +84,26 @@
 
 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
 
-#define GET_OPCODE(op) \
-	((op) & ~(SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+#define VARIABLE_FLAG_SHIFT (10)
+#define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT)
+#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
 
-#define GET_FLAGS(op) \
-	((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))
+#define GET_OPCODE(op) \
+	((op) & ~(SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
+
+#define HAS_FLAGS(op) \
+	((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
 
 #define GET_ALL_FLAGS(op) \
-	((op) & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+	((op) & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
 
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
 #define TYPE_CAST_NEEDED(op) \
-	(((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16) || ((op) >= SLJIT_MOVU_U8 && (op) <= SLJIT_MOVU_S16))
+	((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)
+#else
+#define TYPE_CAST_NEEDED(op) \
+	((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)
+#endif
 
 #define BUF_SIZE	4096
 
@@ -106,16 +123,19 @@
 /* When reg can be unused. */
 #define SLOW_IS_REG(reg)	((reg) > 0 && (reg) <= REG_MASK)
 
+/* Mask for argument types. */
+#define SLJIT_DEF_MASK ((1 << SLJIT_DEF_SHIFT) - 1)
+
 /* Jump flags. */
 #define JUMP_LABEL	0x1
 #define JUMP_ADDR	0x2
 /* SLJIT_REWRITABLE_JUMP is 0x1000. */
 
 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-#	define PATCH_MB	0x4
-#	define PATCH_MW	0x8
+#	define PATCH_MB		0x4
+#	define PATCH_MW		0x8
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-#	define PATCH_MD	0x10
+#	define PATCH_MD		0x10
 #endif
 #endif
 
@@ -242,9 +262,21 @@
 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
 
 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
+#include "sljitProtExecAllocator.c"
+#else
 #include "sljitExecAllocator.c"
 #endif
 
+#endif
+
+#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
+#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
+#else
+#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
+#endif
+
 /* Argument checking features. */
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
@@ -318,7 +350,7 @@
 /*  Public functions                                                     */
 /* --------------------------------------------------------------------- */
 
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
 #define SLJIT_NEEDS_COMPILER_INIT 1
 static sljit_s32 compiler_initialized = 0;
 /* A thread safe initialization. */
@@ -345,6 +377,8 @@
 		int_op_and_single_op_must_be_the_same);
 	SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_F32_OP,
 		rewritable_jump_and_single_op_must_not_be_the_same);
+	SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_EQUAL_F64 & 0x1) && !(SLJIT_JUMP & 0x1),
+		conditional_flags_must_be_even_numbers);
 
 	/* Only the non-zero members must be set. */
 	compiler->error = SLJIT_SUCCESS;
@@ -479,6 +513,18 @@
 	}
 }
 
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(current_flags);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_I32_OP | SLJIT_SET_Z)) == 0) {
+		compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_I32_OP | SLJIT_SET_Z));
+	}
+#endif
+}
+
 /* --------------------------------------------------------------------- */
 /*  Private functions                                                    */
 /* --------------------------------------------------------------------- */
@@ -553,6 +599,19 @@
 	compiler->buf = prev;
 }
 
+static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
+{
+	sljit_s32 arg_count = 0;
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+	while (arg_types) {
+		arg_count++;
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	return arg_count;
+}
+
 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)
@@ -624,149 +683,108 @@
 	(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-#define FUNCTION_CHECK_OP() \
-	CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
-	switch (GET_OPCODE(op)) { \
-	case SLJIT_NOT: \
-	case SLJIT_CLZ: \
-	case SLJIT_AND: \
-	case SLJIT_OR: \
-	case SLJIT_XOR: \
-	case SLJIT_SHL: \
-	case SLJIT_LSHR: \
-	case SLJIT_ASHR: \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \
-		break; \
-	case SLJIT_NEG: \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
-		break; \
-	case SLJIT_MUL: \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
-		break; \
-	case SLJIT_ADD: \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \
-		break; \
-	case SLJIT_SUB: \
-		break; \
-	case SLJIT_ADDC: \
-	case SLJIT_SUBC: \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \
-		break; \
-	case SLJIT_BREAKPOINT: \
-	case SLJIT_NOP: \
-	case SLJIT_LMUL_UW: \
-	case SLJIT_LMUL_SW: \
-	case SLJIT_MOV: \
-	case SLJIT_MOV_U32: \
-	case SLJIT_MOV_P: \
-	case SLJIT_MOVU: \
-	case SLJIT_MOVU_U32: \
-	case SLJIT_MOVU_P: \
-		/* Nothing allowed */ \
-		CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
-		break; \
-	default: \
-		/* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
-		break; \
-	}
-
-#define FUNCTION_CHECK_FOP() \
-	CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
-	switch (GET_OPCODE(op)) { \
-	case SLJIT_CMP_F64: \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
-		CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_SET_S))); \
-		break; \
-	default: \
-		/* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \
-		CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
-		break; \
-	}
 
 #define FUNCTION_CHECK_IS_REG(r) \
-	(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
-	((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
+	(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \
+	|| ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
 
-#define FUNCTION_CHECK_IS_REG_OR_UNUSED(r) \
-	((r) == SLJIT_UNUSED || \
-	((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
-	((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
+#define FUNCTION_CHECK_IS_FREG(fr) \
+	(((fr) >= SLJIT_FR0 && (fr) < (SLJIT_FR0 + compiler->fscratches)) \
+	|| ((fr) > (SLJIT_FS0 - compiler->fsaveds) && (fr) <= SLJIT_FS0))
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-#define CHECK_NOT_VIRTUAL_REGISTER(p) \
-	CHECK_ARGUMENT((p) < SLJIT_R3 || (p) > SLJIT_R6);
+#define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)
 #else
-#define CHECK_NOT_VIRTUAL_REGISTER(p)
+#define CHECK_IF_VIRTUAL_REGISTER(p) 0
 #endif
 
-#define FUNCTION_CHECK_SRC(p, i) \
-	CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
-	if (FUNCTION_CHECK_IS_REG(p)) \
-		CHECK_ARGUMENT((i) == 0); \
-	else if ((p) == SLJIT_IMM) \
-		; \
-	else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
-		CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
-	else { \
-		CHECK_ARGUMENT((p) & SLJIT_MEM); \
-		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
-		CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
-		if ((p) & OFFS_REG_MASK) { \
-			CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
-			CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
-			CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
-			CHECK_ARGUMENT(!((i) & ~0x3)); \
-		} \
-		CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
+static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
+{
+	if (compiler->scratches == -1 || compiler->saveds == -1)
+		return 0;
+
+	if (!(p & SLJIT_MEM))
+		return 0;
+
+	if (!((p & REG_MASK) == SLJIT_UNUSED || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
+		return 0;
+
+	if (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))
+		return 0;
+
+	if (p & OFFS_REG_MASK) {
+		if ((p & REG_MASK) == SLJIT_UNUSED)
+			return 0;
+
+		if (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))
+			return 0;
+
+		if (CHECK_IF_VIRTUAL_REGISTER(OFFS_REG(p)))
+			return 0;
+
+		if ((i & ~0x3) != 0)
+			return 0;
 	}
 
-#define FUNCTION_CHECK_DST(p, i) \
-	CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
-	if (FUNCTION_CHECK_IS_REG_OR_UNUSED(p)) \
-		CHECK_ARGUMENT((i) == 0); \
-	else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
-		CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
-	else { \
-		CHECK_ARGUMENT((p) & SLJIT_MEM); \
-		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
-		CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
-		if ((p) & OFFS_REG_MASK) { \
-			CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
-			CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
-			CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
-			CHECK_ARGUMENT(!((i) & ~0x3)); \
-		} \
-		CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
-	}
+	return (p & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK)) == 0;
+}
+
+#define FUNCTION_CHECK_SRC_MEM(p, i) \
+	CHECK_ARGUMENT(function_check_src_mem(compiler, p, i));
+
+static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
+{
+	if (compiler->scratches == -1 || compiler->saveds == -1)
+		return 0;
+
+	if (FUNCTION_CHECK_IS_REG(p))
+		return (i == 0);
+
+	if (p == SLJIT_IMM)
+		return 1;
+
+	if (p == SLJIT_MEM1(SLJIT_SP))
+		return (i >= 0 && i < compiler->logical_local_size);
+
+	return function_check_src_mem(compiler, p, i);
+}
+
+#define FUNCTION_CHECK_SRC(p, i) \
+	CHECK_ARGUMENT(function_check_src(compiler, p, i));
+
+static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 unused)
+{
+	if (compiler->scratches == -1 || compiler->saveds == -1)
+		return 0;
+
+	if (FUNCTION_CHECK_IS_REG(p) || ((unused) && (p) == SLJIT_UNUSED))
+		return (i == 0);
+
+	if (p == SLJIT_MEM1(SLJIT_SP))
+		return (i >= 0 && i < compiler->logical_local_size);
+
+	return function_check_src_mem(compiler, p, i);
+}
+
+#define FUNCTION_CHECK_DST(p, i, unused) \
+	CHECK_ARGUMENT(function_check_dst(compiler, p, i, unused));
+
+static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
+{
+	if (compiler->scratches == -1 || compiler->saveds == -1)
+		return 0;
+
+	if (FUNCTION_CHECK_IS_FREG(p))
+		return (i == 0);
+
+	if (p == SLJIT_MEM1(SLJIT_SP))
+		return (i >= 0 && i < compiler->logical_local_size);
+
+	return function_check_src_mem(compiler, p, i);
+}
 
 #define FUNCTION_FCHECK(p, i) \
-	CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); \
-	if (((p) >= SLJIT_FR0 && (p) < (SLJIT_FR0 + compiler->fscratches)) || \
-			((p) > (SLJIT_FS0 - compiler->fsaveds) && (p) <= SLJIT_FS0)) \
-		CHECK_ARGUMENT(i == 0); \
-	else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
-		CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
-	else { \
-		CHECK_ARGUMENT((p) & SLJIT_MEM); \
-		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
-		CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
-		if ((p) & OFFS_REG_MASK) { \
-			CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
-			CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
-			CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
-			CHECK_ARGUMENT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SP) && !(i & ~0x3)); \
-		} \
-		CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
-	}
-
-#define FUNCTION_CHECK_OP1() \
-	if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \
-		CHECK_ARGUMENT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_SP); \
-		CHECK_ARGUMENT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_SP); \
-		if ((src & SLJIT_MEM) && (src & REG_MASK)) \
-			CHECK_ARGUMENT((dst & REG_MASK) != (src & REG_MASK) && OFFS_REG(dst) != (src & REG_MASK)); \
-	}
+	CHECK_ARGUMENT(function_fcheck(compiler, p, i));
 
 #endif /* SLJIT_ARGUMENT_CHECKS */
 
@@ -787,62 +805,72 @@
 #	define SLJIT_PRINT_D	""
 #endif
 
-#define sljit_verbose_reg(compiler, r) \
-	do { \
-		if ((r) < (SLJIT_R0 + compiler->scratches)) \
-			fprintf(compiler->verbose, "r%d", (r) - SLJIT_R0); \
-		else \
-			fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - (r)); \
-	} while (0)
+static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r)
+{
+	if (r < (SLJIT_R0 + compiler->scratches))
+		fprintf(compiler->verbose, "r%d", r - SLJIT_R0);
+	else if (r != SLJIT_SP)
+		fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r);
+	else
+		fprintf(compiler->verbose, "sp");
+}
 
-#define sljit_verbose_param(compiler, p, 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_verbose_reg(compiler, p); \
-	else \
+static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r)
+{
+	if (r < (SLJIT_FR0 + compiler->fscratches))
+		fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0);
+	else
+		fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r);
+}
+
+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_verbose_reg(compiler, p);
+	else
 		fprintf(compiler->verbose, "unused");
+}
 
-#define sljit_verbose_fparam(compiler, p, 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)); \
-	} \
-	else { \
-		if ((p) < (SLJIT_FR0 + compiler->fscratches)) \
-			fprintf(compiler->verbose, "fr%d", (p) - SLJIT_FR0); \
-		else \
-			fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (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));
 	}
+	else
+		sljit_verbose_freg(compiler, p);
+}
 
 static const char* op0_names[] = {
 	(char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw",
@@ -885,12 +913,17 @@
 	(char*)"sig_greater", (char*)"sig_less_equal",
 	(char*)"overflow", (char*)"not_overflow",
 	(char*)"mul_overflow", (char*)"mul_not_overflow",
+	(char*)"carry", (char*)"",
 	(char*)"equal", (char*)"not_equal",
 	(char*)"less", (char*)"greater_equal",
 	(char*)"greater", (char*)"less_equal",
 	(char*)"unordered", (char*)"ordered",
 	(char*)"jump", (char*)"fast_call",
-	(char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
+	(char*)"call", (char*)"call.cdecl"
+};
+
+static char* call_arg_names[] = {
+	(char*)"void", (char*)"sw", (char*)"uw", (char*)"s32", (char*)"u32", (char*)"f32", (char*)"f64"
 };
 
 #endif /* SLJIT_VERBOSE */
@@ -923,56 +956,104 @@
 }
 
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	sljit_s32 types, arg_count, curr_type;
+#endif
+
 	SLJIT_UNUSED_ARG(compiler);
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT));
-	CHECK_ARGUMENT(args >= 0 && args <= 3);
+	CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
 	CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
 	CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
 	CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
-	CHECK_ARGUMENT(args <= saveds);
 	CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
 	CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
 	CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
 	CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+	CHECK_ARGUMENT((arg_types & SLJIT_DEF_MASK) == 0);
+
+	types = (arg_types >> SLJIT_DEF_SHIFT);
+	arg_count = 0;
+	while (types != 0 && arg_count < 3) {
+		curr_type = (types & SLJIT_DEF_MASK);
+		CHECK_ARGUMENT(curr_type == SLJIT_ARG_TYPE_SW || curr_type == SLJIT_ARG_TYPE_UW);
+		arg_count++;
+		types >>= SLJIT_DEF_SHIFT;
+	}
+	CHECK_ARGUMENT(arg_count <= saveds && types == 0);
+
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-	if (SLJIT_UNLIKELY(!!compiler->verbose))
-		fprintf(compiler->verbose, "  enter options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
-			args, scratches, saveds, fscratches, fsaveds, local_size);
+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+		fprintf(compiler->verbose, "  enter options:%s args[", (options & SLJIT_F64_ALIGNMENT) ? "f64_align" : "");
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+		while (arg_types) {
+			fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+			arg_types >>= SLJIT_DEF_SHIFT;
+			if (arg_types)
+				fprintf(compiler->verbose, ",");
+		}
+
+		fprintf(compiler->verbose, "] scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
+			scratches, saveds, fscratches, fsaveds, local_size);
+	}
 #endif
 	CHECK_RETURN_OK;
 }
 
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
-	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
-		compiler->skip_checks = 0;
-		CHECK_RETURN_OK;
-	}
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	sljit_s32 types, arg_count, curr_type;
+#endif
+
+	SLJIT_UNUSED_ARG(compiler);
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(!(options & ~SLJIT_DOUBLE_ALIGNMENT));
-	CHECK_ARGUMENT(args >= 0 && args <= 3);
+	CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
 	CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
 	CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
 	CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
-	CHECK_ARGUMENT(args <= saveds);
 	CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
 	CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
 	CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
 	CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+
+	types = (arg_types >> SLJIT_DEF_SHIFT);
+	arg_count = 0;
+	while (types != 0 && arg_count < 3) {
+		curr_type = (types & SLJIT_DEF_MASK);
+		CHECK_ARGUMENT(curr_type == SLJIT_ARG_TYPE_SW || curr_type == SLJIT_ARG_TYPE_UW);
+		arg_count++;
+		types >>= SLJIT_DEF_SHIFT;
+	}
+	CHECK_ARGUMENT(arg_count <= saveds && types == 0);
+
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-	if (SLJIT_UNLIKELY(!!compiler->verbose))
-		fprintf(compiler->verbose, "  set_context options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
-			args, scratches, saveds, fscratches, fsaveds, local_size);
+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+		fprintf(compiler->verbose, "  set_context options:%s args[", (options & SLJIT_F64_ALIGNMENT) ? "f64_align" : "");
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+		while (arg_types) {
+			fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+			arg_types >>= SLJIT_DEF_SHIFT;
+			if (arg_types)
+				fprintf(compiler->verbose, ",");
+		}
+
+		fprintf(compiler->verbose, "] scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
+			scratches, saveds, fscratches, fsaveds, local_size);
+	}
 #endif
 	CHECK_RETURN_OK;
 }
@@ -987,6 +1068,7 @@
 	}
 	else
 		CHECK_ARGUMENT(src == 0 && srcw == 0);
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1005,7 +1087,8 @@
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	FUNCTION_CHECK_DST(dst, dstw);
+	FUNCTION_CHECK_DST(dst, dstw, 0);
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1021,6 +1104,8 @@
 {
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	FUNCTION_CHECK_SRC(src, srcw);
+	CHECK_ARGUMENT(src != SLJIT_IMM);
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1038,6 +1123,8 @@
 	CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
 		|| ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW));
 	CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2);
+	if (op >= SLJIT_LMUL_UW)
+		compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose))
@@ -1063,23 +1150,48 @@
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
-	FUNCTION_CHECK_OP();
+
+	switch (GET_OPCODE(op)) {
+	case SLJIT_NOT:
+		/* Only SLJIT_I32_OP and SLJIT_SET_Z are allowed. */
+		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
+		break;
+	case SLJIT_NEG:
+		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
+			|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
+		break;
+	case SLJIT_MOV:
+	case SLJIT_MOV_U32:
+	case SLJIT_MOV_P:
+		/* Nothing allowed */
+		CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+		break;
+	default:
+		/* Only SLJIT_I32_OP is allowed. */
+		CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+		break;
+	}
+
+	FUNCTION_CHECK_DST(dst, dstw, 1);
 	FUNCTION_CHECK_SRC(src, srcw);
-	FUNCTION_CHECK_DST(dst, dstw);
-	FUNCTION_CHECK_OP1();
+
+	if (GET_OPCODE(op) >= SLJIT_NOT) {
+		CHECK_ARGUMENT(src != SLJIT_IMM);
+		compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
+	}
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-		if (GET_OPCODE(op) <= SLJIT_MOVU_P)
+		if (GET_OPCODE(op) <= SLJIT_MOV_P)
 		{
-			fprintf(compiler->verbose, "  mov%s%s%s ", (GET_OPCODE(op) >= SLJIT_MOVU) ? "u" : "",
-				!(op & SLJIT_I32_OP) ? "" : "32", (op != SLJIT_MOV32 && op != SLJIT_MOVU32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : "");
+			fprintf(compiler->verbose, "  mov%s%s ", !(op & SLJIT_I32_OP) ? "" : "32",
+				(op != SLJIT_MOV32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : "");
 		}
 		else
 		{
-			fprintf(compiler->verbose, "  %s%s%s%s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
-				!(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s",
-				!(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
+			fprintf(compiler->verbose, "  %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
+				!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
+				!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
 		}
 
 		sljit_verbose_param(compiler, dst, dstw);
@@ -1103,16 +1215,53 @@
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
-	FUNCTION_CHECK_OP();
+
+	switch (GET_OPCODE(op)) {
+	case SLJIT_AND:
+	case SLJIT_OR:
+	case SLJIT_XOR:
+	case SLJIT_SHL:
+	case SLJIT_LSHR:
+	case SLJIT_ASHR:
+		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
+		break;
+	case SLJIT_MUL:
+		CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
+		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
+			|| GET_FLAG_TYPE(op) == SLJIT_MUL_OVERFLOW);
+		break;
+	case SLJIT_ADD:
+		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
+			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
+			|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
+		break;
+	case SLJIT_SUB:
+		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
+			|| (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_OVERFLOW)
+			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
+		break;
+	case SLJIT_ADDC:
+	case SLJIT_SUBC:
+		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
+			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
+		CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
+		CHECK_ARGUMENT((op & SLJIT_I32_OP) == (compiler->last_flags & SLJIT_I32_OP));
+		break;
+	default:
+		SLJIT_UNREACHABLE();
+		break;
+	}
+
+	FUNCTION_CHECK_DST(dst, dstw, 1);
 	FUNCTION_CHECK_SRC(src1, src1w);
 	FUNCTION_CHECK_SRC(src2, src2w);
-	FUNCTION_CHECK_DST(dst, dstw);
+	compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-		fprintf(compiler->verbose, "  %s%s%s%s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
-			!(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s",
-			!(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
+		fprintf(compiler->verbose, "  %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
+			!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
+			!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
 		sljit_verbose_param(compiler, dst, dstw);
 		fprintf(compiler->verbose, ", ");
 		sljit_verbose_param(compiler, src1, src1w);
@@ -1153,6 +1302,7 @@
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	CHECK_ARGUMENT(instruction);
+
 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
 	CHECK_ARGUMENT(size > 0 && size < 16);
 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
@@ -1162,6 +1312,7 @@
 	CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
 #endif
 
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1184,9 +1335,9 @@
 	}
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(sljit_is_fpu_available());
+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);
-	FUNCTION_CHECK_FOP();
+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
 	FUNCTION_FCHECK(src, srcw);
 	FUNCTION_FCHECK(dst, dstw);
 #endif
@@ -1212,22 +1363,31 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
+#endif
+
 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
 		compiler->skip_checks = 0;
 		CHECK_RETURN_OK;
 	}
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(sljit_is_fpu_available());
+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
 	CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
-	FUNCTION_CHECK_FOP();
+	CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
+	CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)
+		|| (GET_FLAG_TYPE(op) >= SLJIT_EQUAL_F64 && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_F64));
 	FUNCTION_FCHECK(src1, src1w);
 	FUNCTION_FCHECK(src2, src2w);
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-		fprintf(compiler->verbose, "  %s%s%s%s ", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64",
-			(op & SLJIT_SET_E) ? ".e" : "", (op & SLJIT_SET_S) ? ".s" : "");
+		fprintf(compiler->verbose, "  %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+		if (op & VARIABLE_FLAG_MASK) {
+			fprintf(compiler->verbose, ".%s_f", jump_names[GET_FLAG_TYPE(op)]);
+		}
+		fprintf(compiler->verbose, " ");
 		sljit_verbose_fparam(compiler, src1, src1w);
 		fprintf(compiler->verbose, ", ");
 		sljit_verbose_fparam(compiler, src2, src2w);
@@ -1247,11 +1407,11 @@
 	}
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(sljit_is_fpu_available());
+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64);
-	FUNCTION_CHECK_FOP();
+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
 	FUNCTION_FCHECK(src, srcw);
-	FUNCTION_CHECK_DST(dst, dstw);
+	FUNCTION_CHECK_DST(dst, dstw, 0);
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1277,9 +1437,9 @@
 	}
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(sljit_is_fpu_available());
+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32);
-	FUNCTION_CHECK_FOP();
+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
 	FUNCTION_CHECK_SRC(src, srcw);
 	FUNCTION_FCHECK(dst, dstw);
 #endif
@@ -1303,9 +1463,9 @@
 	sljit_s32 src2, sljit_sw src2w)
 {
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(sljit_is_fpu_available());
+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);
-	FUNCTION_CHECK_FOP();
+	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
 	FUNCTION_FCHECK(src1, src1w);
 	FUNCTION_FCHECK(src2, src2w);
 	FUNCTION_FCHECK(dst, dstw);
@@ -1328,6 +1488,15 @@
 {
 	SLJIT_UNUSED_ARG(compiler);
 
+	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+		compiler->skip_checks = 0;
+		CHECK_RETURN_OK;
+	}
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->last_flags = 0;
+#endif
+
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose))
 		fprintf(compiler->verbose, "label:\n");
@@ -1344,9 +1513,19 @@
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
-	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3);
+	CHECK_ARGUMENT((type & 0xff) != GET_FLAG_TYPE(SLJIT_SET_CARRY) && (type & 0xff) != (GET_FLAG_TYPE(SLJIT_SET_CARRY) + 1));
+	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);
 	CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP));
-	CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches);
+
+	if ((type & 0xff) < SLJIT_JUMP) {
+		if ((type & 0xff) <= SLJIT_NOT_ZERO)
+			CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
+		else
+			CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
+				|| ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
+				|| ((type & 0xff) == SLJIT_MUL_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_MUL_OVERFLOW));
+		CHECK_ARGUMENT((type & SLJIT_I32_OP) == (compiler->last_flags & SLJIT_I32_OP));
+	}
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose))
@@ -1356,6 +1535,63 @@
 	CHECK_RETURN_OK;
 }
 
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	sljit_s32 i, types, curr_type, scratches, fscratches;
+
+	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
+	CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL || (type & 0xff) == SLJIT_CALL_CDECL);
+
+	types = arg_types;
+	scratches = 0;
+	fscratches = 0;
+	for (i = 0; i < 5; i++) {
+		curr_type = (types & SLJIT_DEF_MASK);
+		CHECK_ARGUMENT(curr_type <= SLJIT_ARG_TYPE_F64);
+		if (i > 0) {
+			if (curr_type == 0) {
+				break;
+			}
+			if (curr_type >= SLJIT_ARG_TYPE_F32)
+				fscratches++;
+			else
+				scratches++;
+		} else {
+			if (curr_type >= SLJIT_ARG_TYPE_F32) {
+				CHECK_ARGUMENT(compiler->fscratches > 0);
+			} else if (curr_type >= SLJIT_ARG_TYPE_SW) {
+				CHECK_ARGUMENT(compiler->scratches > 0);
+			}
+		}
+		types >>= SLJIT_DEF_SHIFT;
+	}
+	CHECK_ARGUMENT(compiler->scratches >= scratches);
+	CHECK_ARGUMENT(compiler->fscratches >= fscratches);
+	CHECK_ARGUMENT(types == 0);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+		fprintf(compiler->verbose, "  %s%s ret[%s", jump_names[type & 0xff],
+			!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+		if (arg_types) {
+			fprintf(compiler->verbose, "], args[");
+			do {
+				fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+				arg_types >>= SLJIT_DEF_SHIFT;
+				if (arg_types)
+					fprintf(compiler->verbose, ",");
+			} while (arg_types);
+		}
+		fprintf(compiler->verbose, "]\n");
+	}
+#endif
+	CHECK_RETURN_OK;
+}
+
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
@@ -1365,6 +1601,7 @@
 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
 	FUNCTION_CHECK_SRC(src1, src1w);
 	FUNCTION_CHECK_SRC(src2, src2w);
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1384,11 +1621,12 @@
 	sljit_s32 src2, sljit_sw src2w)
 {
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(sljit_is_fpu_available());
+	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_F32_OP)));
 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64);
 	FUNCTION_FCHECK(src1, src1w);
 	FUNCTION_FCHECK(src2, src2w);
+	compiler->last_flags = 0;
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1403,7 +1641,8 @@
 	CHECK_RETURN_OK;
 }
 
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 src, sljit_sw srcw)
 {
 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
 		compiler->skip_checks = 0;
@@ -1411,8 +1650,7 @@
 	}
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
-	CHECK_ARGUMENT(type <= SLJIT_CALL0 || (type - SLJIT_CALL0) <= compiler->scratches);
+	CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);
 	FUNCTION_CHECK_SRC(src, srcw);
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
@@ -1425,48 +1663,212 @@
 	CHECK_RETURN_OK;
 }
 
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	sljit_s32 i, types, curr_type, scratches, fscratches;
+
+	CHECK_ARGUMENT(type == SLJIT_CALL || type == SLJIT_CALL_CDECL);
+	FUNCTION_CHECK_SRC(src, srcw);
+
+	types = arg_types;
+	scratches = 0;
+	fscratches = 0;
+	for (i = 0; i < 5; i++) {
+		curr_type = (types & SLJIT_DEF_MASK);
+		CHECK_ARGUMENT(curr_type <= SLJIT_ARG_TYPE_F64);
+		if (i > 0) {
+			if (curr_type == 0) {
+				break;
+			}
+			if (curr_type >= SLJIT_ARG_TYPE_F32)
+				fscratches++;
+			else
+				scratches++;
+		} else {
+			if (curr_type >= SLJIT_ARG_TYPE_F32) {
+				CHECK_ARGUMENT(compiler->fscratches > 0);
+			} else if (curr_type >= SLJIT_ARG_TYPE_SW) {
+				CHECK_ARGUMENT(compiler->scratches > 0);
+			}
+		}
+		types >>= SLJIT_DEF_SHIFT;
+	}
+	CHECK_ARGUMENT(compiler->scratches >= scratches);
+	CHECK_ARGUMENT(compiler->fscratches >= fscratches);
+	CHECK_ARGUMENT(types == 0);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+		fprintf(compiler->verbose, "  i%s%s ret[%s", jump_names[type & 0xff],
+			!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+		if (arg_types) {
+			fprintf(compiler->verbose, "], args[");
+			do {
+				fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+				arg_types >>= SLJIT_DEF_SHIFT;
+				if (arg_types)
+					fprintf(compiler->verbose, ",");
+			} while (arg_types);
+		}
+		fprintf(compiler->verbose, "], ");
+		sljit_verbose_param(compiler, src, srcw);
+		fprintf(compiler->verbose, "\n");
+	}
+#endif
+	CHECK_RETURN_OK;
+}
+
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
-	CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_U32 || GET_OPCODE(op) == SLJIT_MOV_S32
+	CHECK_ARGUMENT((type & 0xff) != GET_FLAG_TYPE(SLJIT_SET_CARRY) && (type & 0xff) != (GET_FLAG_TYPE(SLJIT_SET_CARRY) + 1));
+	CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32
 		|| (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
-	CHECK_ARGUMENT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0);
-	CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS));
-	if (GET_OPCODE(op) < SLJIT_ADD) {
-		CHECK_ARGUMENT(src == SLJIT_UNUSED && srcw == 0);
-	} else {
-		CHECK_ARGUMENT(src == dst && srcw == dstw);
-	}
-	FUNCTION_CHECK_DST(dst, dstw);
+	CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
+
+	if ((type & 0xff) <= SLJIT_NOT_ZERO)
+		CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
+	else
+		CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
+			|| ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
+			|| ((type & 0xff) == SLJIT_MUL_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_MUL_OVERFLOW));
+
+	FUNCTION_CHECK_DST(dst, dstw, 0);
+
+	if (GET_OPCODE(op) >= SLJIT_ADD)
+		compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-		fprintf(compiler->verbose, "  flags %s%s%s%s, ",
-			!(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k",
+		fprintf(compiler->verbose, "  flags%s %s%s, ",
+			!(op & SLJIT_SET_Z) ? "" : ".z",
 			GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
 			GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_I32_OP) ? "32" : ""));
 		sljit_verbose_param(compiler, dst, dstw);
-		if (src != SLJIT_UNUSED) {
-			fprintf(compiler->verbose, ", ");
-			sljit_verbose_param(compiler, src, srcw);
-		}
 		fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type));
 	}
 #endif
 	CHECK_RETURN_OK;
 }
 
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
+	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
+
+	CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
+	CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_I32_OP));
+	if (src != SLJIT_IMM) {
+		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src));
+		CHECK_ARGUMENT(srcw == 0);
+	}
+
+	if ((type & 0xff) <= SLJIT_NOT_ZERO)
+		CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
+	else
+		CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
+			|| ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
+			|| ((type & 0xff) == SLJIT_MUL_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_MUL_OVERFLOW));
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+		fprintf(compiler->verbose, "  cmov%s %s%s, ",
+			!(dst_reg & SLJIT_I32_OP) ? "" : "32",
+			jump_names[type & 0xff], JUMP_POSTFIX(type));
+		sljit_verbose_reg(compiler, dst_reg & ~SLJIT_I32_OP);
+		fprintf(compiler->verbose, ", ");
+		sljit_verbose_param(compiler, src, srcw);
+		fprintf(compiler->verbose, "\n");
+	}
+#endif
+	CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 reg,
+	sljit_s32 mem, sljit_sw memw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
+	CHECK_ARGUMENT(!(type & SLJIT_I32_OP) || ((type & 0xff) != SLJIT_MOV && (type & 0xff) != SLJIT_MOV_U32 && (type & 0xff) != SLJIT_MOV_P));
+	CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
+	CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
+	CHECK_ARGUMENT((type & ~(0xff | SLJIT_I32_OP | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
+
+	FUNCTION_CHECK_SRC_MEM(mem, memw);
+	CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
+
+	CHECK_ARGUMENT((mem & REG_MASK) != SLJIT_UNUSED && (mem & REG_MASK) != reg);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+	if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
+		if (sljit_emit_mem(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
+			fprintf(compiler->verbose, "  //");
+
+		fprintf(compiler->verbose, "  mem%s.%s%s%s ",
+			!(type & SLJIT_I32_OP) ? "" : "32",
+			(type & SLJIT_MEM_STORE) ? "st" : "ld",
+			op1_names[(type & 0xff) - SLJIT_OP1_BASE],
+			(type & SLJIT_MEM_PRE) ? ".pre" : ".post");
+		sljit_verbose_reg(compiler, reg);
+		fprintf(compiler->verbose, ", ");
+		sljit_verbose_param(compiler, mem, memw);
+		fprintf(compiler->verbose, "\n");
+	}
+#endif
+	CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 freg,
+	sljit_s32 mem, sljit_sw memw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
+	CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
+	CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
+	CHECK_ARGUMENT((type & ~(0xff | SLJIT_I32_OP | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
+
+	FUNCTION_CHECK_SRC_MEM(mem, memw);
+	CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg));
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+	if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
+		if (sljit_emit_fmem(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
+			fprintf(compiler->verbose, "  //");
+
+		fprintf(compiler->verbose, "  fmem.%s%s%s ",
+			(type & SLJIT_MEM_STORE) ? "st" : "ld",
+			!(type & SLJIT_I32_OP) ? ".f64" : ".f32",
+			(type & SLJIT_MEM_PRE) ? ".pre" : ".post");
+		sljit_verbose_freg(compiler, freg);
+		fprintf(compiler->verbose, ", ");
+		sljit_verbose_param(compiler, mem, memw);
+		fprintf(compiler->verbose, "\n");
+	}
+#endif
+	CHECK_RETURN_OK;
+}
+
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
 {
+	/* Any offset is allowed. */
 	SLJIT_UNUSED_ARG(offset);
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	FUNCTION_CHECK_DST(dst, dstw);
+	FUNCTION_CHECK_DST(dst, dstw, 0);
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1483,7 +1885,7 @@
 	SLJIT_UNUSED_ARG(init_value);
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	FUNCTION_CHECK_DST(dst, dstw);
+	FUNCTION_CHECK_DST(dst, dstw, 0);
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1544,6 +1946,44 @@
 	return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
 }
 
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
+		|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
+		|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+		|| ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1))
+
+static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	struct sljit_label *label;
+	struct sljit_jump *jump;
+	sljit_s32 op = (dst_reg & SLJIT_I32_OP) ? SLJIT_MOV32 : SLJIT_MOV;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+	jump = sljit_emit_jump(compiler, type ^ 0x1);
+	FAIL_IF(!jump);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+	FAIL_IF(sljit_emit_op1(compiler, op, dst_reg & ~SLJIT_I32_OP, 0, src, srcw));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+	label = sljit_emit_label(compiler);
+	FAIL_IF(!label);
+	sljit_set_label(jump, label);
+	return SLJIT_SUCCESS;
+}
+
+#endif
+
 /* CPU description section */
 
 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
@@ -1645,6 +2085,7 @@
 			condition = SLJIT_SIG_GREATER_EQUAL;
 			break;
 		}
+
 		type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP));
 		tmp_src = src1;
 		src1 = src2;
@@ -1655,11 +2096,9 @@
 	}
 
 	if (condition <= SLJIT_NOT_ZERO)
-		flags = SLJIT_SET_E;
-	else if (condition <= SLJIT_LESS_EQUAL)
-		flags = SLJIT_SET_U;
+		flags = SLJIT_SET_Z;
 	else
-		flags = SLJIT_SET_S;
+		flags = condition << VARIABLE_FLAG_SHIFT;
 
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
@@ -1671,34 +2110,70 @@
 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	compiler->skip_checks = 1;
 #endif
-	return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+	return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
 }
 
+#endif
+
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
-	sljit_s32 flags, condition;
-
 	CHECK_ERROR_PTR();
 	CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
 
-	condition = type & 0xff;
-	flags = (condition <= SLJIT_NOT_EQUAL_F64) ? SLJIT_SET_E : SLJIT_SET_S;
-	if (type & SLJIT_F32_OP)
-		flags |= SLJIT_F32_OP;
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+	sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_I32_OP), src1, src1w, src2, src2w);
 
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	compiler->skip_checks = 1;
 #endif
-	sljit_emit_fop1(compiler, SLJIT_CMP_F64 | flags, src1, src1w, src2, src2w);
+	return sljit_emit_jump(compiler, type);
+}
 
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
-		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	compiler->skip_checks = 1;
+#if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
+	&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+	&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 reg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(type);
+	SLJIT_UNUSED_ARG(reg);
+	SLJIT_UNUSED_ARG(mem);
+	SLJIT_UNUSED_ARG(memw);
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
+
+	return SLJIT_ERR_UNSUPPORTED;
+}
+
 #endif
-	return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+
+#if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+	&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 freg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(type);
+	SLJIT_UNUSED_ARG(freg);
+	SLJIT_UNUSED_ARG(mem);
+	SLJIT_UNUSED_ARG(memw);
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
+
+	return SLJIT_ERR_UNSUPPORTED;
 }
 
 #endif
@@ -1716,7 +2191,7 @@
 	compiler->skip_checks = 1;
 #endif
 	if (offset != 0)
-		return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
+		return sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
 	return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
 }
 
@@ -1731,23 +2206,30 @@
 	return "unsupported";
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
 {
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNUSED_ARG(allocator_data);
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
 {
 	SLJIT_UNUSED_ARG(compiler);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNREACHABLE();
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
 {
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(size);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
@@ -1756,52 +2238,59 @@
 {
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(verbose);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 }
 #endif
 
 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
 {
 	SLJIT_UNUSED_ARG(compiler);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	SLJIT_UNUSED_ARG(feature_type);
+	SLJIT_UNREACHABLE();
+	return 0;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
 {
 	SLJIT_UNUSED_ARG(code);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(options);
-	SLJIT_UNUSED_ARG(args);
+	SLJIT_UNUSED_ARG(arg_types);
 	SLJIT_UNUSED_ARG(scratches);
 	SLJIT_UNUSED_ARG(saveds);
 	SLJIT_UNUSED_ARG(fscratches);
 	SLJIT_UNUSED_ARG(fsaveds);
 	SLJIT_UNUSED_ARG(local_size);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(options);
-	SLJIT_UNUSED_ARG(args);
+	SLJIT_UNUSED_ARG(arg_types);
 	SLJIT_UNUSED_ARG(scratches);
 	SLJIT_UNUSED_ARG(saveds);
 	SLJIT_UNUSED_ARG(fscratches);
 	SLJIT_UNUSED_ARG(fsaveds);
 	SLJIT_UNUSED_ARG(local_size);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -1811,7 +2300,7 @@
 	SLJIT_UNUSED_ARG(op);
 	SLJIT_UNUSED_ARG(src);
 	SLJIT_UNUSED_ARG(srcw);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -1820,7 +2309,7 @@
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(dst);
 	SLJIT_UNUSED_ARG(dstw);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -1829,7 +2318,7 @@
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(src);
 	SLJIT_UNUSED_ARG(srcw);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -1837,7 +2326,7 @@
 {
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(op);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -1851,7 +2340,7 @@
 	SLJIT_UNUSED_ARG(dstw);
 	SLJIT_UNUSED_ARG(src);
 	SLJIT_UNUSED_ARG(srcw);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -1868,13 +2357,13 @@
 	SLJIT_UNUSED_ARG(src1w);
 	SLJIT_UNUSED_ARG(src2);
 	SLJIT_UNUSED_ARG(src2w);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
 {
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return reg;
 }
 
@@ -1884,14 +2373,14 @@
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(instruction);
 	SLJIT_UNUSED_ARG(size);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
 {
-	SLJIT_ASSERT_STOP();
-	return 0;
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(current_flags);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
@@ -1904,7 +2393,7 @@
 	SLJIT_UNUSED_ARG(dstw);
 	SLJIT_UNUSED_ARG(src);
 	SLJIT_UNUSED_ARG(srcw);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -1921,14 +2410,14 @@
 	SLJIT_UNUSED_ARG(src1w);
 	SLJIT_UNUSED_ARG(src2);
 	SLJIT_UNUSED_ARG(src2w);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
 {
 	SLJIT_UNUSED_ARG(compiler);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
@@ -1936,7 +2425,17 @@
 {
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(type);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
+	return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(type);
+	SLJIT_UNUSED_ARG(arg_types);
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
@@ -1950,7 +2449,7 @@
 	SLJIT_UNUSED_ARG(src1w);
 	SLJIT_UNUSED_ARG(src2);
 	SLJIT_UNUSED_ARG(src2w);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
@@ -1964,7 +2463,7 @@
 	SLJIT_UNUSED_ARG(src1w);
 	SLJIT_UNUSED_ARG(src2);
 	SLJIT_UNUSED_ARG(src2w);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
@@ -1972,14 +2471,14 @@
 {
 	SLJIT_UNUSED_ARG(jump);
 	SLJIT_UNUSED_ARG(label);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
 {
 	SLJIT_UNUSED_ARG(jump);
 	SLJIT_UNUSED_ARG(target);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
@@ -1988,23 +2487,68 @@
 	SLJIT_UNUSED_ARG(type);
 	SLJIT_UNUSED_ARG(src);
 	SLJIT_UNUSED_ARG(srcw);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
+	return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(type);
+	SLJIT_UNUSED_ARG(arg_types);
+	SLJIT_UNUSED_ARG(src);
+	SLJIT_UNUSED_ARG(srcw);
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
 	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(op);
 	SLJIT_UNUSED_ARG(dst);
 	SLJIT_UNUSED_ARG(dstw);
+	SLJIT_UNUSED_ARG(type);
+	SLJIT_UNREACHABLE();
+	return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(type);
+	SLJIT_UNUSED_ARG(dst_reg);
 	SLJIT_UNUSED_ARG(src);
 	SLJIT_UNUSED_ARG(srcw);
+	SLJIT_UNREACHABLE();
+	return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
+{
+	SLJIT_UNUSED_ARG(compiler);
 	SLJIT_UNUSED_ARG(type);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNUSED_ARG(reg);
+	SLJIT_UNUSED_ARG(mem);
+	SLJIT_UNUSED_ARG(memw);
+	SLJIT_UNREACHABLE();
+	return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
+{
+	SLJIT_UNUSED_ARG(compiler);
+	SLJIT_UNUSED_ARG(type);
+	SLJIT_UNUSED_ARG(freg);
+	SLJIT_UNUSED_ARG(mem);
+	SLJIT_UNUSED_ARG(memw);
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -2014,7 +2558,7 @@
 	SLJIT_UNUSED_ARG(dst);
 	SLJIT_UNUSED_ARG(dstw);
 	SLJIT_UNUSED_ARG(offset);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
@@ -2024,22 +2568,24 @@
 	SLJIT_UNUSED_ARG(dst);
 	SLJIT_UNUSED_ARG(dstw);
 	SLJIT_UNUSED_ARG(initval);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return NULL;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
 	SLJIT_UNUSED_ARG(addr);
-	SLJIT_UNUSED_ARG(new_addr);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNUSED_ARG(new_target);
+	SLJIT_UNUSED_ARG(executable_offset);
+	SLJIT_UNREACHABLE();
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
 	SLJIT_UNUSED_ARG(addr);
 	SLJIT_UNUSED_ARG(new_constant);
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNUSED_ARG(executable_offset);
+	SLJIT_UNREACHABLE();
 }
 
 #endif
diff --git a/dist2/src/sljit/sljitLir.h b/dist2/src/sljit/sljitLir.h
index df69b86..920f6d4 100644
--- a/dist2/src/sljit/sljitLir.h
+++ b/dist2/src/sljit/sljitLir.h
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -99,6 +99,8 @@
 #define SLJIT_ERR_UNSUPPORTED		4
 /* An ivalid argument is passed to any SLJIT function. */
 #define SLJIT_ERR_BAD_ARGUMENT		5
+/* Dynamic code modification is not enabled. */
+#define SLJIT_ERR_DYN_CODE_MOD		6
 
 /* --------------------------------------------------------------------- */
 /*  Registers                                                            */
@@ -118,8 +120,8 @@
   If an architecture provides two scratch and three saved registers,
   its scratch and saved register sets are the following:
 
-     R0   |  [S4]  |   R0 and S4 represent the same physical register
-     R1   |  [S3]  |   R1 and S3 represent the same physical register
+     R0   |        |   R0 is always a scratch register
+     R1   |        |   R1 is always a scratch register
     [R2]  |   S2   |   R2 and S2 represent the same physical register
     [R3]  |   S1   |   R3 and S1 represent the same physical register
     [R4]  |   S0   |   R4 and S0 represent the same physical register
@@ -127,38 +129,35 @@
   Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and
         SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture.
 
-  Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 10
-        and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 5. However, 4 registers
+  Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12
+        and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 6. However, 6 registers
         are virtual on x86-32. See below.
 
-  The purpose of this definition is convenience. Although a register
-  is either scratch register or saved register, SLJIT allows accessing
-  them from the other set. For example, four registers can be used as
-  scratch registers and the fifth one as saved register on the architecture
-  above. Of course the last two scratch registers (R2 and R3) from this
-  four will be saved on the stack, because they are defined as saved
-  registers in the application binary interface. Still R2 and R3 can be
-  used for referencing to these registers instead of S2 and S1, which
-  makes easier to write platform independent code. Scratch registers
-  can be saved registers in a similar way, but these extra saved
-  registers will not be preserved across function calls! Hence the
-  application must save them on those platforms, where the number of
-  saved registers is too low. This can be done by copy them onto
-  the stack and restore them after a function call.
+  The purpose of this definition is convenience: saved registers can
+  be used as extra scratch registers. For example four registers can
+  be specified as scratch registers and the fifth one as saved register
+  on the CPU above and any user code which requires four scratch
+  registers can run unmodified. The SLJIT compiler automatically saves
+  the content of the two extra scrath register on the stack. Scratch
+  registers can also be preserved by saving their value on the stack
+  but this needs to be done manually.
 
   Note: To emphasize that registers assigned to R2-R4 are saved
-        registers, they are enclosed by square brackets. S3-S4
-        are marked in a similar way.
+        registers, they are enclosed by square brackets.
 
   Note: sljit_emit_enter and sljit_set_context defines whether a register
         is S or R register. E.g: when 3 scratches and 1 saved is mapped
         by sljit_emit_enter, the allowed register set will be: R0-R2 and
         S0. Although S2 is mapped to the same position as R2, it does not
-        available in the current configuration. Furthermore the R3 (S1)
-        register does not available as well.
+        available in the current configuration. Furthermore the S1 register
+        is not available at all.
 */
 
-/* When SLJIT_UNUSED is specified as destination, the result is discarded. */
+/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1
+   or sljit_emit_op2 operations the result is discarded. If no status
+   flags are set, no instructions are emitted for these operations. Data
+   prefetch is a special exception, see SLJIT_MOV operation. Other SLJIT
+   operations do not support SLJIT_UNUSED as a destination operand. */
 #define SLJIT_UNUSED		0
 
 /* Scratch registers. */
@@ -214,14 +213,6 @@
 
 #define SLJIT_RETURN_REG	SLJIT_R0
 
-/* x86 prefers specific registers for special purposes. In case of shift
-   by register it supports only SLJIT_R2 for shift argument
-   (which is the src2 argument of sljit_emit_op2). If another register is
-   used, sljit must exchange data between registers which cause a minor
-   slowdown. Other architectures has no such limitation. */
-
-#define SLJIT_PREF_SHIFT_REG	SLJIT_R2
-
 /* --------------------------------------------------------------------- */
 /*  Floating point registers                                             */
 /* --------------------------------------------------------------------- */
@@ -259,6 +250,79 @@
 #define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1)
 
 /* --------------------------------------------------------------------- */
+/*  Argument type definitions                                            */
+/* --------------------------------------------------------------------- */
+
+/* Argument type definitions.
+   Used by SLJIT_[DEF_]ARGx and SLJIT_[DEF]_RET macros. */
+
+#define SLJIT_ARG_TYPE_VOID 0
+#define SLJIT_ARG_TYPE_SW 1
+#define SLJIT_ARG_TYPE_UW 2
+#define SLJIT_ARG_TYPE_S32 3
+#define SLJIT_ARG_TYPE_U32 4
+#define SLJIT_ARG_TYPE_F32 5
+#define SLJIT_ARG_TYPE_F64 6
+
+/* The following argument type definitions are used by sljit_emit_enter,
+   sljit_set_context, sljit_emit_call, and sljit_emit_icall functions.
+   The following return type definitions are used by sljit_emit_call
+   and sljit_emit_icall functions.
+
+   When a function is called, the first integer argument must be placed
+   in SLJIT_R0, the second in SLJIT_R1, and so on. Similarly the first
+   floating point argument must be placed in SLJIT_FR0, the second in
+   SLJIT_FR1, and so on.
+
+   Example function definition:
+     sljit_f32 SLJIT_FUNC example_c_callback(sljit_sw arg_a,
+         sljit_f64 arg_b, sljit_u32 arg_c, sljit_f32 arg_d);
+
+   Argument type definition:
+     SLJIT_DEF_RET(SLJIT_ARG_TYPE_F32)
+        | SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_SW) | SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_F64)
+        | SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_U32) | SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_F32)
+
+   Short form of argument type definition:
+     SLJIT_RET(F32) | SLJIT_ARG1(SW) | SLJIT_ARG2(F64)
+        | SLJIT_ARG3(S32) | SLJIT_ARG4(F32)
+
+   Argument passing:
+     arg_a must be placed in SLJIT_R0
+     arg_c must be placed in SLJIT_R1
+     arg_b must be placed in SLJIT_FR0
+     arg_d must be placed in SLJIT_FR1
+
+Note:
+   The SLJIT_ARG_TYPE_VOID type is only supported by
+   SLJIT_DEF_RET, and SLJIT_ARG_TYPE_VOID is also the
+   default value when SLJIT_DEF_RET is not specified. */
+#define SLJIT_DEF_SHIFT 4
+#define SLJIT_DEF_RET(type) (type)
+#define SLJIT_DEF_ARG1(type) ((type) << SLJIT_DEF_SHIFT)
+#define SLJIT_DEF_ARG2(type) ((type) << (2 * SLJIT_DEF_SHIFT))
+#define SLJIT_DEF_ARG3(type) ((type) << (3 * SLJIT_DEF_SHIFT))
+#define SLJIT_DEF_ARG4(type) ((type) << (4 * SLJIT_DEF_SHIFT))
+
+/* Short form of the macros above.
+
+   For example the following definition:
+   SLJIT_DEF_RET(SLJIT_ARG_TYPE_SW) | SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_F32)
+
+   can be shortened to:
+   SLJIT_RET(SW) | SLJIT_ARG1(F32)
+
+Note:
+   The VOID type is only supported by SLJIT_RET, and
+   VOID is also the default value when SLJIT_RET is
+   not specified. */
+#define SLJIT_RET(type) SLJIT_DEF_RET(SLJIT_ARG_TYPE_ ## type)
+#define SLJIT_ARG1(type) SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_ ## type)
+#define SLJIT_ARG2(type) SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_ ## type)
+#define SLJIT_ARG3(type) SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_ ## type)
+#define SLJIT_ARG4(type) SLJIT_DEF_ARG4(SLJIT_ARG_TYPE_ ## type)
+
+/* --------------------------------------------------------------------- */
 /*  Main structures and functions                                        */
 /* --------------------------------------------------------------------- */
 
@@ -323,19 +387,23 @@
 	sljit_s32 local_size;
 	/* Code size. */
 	sljit_uw size;
-	/* For statistical purposes. */
+	/* Relative offset of the executable mapping from the writable mapping. */
+	sljit_uw executable_offset;
+	/* Executable size for statistical purposes. */
 	sljit_uw executable_size;
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 	sljit_s32 args;
+	sljit_s32 locals_offset;
+	sljit_s32 saveds_offset;
+	sljit_s32 stack_tmp_size;
 #endif
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 	sljit_s32 mode32;
+#ifdef _WIN64
+	sljit_s32 locals_offset;
 #endif
-
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-	sljit_s32 flags_saved;
 #endif
 
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
@@ -352,24 +420,10 @@
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
 	/* Temporary fields. */
 	sljit_uw shift_imm;
-	sljit_s32 cache_arg;
-	sljit_sw cache_argw;
-#endif
-
-#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-	sljit_s32 cache_arg;
-	sljit_sw cache_argw;
-#endif
-
-#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
-	sljit_s32 cache_arg;
-	sljit_sw cache_argw;
 #endif
 
 #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
 	sljit_sw imm;
-	sljit_s32 cache_arg;
-	sljit_sw cache_argw;
 #endif
 
 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
@@ -395,6 +449,9 @@
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
 		|| (defined SLJIT_DEBUG && SLJIT_DEBUG)
+	/* Flags specified by the last arithmetic instruction.
+	   It contains the type of the variable flag. */
+	sljit_s32 last_flags;
 	/* Local size passed to the functions. */
 	sljit_s32 logical_local_size;
 #endif
@@ -402,6 +459,7 @@
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
 		|| (defined SLJIT_DEBUG && SLJIT_DEBUG) \
 		|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+	/* Trust arguments when the API function is called. */
 	sljit_s32 skip_checks;
 #endif
 };
@@ -455,44 +513,89 @@
 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
 #endif
 
+/*
+   Create executable code from the sljit instruction stream. This is the final step
+   of the code generation so no more instructions can be added after this call.
+*/
+
 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
+
+/* Free executable code. */
+
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
 
 /*
-   After the machine code generation is finished we can retrieve the allocated
-   executable memory size, although this area may not be fully filled with
-   instructions depending on some optimizations. This function is useful only
-   for statistical purposes.
+   When the protected executable allocator is used the JIT code is mapped
+   twice. The first mapping has read/write and the second mapping has read/exec
+   permissions. This function returns with the relative offset of the executable
+   mapping using the writable mapping as the base after the machine code is
+   successfully generated. The returned value is always 0 for the normal executable
+   allocator, since it uses only one mapping with read/write/exec permissions.
+   Dynamic code modifications requires this value.
+
+   Before a successful code generation, this function returns with 0.
+*/
+static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; }
+
+/*
+   The executable memory consumption of the generated code can be retrieved by
+   this function. The returned value can be used for statistical purposes.
 
    Before a successful code generation, this function returns with 0.
 */
 static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
 
+/* Returns with non-zero if the feature or limitation type passed as its
+   argument is present on the current CPU.
+
+   Some features (e.g. floating point operations) require hardware (CPU)
+   support while others (e.g. move with update) are emulated if not available.
+   However even if a feature is emulated, specialized code paths can be faster
+   than the emulation. Some limitations are emulated as well so their general
+   case is supported but it has extra performance costs. */
+
+/* [Not emulated] Floating-point support is available. */
+#define SLJIT_HAS_FPU			0
+/* [Limitation] Some registers are virtual registers. */
+#define SLJIT_HAS_VIRTUAL_REGISTERS	1
+/* [Emulated] Count leading zero is supported. */
+#define SLJIT_HAS_CLZ			2
+/* [Emulated] Conditional move is supported. */
+#define SLJIT_HAS_CMOV			3
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+/* [Not emulated] SSE2 support is available on x86. */
+#define SLJIT_HAS_SSE2			100
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type);
+
 /* Instruction generation. Returns with any error code. If there is no
    error, they return with SLJIT_SUCCESS. */
 
 /*
-   The executable code is a function call from the viewpoint of the C
+   The executable code is a function from the viewpoint of the C
    language. The function calls must obey to the ABI (Application
    Binary Interface) of the platform, which specify the purpose of
-   all machine registers and stack handling among other things. The
+   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 and moves function
    arguments to the saved registers. Furthermore the options argument
    can be used to pass configuration options to the compiler. The
    available options are listed before sljit_emit_enter.
 
-   The number of sljit_sw arguments passed to the generated function
-   are specified in the "args" parameter. The number of arguments must
-   be less than or equal to 3. The first argument goes to SLJIT_S0,
-   the second goes to SLJIT_S1 and so on. The register set used by
-   the function must be declared as well. The number of scratch and
-   saved registers used by 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 2, the register set will be
-   limited to R0 and R1. The S registers and the floating point
+   The function argument list is the combination of SLJIT_ARGx
+   (SLJIT_DEF_ARG1) macros. Currently maximum 3 SW / UW
+   (SLJIT_ARG_TYPE_SW / LJIT_ARG_TYPE_UW) arguments are supported.
+   The first argument goes to SLJIT_S0, the second goes to SLJIT_S1
+   and so on. The register set used by the function must be declared
+   as well. The number of scratch and saved registers used by 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 2, 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
-   way. The sljit_emit_enter is also capable of allocating a stack
+   manner. The sljit_emit_enter is also capable of allocating a stack
    space for local variables. The "local_size" argument contains the
    size in bytes of this local area and its staring address is stored
    in SLJIT_SP. The memory area between SLJIT_SP (inclusive) and
@@ -512,14 +615,14 @@
 */
 
 /* The absolute address returned by sljit_get_local_base with
-offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */
-#define SLJIT_DOUBLE_ALIGNMENT 0x00000001
+offset 0 is aligned to sljit_f64. Otherwise it is aligned to sljit_sw. */
+#define SLJIT_F64_ALIGNMENT 0x00000001
 
 /* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */
 #define SLJIT_MAX_LOCAL_SIZE	65536
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
 
 /* The machine code has a context (which contains the local stack space size,
@@ -533,7 +636,7 @@
          the previous context. */
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
 
 /* Return from machine code.  The op argument can be SLJIT_UNUSED which means the
@@ -545,26 +648,31 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 src, sljit_sw srcw);
 
-/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and
-   even the stack frame is passed to the callee. The return address is preserved in
-   dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function
-   is sljit_p), and sljit_emit_fast_return can use this as a return value later. */
+/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL).
+   Both sljit_emit_fast_enter and sljit_emit_fast_return functions preserve the
+   values of all registers and stack frame. The return address is stored in the
+   dst argument of sljit_emit_fast_enter, and this return address can be passed
+   to sljit_emit_fast_return to continue the execution after the fast call.
 
-/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine
-   instructions are needed. Excellent for small uility functions, where saving registers
-   and setting up a new stack frame would cost too much performance. However, it is still
-   possible to return to the address of the caller (or anywhere else). */
+   Fast calls are cheap operations (usually only a single call instruction is
+   emitted) but they do not preserve any registers. However the callee function
+   can freely use / update any registers and stack values which can be
+   efficiently exploited by various optimizations. Registers can be saved
+   manually by the callee function if needed.
 
-/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */
+   Although returning to different address by sljit_emit_fast_return is possible,
+   this address usually cannot be predicted by the return address predictor of
+   modern CPUs which may reduce performance. Furthermore using sljit_emit_ijump
+   to return is also inefficient since return address prediction is usually
+   triggered by a specific form of ijump.
 
-/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
-   since many architectures do clever branch prediction on call / return instruction pairs. */
+   Flags: - (does not modify flags). */
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw);
 
 /*
-   Source and destination values for arithmetical instructions
+   Source and destination operands for arithmetical instructions
     imm              - a simple immediate value (cannot be used as a destination)
     reg              - any of the registers (immediate argument must be 0)
     [imm]            - absolute immediate memory address
@@ -605,6 +713,9 @@
    arm-t2: [reg+imm], -255 <= imm <= 4095
            [reg+(reg<<imm)] is supported
            Write back is supported only for [reg+imm], where -255 <= imm <= 255
+   arm64:  [reg+imm], -256 <= imm <= 255, 0 <= aligned imm <= 4095 * alignment
+           [reg+(reg<<imm)] is supported
+           Write back is supported only for [reg+imm], where -256 <= imm <= 255
    ppc:    [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
                 signed load on 64 bit requires immediates divisible by 4.
                 [reg+imm] is not supported for signed 8 bit values.
@@ -616,65 +727,104 @@
            [reg+reg] is supported
 */
 
-/* Register output: simply the name of the register.
-   For destination, you can use SLJIT_UNUSED as well. */
+/* Macros for specifying operand types. */
 #define SLJIT_MEM		0x80
 #define SLJIT_MEM0()		(SLJIT_MEM)
 #define SLJIT_MEM1(r1)		(SLJIT_MEM | (r1))
 #define SLJIT_MEM2(r1, r2)	(SLJIT_MEM | (r1) | ((r2) << 8))
 #define SLJIT_IMM		0x40
 
-/* Set 32 bit operation mode (I) on 64 bit CPUs. This flag is ignored on 32
-   bit CPUs. When this flag is set for an arithmetic operation, only the
-   lower 32 bit of the input register(s) are used, and the CPU status flags
-   are set according to the 32 bit result. Although the higher 32 bit of
-   the input and the result registers are not defined by SLJIT, it might be
-   defined by the CPU architecture (e.g. MIPS). To satisfy these requirements
-   all source registers must be computed by operations where this flag is
-   also set. In other words 32 and 64 bit arithmetic operations cannot be
-   mixed. The only exception is SLJIT_IMOV and SLJIT_IMOVU whose source
-   register can hold any 32 or 64 bit value. This source register is
-   converted to a 32 bit compatible format. SLJIT does not generate any
-   instructions on certain CPUs (e.g. on x86 and ARM) if the source and
-   destination operands are the same registers. Affects sljit_emit_op0,
-   sljit_emit_op1 and sljit_emit_op2. */
+/* Set 32 bit operation mode (I) on 64 bit CPUs. This option is ignored on
+   32 bit CPUs. When this option is set for an arithmetic operation, only
+   the lower 32 bit of the input registers are used, and the CPU status
+   flags are set according to the 32 bit result. Although the higher 32 bit
+   of the input and the result registers are not defined by SLJIT, it might
+   be defined by the CPU architecture (e.g. MIPS). To satisfy these CPU
+   requirements all source registers must be the result of those operations
+   where this option was also set. Memory loads read 32 bit values rather
+   than 64 bit ones. In other words 32 bit and 64 bit operations cannot
+   be mixed. The only exception is SLJIT_MOV32 and SLJIT_MOVU32 whose source
+   register can hold any 32 or 64 bit value, and it is converted to a 32 bit
+   compatible format first. This conversion is free (no instructions are
+   emitted) on most CPUs. A 32 bit value can also be coverted to a 64 bit
+   value by SLJIT_MOV_S32 (sign extension) or SLJIT_MOV_U32 (zero extension).
+
+   Note: memory addressing always uses 64 bit values on 64 bit systems so
+         the result of a 32 bit operation must not be used with SLJIT_MEMx
+         macros.
+
+   This option is part of the instruction name, so there is no need to
+   manually set it. E.g:
+
+     SLJIT_ADD32 == (SLJIT_ADD | SLJIT_I32_OP) */
 #define SLJIT_I32_OP		0x100
 
-/* F32 precision mode (SP). This flag is similar to SLJIT_I32_OP, just
-   it applies to floating point registers (it is even the same bit). When
-   this flag is passed, the CPU performs 32 bit floating point operations.
-   Similar to SLJIT_I32_OP, all register arguments must be computed by
-   floating point operations where this flag is also set. Affects
-   sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */
-#define SLJIT_F32_OP		0x100
+/* Set F32 (single) precision mode for floating-point computation. This
+   option is similar to SLJIT_I32_OP, it just applies to floating point
+   registers. When this option is passed, the CPU performs 32 bit floating
+   point operations, rather than 64 bit one. Similar to SLJIT_I32_OP, all
+   register arguments must be the result of those operations where this
+   option was also set.
 
-/* Common CPU status flags for all architectures (x86, ARM, PPC)
-    - carry flag
-    - overflow flag
-    - zero flag
-    - negative/positive flag (depends on arc)
-   On mips, these flags are emulated by software. */
+   This option is part of the instruction name, so there is no need to
+   manually set it. E.g:
 
-/* By default, the instructions may, or may not set the CPU status flags.
-   Forcing to set or keep status flags can be done with the following flags: */
+     SLJIT_MOV_F32 = (SLJIT_MOV_F64 | SLJIT_F32_OP)
+ */
+#define SLJIT_F32_OP		SLJIT_I32_OP
 
-/* Note: sljit tries to emit the minimum number of instructions. Using these
-   flags can increase them, so use them wisely to avoid unnecessary code generation. */
+/* Many CPUs (x86, ARM, PPC) has status flags which can be set according
+   to the result of an operation. Other CPUs (MIPS) does not have status
+   flags, and results must be stored in registers. To cover both architecture
+   types efficiently only two flags are defined by SLJIT:
 
-/* Set Equal (Zero) status flag (E). */
-#define SLJIT_SET_E			0x0200
-/* Set unsigned status flag (U). */
-#define SLJIT_SET_U			0x0400
-/* Set signed status flag (S). */
-#define SLJIT_SET_S			0x0800
-/* Set signed overflow flag (O). */
-#define SLJIT_SET_O			0x1000
-/* Set carry flag (C).
-   Note: Kinda unsigned overflow, but behaves differently on various cpus. */
-#define SLJIT_SET_C			0x2000
-/* Do not modify the flags (K).
-   Note: This flag cannot be combined with any other SLJIT_SET_* flag. */
-#define SLJIT_KEEP_FLAGS		0x4000
+    * Zero (equal) flag: it is set if the result is zero
+    * Variable flag: its value is defined by the last arithmetic operation
+
+   SLJIT instructions can set any or both of these flags. The value of
+   these flags is undefined if the instruction does not specify their value.
+   The description of each instruction contains the list of allowed flag
+   types.
+
+   Example: SLJIT_ADD can set the Z, OVERFLOW, CARRY flags hence
+
+     sljit_op2(..., SLJIT_ADD, ...)
+       Both the zero and variable flags are undefined so they can
+       have any value after the operation is completed.
+
+     sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)
+       Sets the zero flag if the result is zero, clears it otherwise.
+       The variable flag is undefined.
+
+     sljit_op2(..., SLJIT_ADD | SLJIT_SET_OVERFLOW, ...)
+       Sets the variable flag if an integer overflow occurs, clears
+       it otherwise. The zero flag is undefined.
+
+     sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z | SLJIT_SET_CARRY, ...)
+       Sets the zero flag if the result is zero, clears it otherwise.
+       Sets the variable flag if unsigned overflow (carry) occurs,
+       clears it otherwise.
+
+   If an instruction (e.g. SLJIT_MOV) does not modify flags the flags are
+   unchanged.
+
+   Using these flags can reduce the number of emitted instructions. E.g. a
+   fast loop can be implemented by decreasing a counter register and set the
+   zero flag to jump back if the counter register is not reached zero.
+
+   Motivation: although CPUs can set a large number of flags, usually their
+   values are ignored or only one of them is used. Emulating a large number
+   of flags on systems without flag register is complicated so SLJIT
+   instructions must specify the flag they want to use and only that flag
+   will be emulated. The last arithmetic instruction can be repeated if
+   multiple flags needs to be checked.
+*/
+
+/* Set Zero status flag. */
+#define SLJIT_SET_Z			0x0200
+/* Set the variable status flag if condition is true.
+   See comparison types. */
+#define SLJIT_SET(condition)			((condition) << 10)
 
 /* Notes:
      - you cannot postpone conditional jump instructions except if noted that
@@ -684,11 +834,11 @@
 /* Starting index of opcodes for sljit_emit_op0. */
 #define SLJIT_OP0_BASE			0
 
-/* Flags: - (never set any flags)
+/* Flags: - (does not modify flags)
    Note: breakpoint instruction is not supported by all architectures (e.g. ppc)
          It falls back to SLJIT_NOP in those cases. */
 #define SLJIT_BREAKPOINT		(SLJIT_OP0_BASE + 0)
-/* Flags: - (never set any flags)
+/* Flags: - (does not modify flags)
    Note: may or may not cause an extra cycle wait
          it can even decrease the runtime in a few cases. */
 #define SLJIT_NOP			(SLJIT_OP0_BASE + 1)
@@ -700,13 +850,13 @@
    Signed multiplication of SLJIT_R0 and SLJIT_R1.
    Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
 #define SLJIT_LMUL_SW			(SLJIT_OP0_BASE + 3)
-/* Flags: I - (may destroy flags)
+/* Flags: - (may destroy flags)
    Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
    The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
    Note: if SLJIT_R1 is 0, the behaviour is undefined. */
 #define SLJIT_DIVMOD_UW			(SLJIT_OP0_BASE + 4)
 #define SLJIT_DIVMOD_U32		(SLJIT_DIVMOD_UW | SLJIT_I32_OP)
-/* Flags: I - (may destroy flags)
+/* Flags: - (may destroy flags)
    Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
    The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
    Note: if SLJIT_R1 is 0, the behaviour is undefined.
@@ -714,13 +864,13 @@
          the behaviour is undefined. */
 #define SLJIT_DIVMOD_SW			(SLJIT_OP0_BASE + 5)
 #define SLJIT_DIVMOD_S32		(SLJIT_DIVMOD_SW | SLJIT_I32_OP)
-/* Flags: I - (may destroy flags)
+/* Flags: - (may destroy flags)
    Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
    The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
    Note: if SLJIT_R1 is 0, the behaviour is undefined. */
 #define SLJIT_DIV_UW			(SLJIT_OP0_BASE + 6)
 #define SLJIT_DIV_U32			(SLJIT_DIV_UW | SLJIT_I32_OP)
-/* Flags: I - (may destroy flags)
+/* Flags: - (may destroy flags)
    Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
    The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
    Note: if SLJIT_R1 is 0, the behaviour is undefined.
@@ -734,76 +884,67 @@
 /* Starting index of opcodes for sljit_emit_op1. */
 #define SLJIT_OP1_BASE			32
 
-/* Notes for MOV instructions:
-   U = Mov with update (pre form). If source or destination defined as SLJIT_MEM1(r1)
-       or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
-   UB = unsigned byte (8 bit)
-   SB = signed byte (8 bit)
-   UH = unsigned half (16 bit)
-   SH = signed half (16 bit)
-   UI = unsigned int (32 bit)
-   SI = signed int (32 bit)
-   P  = pointer (sljit_p) size */
+/* The MOV instruction transfer data from source to destination.
 
-/* Flags: - (never set any flags) */
+   MOV instruction suffixes:
+
+   U8  - unsigned 8 bit data transfer
+   S8  - signed 8 bit data transfer
+   U16 - unsigned 16 bit data transfer
+   S16 - signed 16 bit data transfer
+   U32 - unsigned int (32 bit) data transfer
+   S32 - signed int (32 bit) data transfer
+   P   - pointer (sljit_p) data transfer
+
+   If the destination of a MOV instruction is SLJIT_UNUSED and the source
+   operand is a memory address the compiler emits a prefetch instruction
+   if this instruction is supported by the current CPU. Higher data sizes
+   bring the data closer to the core: a MOV with word size loads the data
+   into a higher level cache than a byte size. Otherwise the type does not
+   affect the prefetch instruction. Furthermore a prefetch instruction
+   never fails, so it can be used to prefetch a data from an address and
+   check whether that address is NULL afterwards.
+*/
+
+/* Flags: - (does not modify flags) */
 #define SLJIT_MOV			(SLJIT_OP1_BASE + 0)
-/* Flags: I - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_MOV_U8			(SLJIT_OP1_BASE + 1)
 #define SLJIT_MOV32_U8			(SLJIT_MOV_U8 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_MOV_S8			(SLJIT_OP1_BASE + 2)
 #define SLJIT_MOV32_S8			(SLJIT_MOV_S8 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_MOV_U16			(SLJIT_OP1_BASE + 3)
 #define SLJIT_MOV32_U16			(SLJIT_MOV_U16 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_MOV_S16			(SLJIT_OP1_BASE + 4)
 #define SLJIT_MOV32_S16			(SLJIT_MOV_S16 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags)
+/* Flags: - (does not modify flags)
    Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */
 #define SLJIT_MOV_U32			(SLJIT_OP1_BASE + 5)
-/* Flags: I - (never set any flags)
+/* Flags: - (does not modify flags)
    Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */
 #define SLJIT_MOV_S32			(SLJIT_OP1_BASE + 6)
-/* Flags: I - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_MOV32			(SLJIT_MOV_S32 | SLJIT_I32_OP)
-/* Flags: - (never set any flags) */
+/* Flags: - (does not modify flags)
+   Note: load a pointer sized data, useful on x32 (a 32 bit mode on x86-64
+         where all x64 features are available, e.g. 16 register) or similar
+         compiling modes */
 #define SLJIT_MOV_P			(SLJIT_OP1_BASE + 7)
-/* Flags: - (never set any flags) */
-#define SLJIT_MOVU			(SLJIT_OP1_BASE + 8)
-/* Flags: I - (never set any flags) */
-#define SLJIT_MOVU_U8			(SLJIT_OP1_BASE + 9)
-#define SLJIT_MOVU32_U8			(SLJIT_MOVU_U8 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags) */
-#define SLJIT_MOVU_S8			(SLJIT_OP1_BASE + 10)
-#define SLJIT_MOVU32_S8			(SLJIT_MOVU_S8 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags) */
-#define SLJIT_MOVU_U16			(SLJIT_OP1_BASE + 11)
-#define SLJIT_MOVU32_U16			(SLJIT_MOVU_U16 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags) */
-#define SLJIT_MOVU_S16			(SLJIT_OP1_BASE + 12)
-#define SLJIT_MOVU32_S16		(SLJIT_MOVU_S16 | SLJIT_I32_OP)
-/* Flags: I - (never set any flags)
-   Note: no SLJIT_MOVU32_U32 form, since it is the same as SLJIT_MOVU32 */
-#define SLJIT_MOVU_U32			(SLJIT_OP1_BASE + 13)
-/* Flags: I - (never set any flags)
-   Note: no SLJIT_MOVU32_S32 form, since it is the same as SLJIT_MOVU32 */
-#define SLJIT_MOVU_S32			(SLJIT_OP1_BASE + 14)
-/* Flags: I - (never set any flags) */
-#define SLJIT_MOVU32			(SLJIT_MOVU_S32 | SLJIT_I32_OP)
-/* Flags: - (never set any flags) */
-#define SLJIT_MOVU_P			(SLJIT_OP1_BASE + 15)
-/* Flags: I | E | K */
-#define SLJIT_NOT			(SLJIT_OP1_BASE + 16)
+/* Flags: Z
+   Note: immediate source argument is not supported */
+#define SLJIT_NOT			(SLJIT_OP1_BASE + 8)
 #define SLJIT_NOT32			(SLJIT_NOT | SLJIT_I32_OP)
-/* Flags: I | E | O | K */
-#define SLJIT_NEG			(SLJIT_OP1_BASE + 17)
+/* Flags: Z | OVERFLOW
+   Note: immediate source argument is not supported */
+#define SLJIT_NEG			(SLJIT_OP1_BASE + 9)
 #define SLJIT_NEG32			(SLJIT_NEG | SLJIT_I32_OP)
 /* Count leading zeroes
-   Flags: I | E | K
-   Important note! Sparc 32 does not support K flag, since
-   the required popc instruction is introduced only in sparc 64. */
-#define SLJIT_CLZ			(SLJIT_OP1_BASE + 18)
+   Flags: - (may destroy flags)
+   Note: immediate source argument is not supported */
+#define SLJIT_CLZ			(SLJIT_OP1_BASE + 10)
 #define SLJIT_CLZ32			(SLJIT_CLZ | SLJIT_I32_OP)
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
@@ -813,46 +954,48 @@
 /* Starting index of opcodes for sljit_emit_op2. */
 #define SLJIT_OP2_BASE			96
 
-/* Flags: I | E | O | C | K */
+/* Flags: Z | OVERFLOW | CARRY */
 #define SLJIT_ADD			(SLJIT_OP2_BASE + 0)
 #define SLJIT_ADD32			(SLJIT_ADD | SLJIT_I32_OP)
-/* Flags: I | C | K */
+/* Flags: CARRY */
 #define SLJIT_ADDC			(SLJIT_OP2_BASE + 1)
 #define SLJIT_ADDC32			(SLJIT_ADDC | SLJIT_I32_OP)
-/* Flags: I | E | U | S | O | C | K */
+/* Flags: Z | LESS | GREATER_EQUAL | GREATER | LESS_EQUAL
+          SIG_LESS | SIG_GREATER_EQUAL | SIG_GREATER
+          SIG_LESS_EQUAL | CARRY */
 #define SLJIT_SUB			(SLJIT_OP2_BASE + 2)
 #define SLJIT_SUB32			(SLJIT_SUB | SLJIT_I32_OP)
-/* Flags: I | C | K */
+/* Flags: CARRY */
 #define SLJIT_SUBC			(SLJIT_OP2_BASE + 3)
 #define SLJIT_SUBC32			(SLJIT_SUBC | SLJIT_I32_OP)
 /* Note: integer mul
-   Flags: I | O (see SLJIT_C_MUL_*) | K */
+   Flags: MUL_OVERFLOW */
 #define SLJIT_MUL			(SLJIT_OP2_BASE + 4)
 #define SLJIT_MUL32			(SLJIT_MUL | SLJIT_I32_OP)
-/* Flags: I | E | K */
+/* Flags: Z */
 #define SLJIT_AND			(SLJIT_OP2_BASE + 5)
 #define SLJIT_AND32			(SLJIT_AND | SLJIT_I32_OP)
-/* Flags: I | E | K */
+/* Flags: Z */
 #define SLJIT_OR			(SLJIT_OP2_BASE + 6)
 #define SLJIT_OR32			(SLJIT_OR | SLJIT_I32_OP)
-/* Flags: I | E | K */
+/* Flags: Z */
 #define SLJIT_XOR			(SLJIT_OP2_BASE + 7)
 #define SLJIT_XOR32			(SLJIT_XOR | SLJIT_I32_OP)
-/* Flags: I | E | K
+/* Flags: Z
    Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0
    to bit_length - 1, the result is undefined. */
 #define SLJIT_SHL			(SLJIT_OP2_BASE + 8)
 #define SLJIT_SHL32			(SLJIT_SHL | SLJIT_I32_OP)
-/* Flags: I | E | K
+/* Flags: Z
    Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0
    to bit_length - 1, the result is undefined. */
 #define SLJIT_LSHR			(SLJIT_OP2_BASE + 9)
 #define SLJIT_LSHR32			(SLJIT_LSHR | SLJIT_I32_OP)
-/* Flags: I | E | K
+/* Flags: Z
    Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0
@@ -865,44 +1008,38 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w);
 
-/* Returns with non-zero if fpu is available. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void);
-
 /* Starting index of opcodes for sljit_emit_fop1. */
 #define SLJIT_FOP1_BASE			128
 
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_MOV_F64			(SLJIT_FOP1_BASE + 0)
 #define SLJIT_MOV_F32			(SLJIT_MOV_F64 | SLJIT_F32_OP)
 /* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]
    SRC/DST TYPE can be: D - double, S - single, W - signed word, I - signed int
    Rounding mode when the destination is W or I: round towards zero. */
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_CONV_F64_FROM_F32		(SLJIT_FOP1_BASE + 1)
 #define SLJIT_CONV_F32_FROM_F64		(SLJIT_CONV_F64_FROM_F32 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_CONV_SW_FROM_F64		(SLJIT_FOP1_BASE + 2)
 #define SLJIT_CONV_SW_FROM_F32		(SLJIT_CONV_SW_FROM_F64 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_CONV_S32_FROM_F64		(SLJIT_FOP1_BASE + 3)
 #define SLJIT_CONV_S32_FROM_F32		(SLJIT_CONV_S32_FROM_F64 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_CONV_F64_FROM_SW		(SLJIT_FOP1_BASE + 4)
 #define SLJIT_CONV_F32_FROM_SW		(SLJIT_CONV_F64_FROM_SW | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_CONV_F64_FROM_S32		(SLJIT_FOP1_BASE + 5)
 #define SLJIT_CONV_F32_FROM_S32		(SLJIT_CONV_F64_FROM_S32 | SLJIT_F32_OP)
 /* Note: dst is the left and src is the right operand for SLJIT_CMPD.
-   Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED flag
-         is set, the comparison result is unpredictable.
-   Flags: SP | E | S (see SLJIT_C_FLOAT_*) */
+   Flags: EQUAL_F | LESS_F | GREATER_EQUAL_F | GREATER_F | LESS_EQUAL_F */
 #define SLJIT_CMP_F64			(SLJIT_FOP1_BASE + 6)
 #define SLJIT_CMP_F32			(SLJIT_CMP_F64 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_NEG_F64			(SLJIT_FOP1_BASE + 7)
 #define SLJIT_NEG_F32			(SLJIT_NEG_F64 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_ABS_F64			(SLJIT_FOP1_BASE + 8)
 #define SLJIT_ABS_F32			(SLJIT_ABS_F64 | SLJIT_F32_OP)
 
@@ -913,16 +1050,16 @@
 /* Starting index of opcodes for sljit_emit_fop2. */
 #define SLJIT_FOP2_BASE			160
 
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_ADD_F64			(SLJIT_FOP2_BASE + 0)
 #define SLJIT_ADD_F32			(SLJIT_ADD_F64 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_SUB_F64			(SLJIT_FOP2_BASE + 1)
 #define SLJIT_SUB_F32			(SLJIT_SUB_F64 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_MUL_F64			(SLJIT_FOP2_BASE + 2)
 #define SLJIT_MUL_F32			(SLJIT_MUL_F64 | SLJIT_F32_OP)
-/* Flags: SP - (never set any flags) */
+/* Flags: - (does not modify flags) */
 #define SLJIT_DIV_F64			(SLJIT_FOP2_BASE + 3)
 #define SLJIT_DIV_F32			(SLJIT_DIV_F64 | SLJIT_F32_OP)
 
@@ -949,69 +1086,98 @@
 
 #define SLJIT_LESS			2
 #define SLJIT_LESS32			(SLJIT_LESS | SLJIT_I32_OP)
+#define SLJIT_SET_LESS			SLJIT_SET(SLJIT_LESS)
 #define SLJIT_GREATER_EQUAL		3
 #define SLJIT_GREATER_EQUAL32		(SLJIT_GREATER_EQUAL | SLJIT_I32_OP)
+#define SLJIT_SET_GREATER_EQUAL		SLJIT_SET(SLJIT_GREATER_EQUAL)
 #define SLJIT_GREATER			4
 #define SLJIT_GREATER32			(SLJIT_GREATER | SLJIT_I32_OP)
+#define SLJIT_SET_GREATER		SLJIT_SET(SLJIT_GREATER)
 #define SLJIT_LESS_EQUAL		5
 #define SLJIT_LESS_EQUAL32		(SLJIT_LESS_EQUAL | SLJIT_I32_OP)
+#define SLJIT_SET_LESS_EQUAL		SLJIT_SET(SLJIT_LESS_EQUAL)
 #define SLJIT_SIG_LESS			6
 #define SLJIT_SIG_LESS32		(SLJIT_SIG_LESS | SLJIT_I32_OP)
+#define SLJIT_SET_SIG_LESS		SLJIT_SET(SLJIT_SIG_LESS)
 #define SLJIT_SIG_GREATER_EQUAL		7
 #define SLJIT_SIG_GREATER_EQUAL32	(SLJIT_SIG_GREATER_EQUAL | SLJIT_I32_OP)
+#define SLJIT_SET_SIG_GREATER_EQUAL	SLJIT_SET(SLJIT_SIG_GREATER_EQUAL)
 #define SLJIT_SIG_GREATER		8
 #define SLJIT_SIG_GREATER32		(SLJIT_SIG_GREATER | SLJIT_I32_OP)
+#define SLJIT_SET_SIG_GREATER		SLJIT_SET(SLJIT_SIG_GREATER)
 #define SLJIT_SIG_LESS_EQUAL		9
 #define SLJIT_SIG_LESS_EQUAL32		(SLJIT_SIG_LESS_EQUAL | SLJIT_I32_OP)
+#define SLJIT_SET_SIG_LESS_EQUAL	SLJIT_SET(SLJIT_SIG_LESS_EQUAL)
 
 #define SLJIT_OVERFLOW			10
 #define SLJIT_OVERFLOW32		(SLJIT_OVERFLOW | SLJIT_I32_OP)
+#define SLJIT_SET_OVERFLOW		SLJIT_SET(SLJIT_OVERFLOW)
 #define SLJIT_NOT_OVERFLOW		11
 #define SLJIT_NOT_OVERFLOW32		(SLJIT_NOT_OVERFLOW | SLJIT_I32_OP)
 
 #define SLJIT_MUL_OVERFLOW		12
 #define SLJIT_MUL_OVERFLOW32		(SLJIT_MUL_OVERFLOW | SLJIT_I32_OP)
+#define SLJIT_SET_MUL_OVERFLOW		SLJIT_SET(SLJIT_MUL_OVERFLOW)
 #define SLJIT_MUL_NOT_OVERFLOW		13
 #define SLJIT_MUL_NOT_OVERFLOW32	(SLJIT_MUL_NOT_OVERFLOW | SLJIT_I32_OP)
 
+/* There is no SLJIT_CARRY or SLJIT_NOT_CARRY. */
+#define SLJIT_SET_CARRY			SLJIT_SET(14)
+
 /* Floating point comparison types. */
-#define SLJIT_EQUAL_F64			14
+#define SLJIT_EQUAL_F64			16
 #define SLJIT_EQUAL_F32			(SLJIT_EQUAL_F64 | SLJIT_F32_OP)
-#define SLJIT_NOT_EQUAL_F64		15
+#define SLJIT_SET_EQUAL_F		SLJIT_SET(SLJIT_EQUAL_F64)
+#define SLJIT_NOT_EQUAL_F64		17
 #define SLJIT_NOT_EQUAL_F32		(SLJIT_NOT_EQUAL_F64 | SLJIT_F32_OP)
-#define SLJIT_LESS_F64			16
+#define SLJIT_SET_NOT_EQUAL_F		SLJIT_SET(SLJIT_NOT_EQUAL_F64)
+#define SLJIT_LESS_F64			18
 #define SLJIT_LESS_F32			(SLJIT_LESS_F64 | SLJIT_F32_OP)
-#define SLJIT_GREATER_EQUAL_F64		17
+#define SLJIT_SET_LESS_F		SLJIT_SET(SLJIT_LESS_F64)
+#define SLJIT_GREATER_EQUAL_F64		19
 #define SLJIT_GREATER_EQUAL_F32		(SLJIT_GREATER_EQUAL_F64 | SLJIT_F32_OP)
-#define SLJIT_GREATER_F64		18
+#define SLJIT_SET_GREATER_EQUAL_F	SLJIT_SET(SLJIT_GREATER_EQUAL_F64)
+#define SLJIT_GREATER_F64		20
 #define SLJIT_GREATER_F32		(SLJIT_GREATER_F64 | SLJIT_F32_OP)
-#define SLJIT_LESS_EQUAL_F64		19
+#define SLJIT_SET_GREATER_F		SLJIT_SET(SLJIT_GREATER_F64)
+#define SLJIT_LESS_EQUAL_F64		21
 #define SLJIT_LESS_EQUAL_F32		(SLJIT_LESS_EQUAL_F64 | SLJIT_F32_OP)
-#define SLJIT_UNORDERED_F64		20
+#define SLJIT_SET_LESS_EQUAL_F		SLJIT_SET(SLJIT_LESS_EQUAL_F64)
+#define SLJIT_UNORDERED_F64		22
 #define SLJIT_UNORDERED_F32		(SLJIT_UNORDERED_F64 | SLJIT_F32_OP)
-#define SLJIT_ORDERED_F64		21
+#define SLJIT_SET_UNORDERED_F		SLJIT_SET(SLJIT_UNORDERED_F64)
+#define SLJIT_ORDERED_F64		23
 #define SLJIT_ORDERED_F32		(SLJIT_ORDERED_F64 | SLJIT_F32_OP)
+#define SLJIT_SET_ORDERED_F		SLJIT_SET(SLJIT_ORDERED_F64)
 
 /* Unconditional jump types. */
-#define SLJIT_JUMP			22
-#define SLJIT_FAST_CALL			23
-#define SLJIT_CALL0			24
-#define SLJIT_CALL1			25
-#define SLJIT_CALL2			26
-#define SLJIT_CALL3			27
-
-/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
+#define SLJIT_JUMP			24
+	/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
+#define SLJIT_FAST_CALL			25
+	/* Called function must be declared with the SLJIT_FUNC attribute. */
+#define SLJIT_CALL			26
+	/* Called function must be decalred with cdecl attribute.
+	   This is the default attribute for C functions. */
+#define SLJIT_CALL_CDECL		27
 
 /* The target can be changed during runtime (see: sljit_set_jump_addr). */
 #define SLJIT_REWRITABLE_JUMP		0x1000
 
 /* Emit a jump instruction. The destination is not set, only the type of the jump.
-    type must be between SLJIT_EQUAL and SLJIT_CALL3
+    type must be between SLJIT_EQUAL and SLJIT_FAST_CALL
     type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
-   Flags: - (never set any flags) for both conditional and unconditional jumps.
-   Flags: destroy all flags for calls. */
+
+   Flags: does not modify flags. */
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type);
 
+/* Emit a C compiler (ABI) compatible function call.
+    type must be SLJIT_CALL or SLJIT_CALL_CDECL
+    type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+    arg_types is the combination of SLJIT_RET / SLJIT_ARGx (SLJIT_DEF_RET / SLJIT_DEF_ARGx) macros
+
+   Flags: destroy all flags. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types);
+
 /* Basic arithmetic comparison. In most architectures it is implemented as
    an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
    appropriate flags) followed by a sljit_emit_jump. However some
@@ -1019,7 +1185,8 @@
    It is suggested to use this comparison form when appropriate.
     type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL
     type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
-   Flags: destroy flags. */
+
+   Flags: may destroy flags. */
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w);
@@ -1043,40 +1210,112 @@
 /* Set the destination address of the jump to this label. */
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
 
-/* Call function or jump anywhere. Both direct and indirect form
-    type must be between SLJIT_JUMP and SLJIT_CALL3
-    Direct form: set src to SLJIT_IMM() and srcw to the address
-    Indirect form: any other valid addressing mode
-   Flags: - (never set any flags) for unconditional jumps.
-   Flags: destroy all flags for calls. */
+/* Emit an indirect jump or fast call. Both direct and indirect form
+   Direct form: set src to SLJIT_IMM() and srcw to the address
+   Indirect form: any other valid addressing mode
+    type must be between SLJIT_JUMP and SLJIT_FAST_CALL
+
+   Flags: does not modify flags. */
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw);
 
+/* Emit a C compiler (ABI) compatible function call.
+   Direct form: set src to SLJIT_IMM() and srcw to the address
+   Indirect form: any other valid addressing mode
+    type must be SLJIT_CALL or SLJIT_CALL_CDECL
+    arg_types is the combination of SLJIT_RET / SLJIT_ARGx (SLJIT_DEF_RET / SLJIT_DEF_ARGx) macros
+
+   Flags: destroy all flags. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw);
+
 /* Perform the operation using the conditional flags as the second argument.
-   Type must always be between SLJIT_EQUAL and SLJIT_S_ORDERED. The value
+   Type must always be between SLJIT_EQUAL and SLJIT_ORDERED_F64. The value
    represented by the type is 1, if the condition represented by the type
    is fulfilled, and 0 otherwise.
 
-   If op == SLJIT_MOV, SLJIT_MOV_S32, SLJIT_MOV_U32:
+   If op == SLJIT_MOV, SLJIT_MOV32:
      Set dst to the value represented by the type (0 or 1).
-     Src must be SLJIT_UNUSED, and srcw must be 0
-     Flags: - (never set any flags)
+     Flags: - (does not modify flags)
    If op == SLJIT_OR, op == SLJIT_AND, op == SLJIT_XOR
-     Performs the binary operation using src as the first, and the value
-     represented by type as the second argument.
-     Important note: only dst=src and dstw=srcw is supported at the moment!
-     Flags: I | E | K
-   Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */
+     Performs the binary operation using dst as the first, and the value
+     represented by type as the second argument. Result is written into dst.
+     Flags: Z (may destroy flags) */
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type);
 
-/* Copies the base address of SLJIT_SP + offset to dst.
-   Flags: - (never set any flags) */
+/* Emit a conditional mov instruction which moves source to destination,
+   if the condition is satisfied. Unlike other arithmetic operations this
+   instruction does not support memory access.
+
+   type must be between SLJIT_EQUAL and SLJIT_ORDERED_F64
+   dst_reg must be a valid register and it can be combined
+      with SLJIT_I32_OP to perform a 32 bit arithmetic operation
+   src must be register or immediate (SLJIT_IMM)
+
+   Flags: - (does not modify flags) */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw);
+
+/* The following flags are used by sljit_emit_mem() and sljit_emit_fmem(). */
+
+/* When SLJIT_MEM_SUPP is passed, no instructions are emitted.
+   Instead the function returns with SLJIT_SUCCESS if the instruction
+   form is supported and SLJIT_ERR_UNSUPPORTED otherwise. This flag
+   allows runtime checking of available instruction forms. */
+#define SLJIT_MEM_SUPP		0x0200
+/* Memory load operation. This is the default. */
+#define SLJIT_MEM_LOAD		0x0000
+/* Memory store operation. */
+#define SLJIT_MEM_STORE		0x0400
+/* Base register is updated before the memory access. */
+#define SLJIT_MEM_PRE		0x0800
+/* Base register is updated after the memory access. */
+#define SLJIT_MEM_POST		0x1000
+
+/* Emit a single memory load or store with update instruction. When the
+   requested instruction from is not supported by the CPU, it returns
+   with SLJIT_ERR_UNSUPPORTED instead of emulating the instruction. This
+   allows specializing tight loops based on the supported instruction
+   forms (see SLJIT_MEM_SUPP flag).
+
+   type must be between SLJIT_MOV and SLJIT_MOV_P and can be
+     combined with SLJIT_MEM_* flags. Either SLJIT_MEM_PRE
+     or SLJIT_MEM_POST must be specified.
+   reg is the source or destination register, and must be
+     different from the base register of the mem operand
+   mem must be a SLJIT_MEM1() or SLJIT_MEM2() operand
+
+   Flags: - (does not modify flags) */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 reg,
+	sljit_s32 mem, sljit_sw memw);
+
+/* Same as sljit_emit_mem except the followings:
+
+   type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be
+     combined with SLJIT_MEM_* flags. Either SLJIT_MEM_PRE
+     or SLJIT_MEM_POST must be specified.
+   freg is the source or destination floating point register */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 freg,
+	sljit_s32 mem, sljit_sw memw);
+
+/* Copies the base address of SLJIT_SP + offset to dst. The offset can be
+   anything to negate the effect of relative addressing. For example if an
+   array of sljit_sw values is stored on the stack from offset 0x40, and R0
+   contains the offset of an array item plus 0x120, this item can be
+   overwritten by two SLJIT instructions:
+
+   sljit_get_local_base(compiler, SLJIT_R1, 0, 0x40 - 0x120);
+   sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM2(SLJIT_R1, SLJIT_R0), 0, SLJIT_IMM, 0x5);
+
+   Flags: - (may destroy flags) */
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
 
 /* The constant can be changed runtime (see: sljit_set_const)
-   Flags: - (never set any flags) */
+   Flags: - (does not modify flags) */
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
 
 /* After the code generation the address for label, jump and const instructions
@@ -1086,16 +1325,17 @@
 static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
 static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
 
-/* Only the address is required to rewrite the code. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant);
+/* Only the address and executable offset are required to perform dynamic
+   code modifications. See sljit_get_executable_offset function. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset);
 
 /* --------------------------------------------------------------------- */
 /*  Miscellaneous utility functions                                      */
 /* --------------------------------------------------------------------- */
 
 #define SLJIT_MAJOR_VERSION	0
-#define SLJIT_MINOR_VERSION	93
+#define SLJIT_MINOR_VERSION	94
 
 /* Get the human readable name of the platform. Can be useful on platforms
    like ARM, where ARM and Thumb2 functions can be mixed, and
@@ -1107,53 +1347,58 @@
 
 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
 /* This global lock is useful to compile common functions. */
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void);
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void);
 #endif
 
 #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
 
-/* The sljit_stack is a utiliy feature of sljit, which allocates a
-   writable memory region between base (inclusive) and limit (exclusive).
-   Both base and limit is a pointer, and base is always <= than limit.
-   This feature uses the "address space reserve" feature
-   of modern operating systems. Basically we don't need to allocate a
-   huge memory block in one step for the worst case, we can start with
-   a smaller chunk and extend it later. Since the address space is
-   reserved, the data never copied to other regions, thus it is safe
-   to store pointers here. */
+/* The sljit_stack structure and its manipulation functions provides
+   an implementation for a top-down stack. The stack top is stored
+   in the end field of the sljit_stack structure and the stack goes
+   down to the min_start field, so the memory region reserved for
+   this stack is between min_start (inclusive) and end (exclusive)
+   fields. However the application can only use the region between
+   start (inclusive) and end (exclusive) fields. The sljit_stack_resize
+   function can be used to extend this region up to min_start.
 
-/* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more).
-   Note: stack growing should not happen in small steps: 4k, 16k or even
-     bigger growth is better.
-   Note: this structure may not be supported by all operating systems.
-     Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK
-     is not defined. */
+   This feature uses the "address space reserve" feature of modern
+   operating systems. Instead of allocating a large memory block
+   applications can allocate a small memory region and extend it
+   later without moving the content of the memory area. Therefore
+   after a successful resize by sljit_stack_resize all pointers into
+   this region are still valid.
+
+   Note:
+     this structure may not be supported by all operating systems.
+     end and max_limit fields are aligned to PAGE_SIZE bytes (usually
+         4 Kbyte or more).
+     stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more. */
 
 struct sljit_stack {
 	/* User data, anything can be stored here.
-	   Starting with the same value as base. */
-	sljit_uw top;
-	/* These members are read only. */
-	sljit_uw base;
-	sljit_uw limit;
-	sljit_uw max_limit;
+	   Initialized to the same value as the end field. */
+	sljit_u8 *top;
+/* These members are read only. */
+	/* End address of the stack */
+	sljit_u8 *end;
+	/* Current start address of the stack. */
+	sljit_u8 *start;
+	/* Lowest start address of the stack. */
+	sljit_u8 *min_start;
 };
 
-/* Returns NULL if unsuccessful.
-   Note: limit and max_limit contains the size for stack allocation.
-   Note: the top field is initialized to base.
+/* Allocates a new stack. Returns NULL if unsuccessful.
    Note: see sljit_create_compiler for the explanation of allocator_data. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data);
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
 
-/* Can be used to increase (allocate) or decrease (free) the memory area.
-   Returns with a non-zero value if unsuccessful. If new_limit is greater than
-   max_limit, it will fail. It is very easy to implement a stack data structure,
-   since the growth ratio can be added to the current limit, and sljit_stack_resize
-   will do all the necessary checks. The fields of the stack are not changed if
-   sljit_stack_resize fails. */
-SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack *stack, sljit_uw new_limit);
+/* Can be used to increase (extend) or decrease (shrink) the stack
+   memory area. Returns with new_start if successful and NULL otherwise.
+   It always fails if new_start is less than min_start or greater or equal
+   than end fields. The fields of the stack are not changed if the returned
+   value is NULL (the current memory content is never lost). */
+SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start);
 
 #endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
 
@@ -1182,6 +1427,15 @@
 
 #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
 
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+/* Free unused executable memory. The allocator keeps some free memory
+   around to reduce the number of OS executable memory allocations.
+   This improves performance since these calls are costly. However
+   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
+
 /* --------------------------------------------------------------------- */
 /*  CPU specific functions                                               */
 /* --------------------------------------------------------------------- */
@@ -1214,32 +1468,10 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
 	void *instruction, sljit_s32 size);
 
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+/* Define the currently available CPU status flags. It is usually used after an
+   sljit_emit_op_custom call to define which flags are set. */
 
-/* Returns with non-zero if sse2 is available. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void);
-
-/* Returns with non-zero if cmov instruction is available. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void);
-
-/* Emit a conditional mov instruction on x86 CPUs. This instruction
-   moves src to destination, if the condition is satisfied. Unlike
-   other arithmetic instructions, destination must be a register.
-   Before such instructions are emitted, cmov support should be
-   checked by sljit_x86_is_cmov_available function.
-    type must be between SLJIT_EQUAL and SLJIT_S_ORDERED
-    dst_reg must be a valid register and it can be combined
-      with SLJIT_I32_OP to perform 32 bit arithmetic
-   Flags: I - (never set any flags)
- */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler,
-	sljit_s32 type,
-	sljit_s32 dst_reg,
-	sljit_s32 src, sljit_sw srcw);
-
-#endif
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,
+	sljit_s32 current_flags);
 
 #endif /* _SLJIT_LIR_H_ */
diff --git a/dist2/src/sljit/sljitNativeARM_32.c b/dist2/src/sljit/sljitNativeARM_32.c
index b92808f..6d61eed 100644
--- a/dist2/src/sljit/sljitNativeARM_32.c
+++ b/dist2/src/sljit/sljitNativeARM_32.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -24,12 +24,18 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifdef __SOFTFP__
+#define ARM_ABI_INFO " ABI:softfp"
+#else
+#define ARM_ABI_INFO " ABI:hardfp"
+#endif
+
 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
 {
 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
-	return "ARMv7" SLJIT_CPUINFO;
+	return "ARMv7" SLJIT_CPUINFO ARM_ABI_INFO;
 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-	return "ARMv5" SLJIT_CPUINFO;
+	return "ARMv5" SLJIT_CPUINFO ARM_ABI_INFO;
 #else
 #error "Internal error: Unknown ARM architecture"
 #endif
@@ -38,11 +44,10 @@
 /* Last register + 1. */
 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
-#define TMP_PC		(SLJIT_NUMBER_OF_REGISTERS + 5)
+#define TMP_PC		(SLJIT_NUMBER_OF_REGISTERS + 4)
 
-#define TMP_FREG1	(0)
-#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
 
 /* In ARM instruction words.
    Cache lines are usually 32 byte aligned. */
@@ -55,8 +60,12 @@
 	(((max_diff) / (sljit_s32)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
 
 /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
-	0, 0, 1, 2, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 12, 14, 15
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
+	0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15
+};
+
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
+	0, 0, 1, 2, 3, 4, 5, 6, 7
 };
 
 #define RM(rm) (reg_map[rm])
@@ -73,31 +82,31 @@
 #define CONDITIONAL	0xe0000000
 #define PUSH_POOL	0xff000000
 
-/* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */
-#define ADC_DP		0x5
-#define ADD_DP		0x4
-#define AND_DP		0x0
+#define ADC		0xe0a00000
+#define ADD		0xe0800000
+#define AND		0xe0000000
 #define B		0xea000000
-#define BIC_DP		0xe
+#define BIC		0xe1c00000
 #define BL		0xeb000000
 #define BLX		0xe12fff30
 #define BX		0xe12fff10
 #define CLZ		0xe16f0f10
-#define CMP_DP		0xa
+#define CMN		0xe1600000
+#define CMP		0xe1400000
 #define BKPT		0xe1200070
-#define EOR_DP		0x1
-#define MOV_DP		0xd
+#define EOR		0xe0200000
+#define MOV		0xe1a00000
 #define MUL		0xe0000090
-#define MVN_DP		0xf
+#define MVN		0xe1e00000
 #define NOP		0xe1a00000
-#define ORR_DP		0xc
+#define ORR		0xe1800000
 #define PUSH		0xe92d0000
 #define POP		0xe8bd0000
-#define RSB_DP		0x3
-#define RSC_DP		0x7
-#define SBC_DP		0x6
+#define RSB		0xe0600000
+#define RSC		0xe0e00000
+#define SBC		0xe0c00000
 #define SMULL		0xe0c00090
-#define SUB_DP		0x2
+#define SUB		0xe0400000
 #define UMULL		0xe0800090
 #define VABS_F32	0xeeb00ac0
 #define VADD_F32	0xee300a00
@@ -108,6 +117,7 @@
 #define VDIV_F32	0xee800a00
 #define VMOV_F32	0xeeb00a40
 #define VMOV		0xee000a10
+#define VMOV2		0xec400a10
 #define VMRS		0xeef1fa10
 #define VMUL_F32	0xee200a00
 #define VNEG_F32	0xeeb10a40
@@ -260,6 +270,8 @@
 {
 	/* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */
 	SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));
+	SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
+
 	return push_inst(compiler, BLX | RM(TMP_REG1));
 }
 
@@ -389,7 +401,7 @@
 
 #endif
 
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code)
+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;
 
@@ -401,7 +413,7 @@
 		code_ptr--;
 
 	if (jump->flags & JUMP_ADDR)
-		diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2));
+		diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset);
 	else {
 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
 		diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2));
@@ -426,7 +438,7 @@
 	}
 #else
 	if (jump->flags & JUMP_ADDR)
-		diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr);
+		diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset);
 	else {
 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
 		diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr);
@@ -446,26 +458,28 @@
 	return 0;
 }
 
-static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_s32 flush)
+static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache)
 {
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-	sljit_uw *ptr = (sljit_uw*)addr;
-	sljit_uw *inst = (sljit_uw*)ptr[0];
+	sljit_uw *ptr = (sljit_uw *)jump_ptr;
+	sljit_uw *inst = (sljit_uw *)ptr[0];
 	sljit_uw mov_pc = ptr[1];
 	sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
-	sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2);
+	sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);
 
 	if (diff <= 0x7fffff && diff >= -0x800000) {
 		/* Turn to branch. */
 		if (!bl) {
 			inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
-			if (flush) {
+			if (flush_cache) {
+				inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 				SLJIT_CACHE_FLUSH(inst, inst + 1);
 			}
 		} else {
 			inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
 			inst[1] = NOP;
-			if (flush) {
+			if (flush_cache) {
+				inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 				SLJIT_CACHE_FLUSH(inst, inst + 2);
 			}
 		}
@@ -479,12 +493,14 @@
 		if (*inst != mov_pc) {
 			inst[0] = mov_pc;
 			if (!bl) {
-				if (flush) {
+				if (flush_cache) {
+					inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 					SLJIT_CACHE_FLUSH(inst, inst + 1);
 				}
 			} else {
 				inst[1] = BLX | RM(TMP_REG1);
-				if (flush) {
+				if (flush_cache) {
+					inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 					SLJIT_CACHE_FLUSH(inst, inst + 2);
 				}
 			}
@@ -492,11 +508,12 @@
 		*ptr = new_addr;
 	}
 #else
-	sljit_uw *inst = (sljit_uw*)addr;
+	sljit_uw *inst = (sljit_uw*)jump_ptr;
 	SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
 	inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
 	inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
-	if (flush) {
+	if (flush_cache) {
+		inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 		SLJIT_CACHE_FLUSH(inst, inst + 2);
 	}
 #endif
@@ -504,7 +521,7 @@
 
 static sljit_uw get_imm(sljit_uw imm);
 
-static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_s32 flush)
+static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_sw new_constant, sljit_s32 flush_cache)
 {
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
 	sljit_uw *ptr = (sljit_uw*)addr;
@@ -515,7 +532,8 @@
 	src2 = get_imm(new_constant);
 	if (src2) {
 		*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
-		if (flush) {
+		if (flush_cache) {
+			inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 			SLJIT_CACHE_FLUSH(inst, inst + 1);
 		}
 		return;
@@ -524,7 +542,8 @@
 	src2 = get_imm(~new_constant);
 	if (src2) {
 		*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
-		if (flush) {
+		if (flush_cache) {
+			inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 			SLJIT_CACHE_FLUSH(inst, inst + 1);
 		}
 		return;
@@ -537,7 +556,8 @@
 
 	if (*inst != ldr_literal) {
 		*inst = ldr_literal;
-		if (flush) {
+		if (flush_cache) {
+			inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 			SLJIT_CACHE_FLUSH(inst, inst + 1);
 		}
 	}
@@ -547,7 +567,8 @@
 	SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
 	inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
 	inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
-	if (flush) {
+	if (flush_cache) {
+		inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 		SLJIT_CACHE_FLUSH(inst, inst + 2);
 	}
 #endif
@@ -562,6 +583,8 @@
 	sljit_uw *buf_end;
 	sljit_uw size;
 	sljit_uw word_count;
+	sljit_sw executable_offset;
+	sljit_sw jump_addr;
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
 	sljit_uw cpool_size;
 	sljit_uw cpool_skip_alignment;
@@ -602,14 +625,14 @@
 
 	code_ptr = code;
 	word_count = 0;
+	executable_offset = SLJIT_EXEC_OFFSET(code);
 
 	label = compiler->labels;
 	jump = compiler->jumps;
 	const_ = compiler->consts;
 
 	if (label && label->size == 0) {
-		label->addr = (sljit_uw)code;
-		label->size = 0;
+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
 		label = label->next;
 	}
 
@@ -636,7 +659,7 @@
 						cpool_size = 0;
 						if (label && label->size == word_count) {
 							/* Points after the current instruction. */
-							label->addr = (sljit_uw)code_ptr;
+							label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 							label->size = code_ptr - code;
 							label = label->next;
 						}
@@ -652,19 +675,19 @@
 				SLJIT_ASSERT(!const_ || const_->addr >= word_count);
 				if (jump && jump->addr == word_count) {
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-					if (detect_jump_type(jump, code_ptr, code))
+					if (detect_jump_type(jump, code_ptr, code, executable_offset))
 						code_ptr--;
 					jump->addr = (sljit_uw)code_ptr;
 #else
 					jump->addr = (sljit_uw)(code_ptr - 2);
-					if (detect_jump_type(jump, code_ptr, code))
+					if (detect_jump_type(jump, code_ptr, code, executable_offset))
 						code_ptr -= 2;
 #endif
 					jump = jump->next;
 				}
 				if (label && label->size == word_count) {
 					/* code_ptr can be affected above. */
-					label->addr = (sljit_uw)(code_ptr + 1);
+					label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);
 					label->size = (code_ptr + 1) - code;
 					label = label->next;
 				}
@@ -729,17 +752,18 @@
 
 	jump = compiler->jumps;
 	while (jump) {
-		buf_ptr = (sljit_uw*)jump->addr;
+		buf_ptr = (sljit_uw *)jump->addr;
 
 		if (jump->flags & PATCH_B) {
+			jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
 			if (!(jump->flags & JUMP_ADDR)) {
 				SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-				SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000);
-				*buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff;
+				SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000);
+				*buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff;
 			}
 			else {
-				SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000);
-				*buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff;
+				SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000);
+				*buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff;
 			}
 		}
 		else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
@@ -747,10 +771,10 @@
 			jump->addr = (sljit_uw)code_ptr;
 			code_ptr[0] = (sljit_uw)buf_ptr;
 			code_ptr[1] = *buf_ptr;
-			inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+			inline_set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
 			code_ptr += 2;
 #else
-			inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+			inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
 #endif
 		}
 		else {
@@ -763,7 +787,7 @@
 				buf_ptr += 1;
 			*buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
 #else
-			inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+			inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
 #endif
 		}
 		jump = jump->next;
@@ -782,7 +806,7 @@
 		else
 			buf_ptr += 1;
 		/* Set the value again (can be a simple constant). */
-		inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0);
+		inline_set_const((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
 		code_ptr += 2;
 
 		const_ = const_->next;
@@ -792,33 +816,87 @@
 	SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
 
 	compiler->error = SLJIT_ERR_COMPILED;
+	compiler->executable_offset = executable_offset;
 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw);
+
+	code = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+	code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
 	SLJIT_CACHE_FLUSH(code, code_ptr);
 	return code;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	switch (feature_type) {
+	case SLJIT_HAS_FPU:
+#ifdef SLJIT_IS_FPU_AVAILABLE
+		return SLJIT_IS_FPU_AVAILABLE;
+#else
+		/* Available by default. */
+		return 1;
+#endif
+
+	case SLJIT_HAS_CLZ:
+	case SLJIT_HAS_CMOV:
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
 /* --------------------------------------------------------------------- */
 /*  Entry, exit                                                          */
 /* --------------------------------------------------------------------- */
 
-/* emit_op inp_flags.
-   WRITE_BACK must be the first, since it is a flag. */
-#define WRITE_BACK	0x01
-#define ALLOW_IMM	0x02
-#define ALLOW_INV_IMM	0x04
-#define ALLOW_ANY_IMM	(ALLOW_IMM | ALLOW_INV_IMM)
-#define ARG_TEST	0x08
-
 /* Creates an index in data_transfer_insts array. */
-#define WORD_DATA	0x00
-#define BYTE_DATA	0x10
-#define HALF_DATA	0x20
-#define SIGNED_DATA	0x40
-#define LOAD_DATA	0x80
+#define WORD_SIZE	0x00
+#define BYTE_SIZE	0x01
+#define HALF_SIZE	0x02
+#define PRELOAD		0x03
+#define SIGNED		0x04
+#define LOAD_DATA	0x08
 
-/* Condition: AL. */
-#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \
-	(0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2))
+/* Flag bits for emit_op. */
+#define ALLOW_IMM	0x10
+#define ALLOW_INV_IMM	0x20
+#define ALLOW_ANY_IMM	(ALLOW_IMM | ALLOW_INV_IMM)
+
+/* s/l - store/load (1 bit)
+   u/s - signed/unsigned (1 bit)
+   w/b/h/N - word/byte/half/NOT allowed (2 bit)
+   Storing signed and unsigned values are the same operations. */
+
+static const sljit_uw data_transfer_insts[16] = {
+/* s u w */ 0xe5000000 /* str */,
+/* s u b */ 0xe5400000 /* strb */,
+/* s u h */ 0xe10000b0 /* strh */,
+/* s u N */ 0x00000000 /* not allowed */,
+/* s s w */ 0xe5000000 /* str */,
+/* s s b */ 0xe5400000 /* strb */,
+/* s s h */ 0xe10000b0 /* strh */,
+/* s s N */ 0x00000000 /* not allowed */,
+
+/* l u w */ 0xe5100000 /* ldr */,
+/* l u b */ 0xe5500000 /* ldrb */,
+/* l u h */ 0xe11000b0 /* ldrh */,
+/* l u p */ 0xf5500000 /* preload */,
+/* l s w */ 0xe5100000 /* ldr */,
+/* l s b */ 0xe11000d0 /* ldrsb */,
+/* l s h */ 0xe11000f0 /* ldrsh */,
+/* l s N */ 0x00000000 /* not allowed */,
+};
+
+#define EMIT_DATA_TRANSFER(type, add, target_reg, base_reg, arg) \
+	(data_transfer_insts[(type) & 0xf] | ((add) << 23) | RD(target_reg) | RN(base_reg) | (arg))
+
+/* Normal ldr/str instruction.
+   Type2: ldrsb, ldrh, ldrsh */
+#define IS_TYPE1_TRANSFER(type) \
+	(data_transfer_insts[(type) & 0xf] & 0x04000000)
+#define TYPE2_TRANSFER_IMM(imm) \
+	(((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22))
 
 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,
 	sljit_s32 dst, sljit_sw dstw,
@@ -826,15 +904,15 @@
 	sljit_s32 src2, sljit_sw src2w);
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 size, i, tmp;
+	sljit_s32 args, size, i, tmp;
 	sljit_uw push;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	/* Push saved registers, temporary registers
 	   stmdb sp!, {..., lr} */
@@ -856,25 +934,27 @@
 	if (local_size > 0)
 		FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size));
 
+	args = get_arg_count(arg_types);
+
 	if (args >= 1)
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S0, SLJIT_UNUSED, RM(SLJIT_R0))));
+		FAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S0) | RM(SLJIT_R0)));
 	if (args >= 2)
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S1, SLJIT_UNUSED, RM(SLJIT_R1))));
+		FAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S1) | RM(SLJIT_R1)));
 	if (args >= 3)
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_S2, SLJIT_UNUSED, RM(SLJIT_R2))));
+		FAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S2) | RM(SLJIT_R2)));
 
 	return SLJIT_SUCCESS;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 size;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
 	compiler->local_size = ((size + local_size + 7) & ~7) - size;
@@ -912,52 +992,15 @@
 /*  Operators                                                            */
 /* --------------------------------------------------------------------- */
 
-/* s/l - store/load (1 bit)
-   u/s - signed/unsigned (1 bit)
-   w/b/h/N - word/byte/half/NOT allowed (2 bit)
-   It contans 16 items, but not all are different. */
-
-static sljit_sw data_transfer_insts[16] = {
-/* s u w */ 0xe5000000 /* str */,
-/* s u b */ 0xe5400000 /* strb */,
-/* s u h */ 0xe10000b0 /* strh */,
-/* s u N */ 0x00000000 /* not allowed */,
-/* s s w */ 0xe5000000 /* str */,
-/* s s b */ 0xe5400000 /* strb */,
-/* s s h */ 0xe10000b0 /* strh */,
-/* s s N */ 0x00000000 /* not allowed */,
-
-/* l u w */ 0xe5100000 /* ldr */,
-/* l u b */ 0xe5500000 /* ldrb */,
-/* l u h */ 0xe11000b0 /* ldrh */,
-/* l u N */ 0x00000000 /* not allowed */,
-/* l s w */ 0xe5100000 /* ldr */,
-/* l s b */ 0xe11000d0 /* ldrsb */,
-/* l s h */ 0xe11000f0 /* ldrsh */,
-/* l s N */ 0x00000000 /* not allowed */,
-};
-
-#define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \
-	(data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2))
-/* Normal ldr/str instruction.
-   Type2: ldrsb, ldrh, ldrsh */
-#define IS_TYPE1_TRANSFER(type) \
-	(data_transfer_insts[(type) >> 4] & 0x04000000)
-#define TYPE2_TRANSFER_IMM(imm) \
-	(((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22))
-
 /* flags: */
   /* Arguments are swapped. */
 #define ARGS_SWAPPED	0x01
   /* Inverted immediate. */
 #define INV_IMM		0x02
   /* Source and destination is register. */
-#define REG_DEST	0x04
-#define REG_SOURCE	0x08
-  /* One instruction is enough. */
-#define FAST_DEST	0x10
-  /* Multiple instructions are required. */
-#define SLOW_DEST	0x20
+#define MOVE_REG_CONV	0x04
+  /* Unused return value. */
+#define UNUSED_RETURN	0x08
 /* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */
 #define SET_FLAGS	(1 << 20)
 /* dst: reg
@@ -966,157 +1009,127 @@
    SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */
 #define SRC2_IMM	(1 << 25)
 
-#define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \
-	return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2)))
-
-#define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \
-	return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2))
-
 #define EMIT_SHIFT_INS_AND_RETURN(opcode) \
 	SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \
 	if (compiler->shift_imm != 0x20) { \
 		SLJIT_ASSERT(src1 == TMP_REG1); \
 		SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \
+		\
 		if (compiler->shift_imm != 0) \
-			return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \
-		return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \
+			return push_inst(compiler, MOV | (flags & SET_FLAGS) | \
+				RD(dst) | (compiler->shift_imm << 7) | (opcode << 5) | RM(src2)); \
+		return push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst) | RM(src2)); \
 	} \
-	return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));
+	return push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst) | \
+		(reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | RM((flags & ARGS_SWAPPED) ? src2 : src1));
 
 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
 	sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
 {
-	sljit_sw mul_inst;
-
 	switch (GET_OPCODE(op)) {
 	case SLJIT_MOV:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
 		if (dst != src2) {
 			if (src2 & SRC2_IMM) {
-				if (flags & INV_IMM)
-					EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
-				EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+				return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);
 			}
-			EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]);
+			return push_inst(compiler, MOV | RD(dst) | RM(src2));
 		}
 		return SLJIT_SUCCESS;
 
 	case SLJIT_MOV_U8:
 	case SLJIT_MOV_S8:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
-		if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+		if (flags & MOVE_REG_CONV) {
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
 			if (op == SLJIT_MOV_U8)
-				return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff));
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2])));
-			return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | reg_map[dst]));
+				return push_inst(compiler, AND | RD(dst) | RN(src2) | SRC2_IMM | 0xff);
+			FAIL_IF(push_inst(compiler, MOV | RD(dst) | (24 << 7) | RM(src2)));
+			return push_inst(compiler, MOV | RD(dst) | (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | RM(dst));
 #else
 			return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2));
 #endif
 		}
 		else if (dst != src2) {
 			SLJIT_ASSERT(src2 & SRC2_IMM);
-			if (flags & INV_IMM)
-				EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
-			EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+			return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);
 		}
 		return SLJIT_SUCCESS;
 
 	case SLJIT_MOV_U16:
 	case SLJIT_MOV_S16:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
-		if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+		if (flags & MOVE_REG_CONV) {
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2])));
-			return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | reg_map[dst]));
+			FAIL_IF(push_inst(compiler, MOV | RD(dst) | (16 << 7) | RM(src2)));
+			return push_inst(compiler, MOV | RD(dst) | (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | RM(dst));
 #else
 			return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2));
 #endif
 		}
 		else if (dst != src2) {
 			SLJIT_ASSERT(src2 & SRC2_IMM);
-			if (flags & INV_IMM)
-				EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
-			EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+			return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2);
 		}
 		return SLJIT_SUCCESS;
 
 	case SLJIT_NOT:
 		if (src2 & SRC2_IMM) {
-			if (flags & INV_IMM)
-				EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
-			EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+			return push_inst(compiler, ((flags & INV_IMM) ? MOV : MVN) | (flags & SET_FLAGS) | RD(dst) | src2);
 		}
-		EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2));
+		return push_inst(compiler, MVN | (flags & SET_FLAGS) | RD(dst) | RM(src2));
 
 	case SLJIT_CLZ:
 		SLJIT_ASSERT(!(flags & INV_IMM));
 		SLJIT_ASSERT(!(src2 & SRC2_IMM));
 		FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2)));
-		if (flags & SET_FLAGS)
-			EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM);
 		return SLJIT_SUCCESS;
 
 	case SLJIT_ADD:
 		SLJIT_ASSERT(!(flags & INV_IMM));
-		EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP);
+		if ((flags & (UNUSED_RETURN | SET_FLAGS)) == (UNUSED_RETURN | SET_FLAGS) && !(flags & ARGS_SWAPPED))
+			return push_inst(compiler, CMN | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
+		return push_inst(compiler, ADD | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
 
 	case SLJIT_ADDC:
 		SLJIT_ASSERT(!(flags & INV_IMM));
-		EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP);
+		return push_inst(compiler, ADC | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
 
 	case SLJIT_SUB:
 		SLJIT_ASSERT(!(flags & INV_IMM));
-		if (!(flags & ARGS_SWAPPED))
-			EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP);
-		EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP);
+		if ((flags & (UNUSED_RETURN | SET_FLAGS)) == (UNUSED_RETURN | SET_FLAGS) && !(flags & ARGS_SWAPPED))
+			return push_inst(compiler, CMP | SET_FLAGS | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
+		return push_inst(compiler, (!(flags & ARGS_SWAPPED) ? SUB : RSB) | (flags & SET_FLAGS)
+			| RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
 
 	case SLJIT_SUBC:
 		SLJIT_ASSERT(!(flags & INV_IMM));
-		if (!(flags & ARGS_SWAPPED))
-			EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP);
-		EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP);
+		return push_inst(compiler, (!(flags & ARGS_SWAPPED) ? SBC : RSC) | (flags & SET_FLAGS)
+			| RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
 
 	case SLJIT_MUL:
 		SLJIT_ASSERT(!(flags & INV_IMM));
 		SLJIT_ASSERT(!(src2 & SRC2_IMM));
-		if (SLJIT_UNLIKELY(op & SLJIT_SET_O))
-			mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12);
-		else
-			mul_inst = MUL | (reg_map[dst] << 16);
 
-		if (dst != src2)
-			FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2]));
-		else if (dst != src1)
-			FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1]));
-		else {
-			/* Rm and Rd must not be the same register. */
-			SLJIT_ASSERT(dst != TMP_REG1);
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2])));
-			FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1]));
-		}
+		if (!HAS_FLAGS(op))
+			return push_inst(compiler, MUL | (reg_map[dst] << 16) | (reg_map[src2] << 8) | reg_map[src1]);
 
-		if (!(op & SLJIT_SET_O))
-			return SLJIT_SUCCESS;
+		FAIL_IF(push_inst(compiler, SMULL | (reg_map[TMP_REG1] << 16) | (reg_map[dst] << 12) | (reg_map[src2] << 8) | reg_map[src1]));
 
-		/* We need to use TMP_REG3. */
-		compiler->cache_arg = 0;
-		compiler->cache_argw = 0;
-		/* cmp TMP_REG2, dst asr #31. */
-		return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0));
+		/* cmp TMP_REG1, dst asr #31. */
+		return push_inst(compiler, CMP | SET_FLAGS | RN(TMP_REG1) | RM(dst) | 0xfc0);
 
 	case SLJIT_AND:
-		if (!(flags & INV_IMM))
-			EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP);
-		EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP);
+		return push_inst(compiler, (!(flags & INV_IMM) ? AND : BIC) | (flags & SET_FLAGS)
+			| RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
 
 	case SLJIT_OR:
 		SLJIT_ASSERT(!(flags & INV_IMM));
-		EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP);
+		return push_inst(compiler, ORR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
 
 	case SLJIT_XOR:
 		SLJIT_ASSERT(!(flags & INV_IMM));
-		EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP);
+		return push_inst(compiler, EOR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2)));
 
 	case SLJIT_SHL:
 		EMIT_SHIFT_INS_AND_RETURN(0);
@@ -1127,12 +1140,11 @@
 	case SLJIT_ASHR:
 		EMIT_SHIFT_INS_AND_RETURN(2);
 	}
-	SLJIT_ASSERT_STOP();
+
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 }
 
-#undef EMIT_DATA_PROCESS_INS_AND_RETURN
-#undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN
 #undef EMIT_SHIFT_INS_AND_RETURN
 
 /* Tests whether the immediate can be stored in the 12 bit imm field.
@@ -1280,8 +1292,8 @@
 			return 0;
 	}
 
-	FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1)));
-	FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2)));
+	FAIL_IF(push_inst(compiler, (positive ? MOV : MVN) | RD(reg) | imm1));
+	FAIL_IF(push_inst(compiler, (positive ? ORR : BIC) | RD(reg) | RN(reg) | imm2));
 	return 1;
 }
 #endif
@@ -1298,11 +1310,11 @@
 	/* Create imm by 1 inst. */
 	tmp = get_imm(imm);
 	if (tmp)
-		return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));
+		return push_inst(compiler, MOV | RD(reg) | tmp);
 
 	tmp = get_imm(~imm);
 	if (tmp)
-		return push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));
+		return push_inst(compiler, MVN | RD(reg) | tmp);
 
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
 	/* Create imm by 2 inst. */
@@ -1310,293 +1322,109 @@
 	FAIL_IF(generate_int(compiler, reg, ~imm, 0));
 
 	/* Load integer. */
-	return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm);
+	return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), imm);
 #else
-	return emit_imm(compiler, reg, imm);
+	FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));
+	if (imm <= 0xffff)
+		return SLJIT_SUCCESS;
+	return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));
 #endif
 }
 
-/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
-static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
+	sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
 {
-	if (value >= 0) {
-		value = get_imm(value);
-		if (value)
-			return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value));
-	}
-	else {
-		value = get_imm(-value);
-		if (value)
-			return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value));
-	}
-	return SLJIT_ERR_UNSUPPORTED;
-}
+	sljit_uw imm, offset_reg;
+	sljit_uw is_type1_transfer = IS_TYPE1_TRANSFER(flags);
 
-/* Can perform an operation using at most 1 instruction. */
-static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
-	sljit_uw imm;
-
-	if (arg & SLJIT_IMM) {
-		imm = get_imm(argw);
-		if (imm) {
-			if (inp_flags & ARG_TEST)
-				return 1;
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm)));
-			return -1;
-		}
-		imm = get_imm(~argw);
-		if (imm) {
-			if (inp_flags & ARG_TEST)
-				return 1;
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm)));
-			return -1;
-		}
-		return 0;
-	}
-
-	SLJIT_ASSERT(arg & SLJIT_MEM);
-
-	/* Fast loads/stores. */
-	if (!(arg & REG_MASK))
-		return 0;
-
-	if (arg & OFFS_REG_MASK) {
-		if ((argw & 0x3) != 0 && !IS_TYPE1_TRANSFER(inp_flags))
-			return 0;
-
-		if (inp_flags & ARG_TEST)
-			return 1;
-		FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK,
-			RM(OFFS_REG(arg)) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7))));
-		return -1;
-	}
-
-	if (IS_TYPE1_TRANSFER(inp_flags)) {
-		if (argw >= 0 && argw <= 0xfff) {
-			if (inp_flags & ARG_TEST)
-				return 1;
-			FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, argw)));
-			return -1;
-		}
-		if (argw < 0 && argw >= -0xfff) {
-			if (inp_flags & ARG_TEST)
-				return 1;
-			FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, -argw)));
-			return -1;
-		}
-	}
-	else {
-		if (argw >= 0 && argw <= 0xff) {
-			if (inp_flags & ARG_TEST)
-				return 1;
-			FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw))));
-			return -1;
-		}
-		if (argw < 0 && argw >= -0xff) {
-			if (inp_flags & ARG_TEST)
-				return 1;
-			argw = -argw;
-			FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & REG_MASK, TYPE2_TRANSFER_IMM(argw))));
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-/* See getput_arg below.
-   Note: can_cache is called only for binary operators. Those
-   operators always uses word arguments without write back. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	/* Immediate caching is not supported as it would be an operation on constant arguments. */
-	if (arg & SLJIT_IMM)
-		return 0;
-
-	/* Always a simple operation. */
-	if (arg & OFFS_REG_MASK)
-		return 0;
-
-	if (!(arg & REG_MASK)) {
-		/* Immediate access. */
-		if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
-			return 1;
-		return 0;
-	}
-
-	if (argw <= 0xfffff && argw >= -0xfffff)
-		return 0;
-
-	if (argw == next_argw && (next_arg & SLJIT_MEM))
-		return 1;
-
-	if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
-		return 1;
-
-	return 0;
-}
-
-#define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \
-	if (max_delta & 0xf00) \
-		FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \
-	else \
-		FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm))));
-
-#define TEST_WRITE_BACK() \
-	if (inp_flags & WRITE_BACK) { \
-		tmp_r = arg & REG_MASK; \
-		if (reg == tmp_r) { \
-			/* This can only happen for stores */ \
-			/* since ldr reg, [reg, ...]! has no meaning */ \
-			SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg)))); \
-			reg = TMP_REG3; \
-		} \
-	}
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	sljit_s32 tmp_r;
-	sljit_sw max_delta;
-	sljit_sw sign;
-	sljit_uw imm;
-
-	if (arg & SLJIT_IMM) {
-		SLJIT_ASSERT(inp_flags & LOAD_DATA);
-		return load_immediate(compiler, reg, argw);
-	}
-
-	SLJIT_ASSERT(arg & SLJIT_MEM);
-
-	tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3;
-	max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff;
+	SLJIT_ASSERT (arg & SLJIT_MEM);
+	SLJIT_ASSERT((arg & REG_MASK) != tmp_reg);
 
 	if ((arg & REG_MASK) == SLJIT_UNUSED) {
-		/* Write back is not used. */
-		imm = (sljit_uw)(argw - compiler->cache_argw);
-		if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
-			if (imm <= (sljit_uw)max_delta) {
-				sign = 1;
-				argw = argw - compiler->cache_argw;
-			}
-			else {
-				sign = 0;
-				argw = compiler->cache_argw - argw;
-			}
-
-			GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, argw);
-			return SLJIT_SUCCESS;
+		if (is_type1_transfer) {
+			FAIL_IF(load_immediate(compiler, tmp_reg, argw & ~0xfff));
+			argw &= 0xfff;
+		}
+		else {
+			FAIL_IF(load_immediate(compiler, tmp_reg, argw & ~0xff));
+			argw &= 0xff;
 		}
 
-		/* With write back, we can create some sophisticated loads, but
-		   it is hard to decide whether we should convert downward (0s) or upward (1s). */
-		imm = (sljit_uw)(argw - next_argw);
-		if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
-			SLJIT_ASSERT(inp_flags & LOAD_DATA);
-
-			compiler->cache_arg = SLJIT_IMM;
-			compiler->cache_argw = argw;
-			tmp_r = TMP_REG3;
-		}
-
-		FAIL_IF(load_immediate(compiler, tmp_r, argw));
-		GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0);
-		return SLJIT_SUCCESS;
+		return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, tmp_reg,
+			is_type1_transfer ? argw : TYPE2_TRANSFER_IMM(argw)));
 	}
 
 	if (arg & OFFS_REG_MASK) {
-		SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00));
-		if (inp_flags & WRITE_BACK)
-			tmp_r = arg & REG_MASK;
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))));
-		return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0)));
+		offset_reg = OFFS_REG(arg);
+		arg &= REG_MASK;
+		argw &= 0x3;
+
+		if (argw != 0 && !is_type1_transfer) {
+			FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | RM(offset_reg) | (argw << 7)));
+			return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, tmp_reg, TYPE2_TRANSFER_IMM(0)));
+		}
+
+		/* Bit 25: RM is offset. */
+		return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg,
+			RM(offset_reg) | (is_type1_transfer ? (1 << 25) : 0) | (argw << 7)));
 	}
 
-	imm = (sljit_uw)(argw - compiler->cache_argw);
-	if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) {
-		SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
-		GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm);
-		return SLJIT_SUCCESS;
+	arg &= REG_MASK;
+
+	if (is_type1_transfer) {
+		if (argw > 0xfff) {
+			imm = get_imm(argw & ~0xfff);
+			if (imm) {
+				FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | imm));
+				argw = argw & 0xfff;
+				arg = tmp_reg;
+			}
+		}
+		else if (argw < -0xfff) {
+			imm = get_imm(-argw & ~0xfff);
+			if (imm) {
+				FAIL_IF(push_inst(compiler, SUB | RD(tmp_reg) | RN(arg) | imm));
+				argw = -(-argw & 0xfff);
+				arg = tmp_reg;
+			}
+		}
+
+		if (argw >= 0 && argw <= 0xfff)
+			return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg, argw));
+
+		if (argw < 0 && argw >= -0xfff)
+			return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 0, reg, arg, -argw));
 	}
-	if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) {
-		SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
-		imm = (sljit_uw)-(sljit_sw)imm;
-		GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm);
-		return SLJIT_SUCCESS;
+	else {
+		if (argw > 0xff) {
+			imm = get_imm(argw & ~0xff);
+			if (imm) {
+				FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | imm));
+				argw = argw & 0xff;
+				arg = tmp_reg;
+			}
+		}
+		else if (argw < -0xff) {
+			imm = get_imm(-argw & ~0xff);
+			if (imm) {
+				FAIL_IF(push_inst(compiler, SUB | RD(tmp_reg) | RN(arg) | imm));
+				argw = -(-argw & 0xff);
+				arg = tmp_reg;
+			}
+		}
+
+		if (argw >= 0 && argw <= 0xff)
+			return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg, TYPE2_TRANSFER_IMM(argw)));
+
+		if (argw < 0 && argw >= -0xff) {
+			argw = -argw;
+			return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 0, reg, arg, TYPE2_TRANSFER_IMM(argw)));
+		}
 	}
 
-	imm = get_imm(argw & ~max_delta);
-	if (imm) {
-		TEST_WRITE_BACK();
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & REG_MASK, imm)));
-		GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
-		return SLJIT_SUCCESS;
-	}
-
-	imm = get_imm(-argw & ~max_delta);
-	if (imm) {
-		argw = -argw;
-		TEST_WRITE_BACK();
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & REG_MASK, imm)));
-		GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta);
-		return SLJIT_SUCCESS;
-	}
-
-	if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
-		TEST_WRITE_BACK();
-		return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
-	}
-
-	if (argw == next_argw && (next_arg & SLJIT_MEM)) {
-		SLJIT_ASSERT(inp_flags & LOAD_DATA);
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-
-		compiler->cache_arg = SLJIT_IMM;
-		compiler->cache_argw = argw;
-
-		TEST_WRITE_BACK();
-		return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
-	}
-
-	imm = (sljit_uw)(argw - next_argw);
-	if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) {
-		SLJIT_ASSERT(inp_flags & LOAD_DATA);
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & REG_MASK])));
-
-		compiler->cache_arg = arg;
-		compiler->cache_argw = argw;
-
-		GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0);
-		return SLJIT_SUCCESS;
-	}
-
-	if ((arg & REG_MASK) == tmp_r) {
-		compiler->cache_arg = SLJIT_IMM;
-		compiler->cache_argw = argw;
-		tmp_r = TMP_REG3;
-	}
-
-	FAIL_IF(load_immediate(compiler, tmp_r, argw));
-	return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0)));
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
-	if (getput_arg_fast(compiler, flags, reg, arg, argw))
-		return compiler->error;
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
-	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
-		return compiler->error;
-	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+	FAIL_IF(load_immediate(compiler, tmp_reg, argw));
+	return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg,
+		RM(tmp_reg) | (is_type1_transfer ? (1 << 25) : 0)));
 }
 
 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags,
@@ -1604,68 +1432,66 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
-	/* arg1 goes to TMP_REG1 or src reg
-	   arg2 goes to TMP_REG2, imm or src reg
-	   TMP_REG3 can be used for caching
-	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+	/* src1 is reg or TMP_REG1
+	   src2 is reg, TMP_REG2, or imm
+	   result goes to TMP_REG2, so put result can use TMP_REG1. */
 
 	/* We prefers register and simple consts. */
-	sljit_s32 dst_r;
-	sljit_s32 src1_r;
-	sljit_s32 src2_r = 0;
-	sljit_s32 sugg_src2_r = TMP_REG2;
-	sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
-
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
+	sljit_s32 dst_reg;
+	sljit_s32 src1_reg;
+	sljit_s32 src2_reg;
+	sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 
 	/* Destination check. */
-	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
-			return SLJIT_SUCCESS;
-		dst_r = TMP_REG2;
-	}
-	else if (FAST_IS_REG(dst)) {
-		dst_r = dst;
-		flags |= REG_DEST;
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
-			sugg_src2_r = dst_r;
-	}
-	else {
-		SLJIT_ASSERT(dst & SLJIT_MEM);
-		if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
-			flags |= FAST_DEST;
-			dst_r = TMP_REG2;
-		}
-		else {
-			flags |= SLOW_DEST;
-			dst_r = 0;
-		}
-	}
+	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED))
+		flags |= UNUSED_RETURN;
 
-	/* Source 1. */
-	if (FAST_IS_REG(src1))
-		src1_r = src1;
-	else if (FAST_IS_REG(src2)) {
-		flags |= ARGS_SWAPPED;
-		src1_r = src2;
-		src2 = src1;
-		src2w = src1w;
-	}
-	else do { /* do { } while(0) is used because of breaks. */
-		src1_r = 0;
-		if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) {
-			/* The second check will generate a hit. */
-			src2_r = get_imm(src1w);
-			if (src2_r) {
+	SLJIT_ASSERT(!(inp_flags & ALLOW_INV_IMM) || (inp_flags & ALLOW_IMM));
+
+	src2_reg = 0;
+
+	do {
+		if (!(inp_flags & ALLOW_IMM))
+			break;
+
+		if (src2 & SLJIT_IMM) {
+			src2_reg = get_imm(src2w);
+			if (src2_reg)
+				break;
+			if (inp_flags & ALLOW_INV_IMM) {
+				src2_reg = get_imm(~src2w);
+				if (src2_reg) {
+					flags |= INV_IMM;
+					break;
+				}
+			}
+			if (GET_OPCODE(op) == SLJIT_ADD) {
+				src2_reg = get_imm(-src2w);
+				if (src2_reg) {
+					op = SLJIT_SUB | GET_ALL_FLAGS(op);
+					break;
+				}
+			}
+			if (GET_OPCODE(op) == SLJIT_SUB) {
+				src2_reg = get_imm(-src2w);
+				if (src2_reg) {
+					op = SLJIT_ADD | GET_ALL_FLAGS(op);
+					break;
+				}
+			}
+		}
+
+		if (src1 & SLJIT_IMM) {
+			src2_reg = get_imm(src1w);
+			if (src2_reg) {
 				flags |= ARGS_SWAPPED;
 				src1 = src2;
 				src1w = src2w;
 				break;
 			}
 			if (inp_flags & ALLOW_INV_IMM) {
-				src2_r = get_imm(~src1w);
-				if (src2_r) {
+				src2_reg = get_imm(~src1w);
+				if (src2_reg) {
 					flags |= ARGS_SWAPPED | INV_IMM;
 					src1 = src2;
 					src1w = src2w;
@@ -1673,9 +1499,9 @@
 				}
 			}
 			if (GET_OPCODE(op) == SLJIT_ADD) {
-				src2_r = get_imm(-src1w);
-				if (src2_r) {
-					/* Note: ARGS_SWAPPED is intentionally not applied! */
+				src2_reg = get_imm(-src1w);
+				if (src2_reg) {
+					/* Note: add is commutative operation. */
 					src1 = src2;
 					src1w = src2w;
 					op = SLJIT_SUB | GET_ALL_FLAGS(op);
@@ -1683,110 +1509,54 @@
 				}
 			}
 		}
+	} while(0);
 
-		if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
-			FAIL_IF(compiler->error);
-			src1_r = TMP_REG1;
+	/* Source 1. */
+	if (FAST_IS_REG(src1))
+		src1_reg = src1;
+	else if (src1 & SLJIT_MEM) {
+		FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
+		src1_reg = TMP_REG1;
+	}
+	else {
+		FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+		src1_reg = TMP_REG1;
+	}
+
+	/* Destination. */
+	dst_reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+
+	if (op <= SLJIT_MOV_P) {
+		if (dst & SLJIT_MEM) {
+			if (inp_flags & BYTE_SIZE)
+				inp_flags &= ~SIGNED;
+
+			if (FAST_IS_REG(src2))
+				return emit_op_mem(compiler, inp_flags, src2, dst, dstw, TMP_REG2);
 		}
-	} while (0);
+
+		if (FAST_IS_REG(src2) && dst_reg != TMP_REG2)
+			flags |= MOVE_REG_CONV;
+	}
 
 	/* Source 2. */
-	if (src2_r == 0) {
-		if (FAST_IS_REG(src2)) {
-			src2_r = src2;
-			flags |= REG_SOURCE;
-			if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
-				dst_r = src2_r;
-		}
-		else do { /* do { } while(0) is used because of breaks. */
-			if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) {
-				src2_r = get_imm(src2w);
-				if (src2_r)
-					break;
-				if (inp_flags & ALLOW_INV_IMM) {
-					src2_r = get_imm(~src2w);
-					if (src2_r) {
-						flags |= INV_IMM;
-						break;
-					}
-				}
-				if (GET_OPCODE(op) == SLJIT_ADD) {
-					src2_r = get_imm(-src2w);
-					if (src2_r) {
-						op = SLJIT_SUB | GET_ALL_FLAGS(op);
-						flags &= ~ARGS_SWAPPED;
-						break;
-					}
-				}
-				if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) {
-					src2_r = get_imm(-src2w);
-					if (src2_r) {
-						op = SLJIT_ADD | GET_ALL_FLAGS(op);
-						flags &= ~ARGS_SWAPPED;
-						break;
-					}
-				}
-			}
+	if (src2_reg == 0) {
+		src2_reg = (op <= SLJIT_MOV_P) ? dst_reg : TMP_REG2;
 
-			/* src2_r is 0. */
-			if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
-				FAIL_IF(compiler->error);
-				src2_r = sugg_src2_r;
-			}
-		} while (0);
-	}
-
-	/* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero.
-	   If they are zero, they must not be registers. */
-	if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
-		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
-			SLJIT_ASSERT(!(flags & ARGS_SWAPPED));
-			flags |= ARGS_SWAPPED;
-			FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w));
-			FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw));
-		}
-		else {
-			FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
-			FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
-		}
-		src1_r = TMP_REG1;
-		src2_r = TMP_REG2;
-	}
-	else if (src1_r == 0 && src2_r == 0) {
-		FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
-		src1_r = TMP_REG1;
-	}
-	else if (src1_r == 0 && dst_r == 0) {
-		FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
-		src1_r = TMP_REG1;
-	}
-	else if (src2_r == 0 && dst_r == 0) {
-		FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
-		src2_r = sugg_src2_r;
-	}
-
-	if (dst_r == 0)
-		dst_r = TMP_REG2;
-
-	if (src1_r == 0) {
-		FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
-		src1_r = TMP_REG1;
-	}
-
-	if (src2_r == 0) {
-		FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
-		src2_r = sugg_src2_r;
-	}
-
-	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
-
-	if (flags & (FAST_DEST | SLOW_DEST)) {
-		if (flags & FAST_DEST)
-			FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw));
+		if (FAST_IS_REG(src2))
+			src2_reg = src2;
+		else if (src2 & SLJIT_MEM)
+			FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, src2_reg, src2, src2w, TMP_REG2));
 		else
-			FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0));
+			FAIL_IF(load_immediate(compiler, src2_reg, src2w));
 	}
-	return SLJIT_SUCCESS;
+
+	FAIL_IF(emit_single_op(compiler, op, flags, dst_reg, src1_reg, src2_reg));
+
+	if (!(dst & SLJIT_MEM))
+		return SLJIT_SUCCESS;
+
+	return emit_op_mem(compiler, inp_flags, dst_reg, dst, dstw, TMP_REG1);
 }
 
 #ifdef __cplusplus
@@ -1806,6 +1576,9 @@
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
 {
+	sljit_sw saved_reg_list[3];
+	sljit_sw saved_reg_count;
+
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_op0(compiler, op));
 
@@ -1819,33 +1592,38 @@
 		break;
 	case SLJIT_LMUL_UW:
 	case SLJIT_LMUL_SW:
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
 		return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
 			| (reg_map[SLJIT_R1] << 16)
 			| (reg_map[SLJIT_R0] << 12)
 			| (reg_map[SLJIT_R0] << 8)
 			| reg_map[SLJIT_R1]);
-#else
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_R1))));
-		return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
-			| (reg_map[SLJIT_R1] << 16)
-			| (reg_map[SLJIT_R0] << 12)
-			| (reg_map[SLJIT_R0] << 8)
-			| reg_map[TMP_REG1]);
-#endif
 	case SLJIT_DIVMOD_UW:
 	case SLJIT_DIVMOD_SW:
 	case SLJIT_DIV_UW:
 	case SLJIT_DIV_SW:
 		SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
-		SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping);
+		SLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);
 
-		if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) {
-			FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */));
-			FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */));
+		saved_reg_count = 0;
+		if (compiler->scratches >= 4)
+			saved_reg_list[saved_reg_count++] = 3;
+		if (compiler->scratches >= 3)
+			saved_reg_list[saved_reg_count++] = 2;
+		if (op >= SLJIT_DIV_UW)
+			saved_reg_list[saved_reg_count++] = 1;
+
+		if (saved_reg_count > 0) {
+			FAIL_IF(push_inst(compiler, 0xe52d0000 | (saved_reg_count >= 3 ? 16 : 8)
+						| (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));
+			if (saved_reg_count >= 2) {
+				SLJIT_ASSERT(saved_reg_list[1] < 8);
+				FAIL_IF(push_inst(compiler, 0xe58d0004 | (saved_reg_list[1] << 12) /* str rX, [sp, #4] */));
+			}
+			if (saved_reg_count >= 3) {
+				SLJIT_ASSERT(saved_reg_list[2] < 8);
+				FAIL_IF(push_inst(compiler, 0xe58d0008 | (saved_reg_list[2] << 12) /* str rX, [sp, #8] */));
+			}
 		}
-		else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3))
-			FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */));
 
 #if defined(__GNUC__)
 		FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
@@ -1854,12 +1632,18 @@
 #error "Software divmod functions are needed"
 #endif
 
-		if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) {
-			FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */));
-			FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */));
+		if (saved_reg_count > 0) {
+			if (saved_reg_count >= 3) {
+				SLJIT_ASSERT(saved_reg_list[2] < 8);
+				FAIL_IF(push_inst(compiler, 0xe59d0008 | (saved_reg_list[2] << 12) /* ldr rX, [sp, #8] */));
+			}
+			if (saved_reg_count >= 2) {
+				SLJIT_ASSERT(saved_reg_list[1] < 8);
+				FAIL_IF(push_inst(compiler, 0xe59d0004 | (saved_reg_list[1] << 12) /* ldr rX, [sp, #4] */));
+			}
+			return push_inst(compiler, 0xe49d0000 | (saved_reg_count >= 3 ? 16 : 8)
+						| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
 		}
-		else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3))
-			return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */);
 		return SLJIT_SUCCESS;
 	}
 
@@ -1875,6 +1659,14 @@
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+		if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
+			return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);
+#endif
+		return SLJIT_SUCCESS;
+	}
+
 	switch (GET_OPCODE(op)) {
 	case SLJIT_MOV:
 	case SLJIT_MOV_U32:
@@ -1883,34 +1675,16 @@
 		return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
 
 	case SLJIT_MOV_U8:
-		return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
+		return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
 
 	case SLJIT_MOV_S8:
-		return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
+		return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
 
 	case SLJIT_MOV_U16:
-		return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
+		return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
 
 	case SLJIT_MOV_S16:
-		return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
-
-	case SLJIT_MOVU:
-	case SLJIT_MOVU_U32:
-	case SLJIT_MOVU_S32:
-	case SLJIT_MOVU_P:
-		return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
-	case SLJIT_MOVU_U8:
-		return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
-
-	case SLJIT_MOVU_S8:
-		return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
-
-	case SLJIT_MOVU_U16:
-		return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
-
-	case SLJIT_MOVU_S16:
-		return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
+		return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
 
 	case SLJIT_NOT:
 		return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
@@ -1940,6 +1714,9 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
+
 	switch (GET_OPCODE(op)) {
 	case SLJIT_ADD:
 	case SLJIT_ADDC:
@@ -1980,7 +1757,7 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
 {
 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
-	return reg << 1;
+	return (freg_map[reg] << 1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
@@ -1996,118 +1773,63 @@
 /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */
 
-#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-
-/* 0 - no fpu
-   1 - vfp */
-static sljit_s32 arm_fpu_type = -1;
-
-static void init_compiler(void)
-{
-	if (arm_fpu_type != -1)
-		return;
-
-	/* TODO: Only the OS can help to determine the correct fpu type. */
-	arm_fpu_type = 1;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-#ifdef SLJIT_IS_FPU_AVAILABLE
-	return SLJIT_IS_FPU_AVAILABLE;
-#else
-	if (arm_fpu_type == -1)
-		init_compiler();
-	return arm_fpu_type;
-#endif
-}
-
-#else
-
-#define arm_fpu_type 1
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-	/* Always available. */
-	return 1;
-}
-
-#endif
 
 #define FPU_LOAD (1 << 20)
 #define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \
-	((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs))
+	((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg_map[freg] << 12) | (offs))
 #define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \
-	((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16))
+	((opcode) | (mode) | (freg_map[dst] << 12) | freg_map[src1] | (freg_map[src2] << 16))
 
 static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
 {
-	sljit_sw tmp;
 	sljit_uw imm;
 	sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD));
+
 	SLJIT_ASSERT(arg & SLJIT_MEM);
+	arg &= ~SLJIT_MEM;
 
 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, RM(OFFS_REG(arg)) | ((argw & 0x3) << 7))));
-		arg = SLJIT_MEM | TMP_REG1;
+		FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((argw & 0x3) << 7)));
+		arg = TMP_REG2;
 		argw = 0;
 	}
 
 	/* Fast loads and stores. */
-	if ((arg & REG_MASK)) {
+	if (arg) {
 		if (!(argw & ~0x3fc))
 			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & REG_MASK, reg, argw >> 2));
 		if (!(-argw & ~0x3fc))
 			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & REG_MASK, reg, (-argw) >> 2));
-	}
 
-	if (compiler->cache_arg == arg) {
-		tmp = argw - compiler->cache_argw;
-		if (!(tmp & ~0x3fc))
-			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2));
-		if (!(-tmp & ~0x3fc))
-			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, reg, -tmp >> 2));
-		if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			compiler->cache_argw = argw;
-			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0));
-		}
-	}
-
-	if (arg & REG_MASK) {
-		if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0));
-		}
 		imm = get_imm(argw & ~0x3fc);
 		if (imm) {
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & REG_MASK, imm)));
-			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2));
+			FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | imm));
+			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG2, reg, (argw & 0x3fc) >> 2));
 		}
 		imm = get_imm(-argw & ~0x3fc);
 		if (imm) {
 			argw = -argw;
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & REG_MASK, imm)));
-			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2));
+			FAIL_IF(push_inst(compiler, SUB | RD(TMP_REG2) | RN(arg & REG_MASK) | imm));
+			return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG2, reg, (argw & 0x3fc) >> 2));
 		}
 	}
 
-	compiler->cache_arg = arg;
-	compiler->cache_argw = argw;
-	if (arg & REG_MASK) {
-		FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & REG_MASK, reg_map[TMP_REG1])));
+	if (arg) {
+		FAIL_IF(load_immediate(compiler, TMP_REG2, argw));
+		FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(TMP_REG2)));
 	}
 	else
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+		FAIL_IF(load_immediate(compiler, TMP_REG2, argw));
 
-	return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0));
+	return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG2, reg, 0));
 }
 
 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
+	op ^= SLJIT_F32_OP;
+
 	if (src & SLJIT_MEM) {
 		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
 		src = TMP_FREG1;
@@ -2115,11 +1837,8 @@
 
 	FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_F32_OP, TMP_FREG1, src, 0)));
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (FAST_IS_REG(dst))
-		return push_inst(compiler, VMOV | (1 << 20) | RD(dst) | (TMP_FREG1 << 16));
+		return push_inst(compiler, VMOV | (1 << 20) | RD(dst) | (freg_map[TMP_FREG1] << 16));
 
 	/* Store the integer value from a VFP register. */
 	return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
@@ -2131,15 +1850,17 @@
 {
 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
+	op ^= SLJIT_F32_OP;
+
 	if (FAST_IS_REG(src))
-		FAIL_IF(push_inst(compiler, VMOV | RD(src) | (TMP_FREG1 << 16)));
+		FAIL_IF(push_inst(compiler, VMOV | RD(src) | (freg_map[TMP_FREG1] << 16)));
 	else if (src & SLJIT_MEM) {
 		/* Load the integer value into a VFP register. */
 		FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw));
 	}
 	else {
 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
-		FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (TMP_FREG1 << 16)));
+		FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (freg_map[TMP_FREG1] << 16)));
 	}
 
 	FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_F32_OP, dst_r, TMP_FREG1, 0)));
@@ -2153,6 +1874,8 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
+	op ^= SLJIT_F32_OP;
+
 	if (src1 & SLJIT_MEM) {
 		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w));
 		src1 = TMP_FREG1;
@@ -2174,16 +1897,15 @@
 	sljit_s32 dst_r;
 
 	CHECK_ERROR();
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
-		op ^= SLJIT_F32_OP;
 
 	SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error);
 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
 
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
+	if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
+		op ^= SLJIT_F32_OP;
+
 	if (src & SLJIT_MEM) {
 		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw));
 		src = dst_r;
@@ -2228,8 +1950,6 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
 	op ^= SLJIT_F32_OP;
 
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
@@ -2270,7 +1990,6 @@
 
 #undef FPU_LOAD
 #undef EMIT_FPU_DATA_TRANSFER
-#undef EMIT_FPU_OPERATION
 
 /* --------------------------------------------------------------------- */
 /*  Other instructions                                                   */
@@ -2282,21 +2001,13 @@
 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	/* For UNUSED dst. Uncommon, but possible. */
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
+	SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
 
 	if (FAST_IS_REG(dst))
-		return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3)));
+		return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2));
 
 	/* Memory. */
-	if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw))
-		return compiler->error;
-	/* TMP_REG3 is used for caching. */
-	FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))));
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0);
+	return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
@@ -2305,21 +2016,14 @@
 	CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
+	SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
+
 	if (FAST_IS_REG(src))
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))));
-	else if (src & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw))
-			FAIL_IF(compiler->error);
-		else {
-			compiler->cache_arg = 0;
-			compiler->cache_argw = 0;
-			FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0));
-			FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2))));
-		}
-	}
-	else if (src & SLJIT_IMM)
-		FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
-	return push_inst(compiler, BLX | RM(TMP_REG3));
+		FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
+	else
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));
+
+	return push_inst(compiler, BX | RM(TMP_REG2));
 }
 
 /* --------------------------------------------------------------------- */
@@ -2376,7 +2080,7 @@
 		return 0x70000000;
 
 	default:
-		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);
 		return 0xe0000000;
 	}
 }
@@ -2409,11 +2113,12 @@
 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
 	type &= 0xff;
 
-	/* In ARM, we don't need to touch the arguments. */
+	SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
+
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
 	if (type >= SLJIT_FAST_CALL)
 		PTR_FAIL_IF(prepare_blx(compiler));
-	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0,
+	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(type), 0));
 
 	if (jump->flags & SLJIT_REWRITABLE_JUMP) {
@@ -2438,6 +2143,241 @@
 	return jump;
 }
 
+#ifdef __SOFTFP__
+
+static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
+{
+	sljit_s32 stack_offset = 0;
+	sljit_s32 arg_count = 0;
+	sljit_s32 word_arg_offset = 0;
+	sljit_s32 float_arg_count = 0;
+	sljit_s32 types = 0;
+	sljit_s32 src_offset = 4 * sizeof(sljit_sw);
+	sljit_u8 offsets[4];
+
+	if (src && FAST_IS_REG(*src))
+		src_offset = reg_map[*src] * sizeof(sljit_sw);
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
+
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			offsets[arg_count] = (sljit_u8)stack_offset;
+			stack_offset += sizeof(sljit_f32);
+			arg_count++;
+			float_arg_count++;
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (stack_offset & 0x7)
+				stack_offset += sizeof(sljit_sw);
+			offsets[arg_count] = (sljit_u8)stack_offset;
+			stack_offset += sizeof(sljit_f64);
+			arg_count++;
+			float_arg_count++;
+			break;
+		default:
+			offsets[arg_count] = (sljit_u8)stack_offset;
+			stack_offset += sizeof(sljit_sw);
+			arg_count++;
+			word_arg_offset += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	if (stack_offset > 16)
+		FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | (((stack_offset - 16) + 0x7) & ~0x7)));
+
+	/* Process arguments in reversed direction. */
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			arg_count--;
+			float_arg_count--;
+			stack_offset = offsets[arg_count];
+
+			if (stack_offset < 16) {
+				if (src_offset == stack_offset) {
+					FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));
+					*src = TMP_REG1;
+				}
+				FAIL_IF(push_inst(compiler, VMOV | 0x100000 | (float_arg_count << 16) | (stack_offset << 10)));
+			} else
+				FAIL_IF(push_inst(compiler, VSTR_F32 | 0x800000 | RN(SLJIT_SP) | (float_arg_count << 12) | ((stack_offset - 16) >> 2)));
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			arg_count--;
+			float_arg_count--;
+			stack_offset = offsets[arg_count];
+
+			SLJIT_ASSERT((stack_offset & 0x7) == 0);
+
+			if (stack_offset < 16) {
+				if (src_offset == stack_offset || src_offset == stack_offset + sizeof(sljit_sw)) {
+					FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));
+					*src = TMP_REG1;
+				}
+				FAIL_IF(push_inst(compiler, VMOV2 | 0x100000 | (stack_offset << 10) | ((stack_offset + sizeof(sljit_sw)) << 14) | float_arg_count));
+			} else
+				FAIL_IF(push_inst(compiler, VSTR_F32 | 0x800100 | RN(SLJIT_SP) | (float_arg_count << 12) | ((stack_offset - 16) >> 2)));
+			break;
+		default:
+			arg_count--;
+			word_arg_offset -= sizeof(sljit_sw);
+			stack_offset = offsets[arg_count];
+
+			SLJIT_ASSERT(stack_offset >= word_arg_offset);
+
+			if (stack_offset != word_arg_offset) {
+				if (stack_offset < 16) {
+					if (src_offset == stack_offset) {
+						FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | (src_offset >> 2)));
+						*src = TMP_REG1;
+					}
+					else if (src_offset == word_arg_offset) {
+						*src = 1 + (stack_offset >> 2);
+						src_offset = stack_offset;
+					}
+					FAIL_IF(push_inst(compiler, MOV | (stack_offset << 10) | (word_arg_offset >> 2)));
+				} else
+					FAIL_IF(push_inst(compiler, data_transfer_insts[WORD_SIZE] | 0x800000 | RN(SLJIT_SP) | (word_arg_offset << 10) | (stack_offset - 16)));
+			}
+			break;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
+	return SLJIT_SUCCESS;
+}
+
+static sljit_s32 softfloat_post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
+{
+	sljit_s32 stack_size = 0;
+
+	if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32)
+		FAIL_IF(push_inst(compiler, VMOV | (0 << 16) | (0 << 12)));
+	if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F64)
+		FAIL_IF(push_inst(compiler, VMOV2 | (1 << 16) | (0 << 12) | 0));
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			stack_size += sizeof(sljit_f32);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (stack_size & 0x7)
+				stack_size += sizeof(sljit_sw);
+			stack_size += sizeof(sljit_f64);
+			break;
+		default:
+			stack_size += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	if (stack_size <= 16)
+		return SLJIT_SUCCESS;
+
+	return push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | SRC2_IMM | (((stack_size - 16) + 0x7) & ~0x7));
+}
+
+#else /* !__SOFTFP__ */
+
+static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
+{
+	sljit_u32 remap = 0;
+	sljit_u32 offset = 0;
+	sljit_u32 new_offset, mask;
+
+	/* Remove return value. */
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32) {
+			new_offset = 0;
+			mask = 1;
+
+			while (remap & mask) {
+				new_offset++;
+				mask <<= 1;
+			}
+			remap |= mask;
+
+			if (offset != new_offset)
+				FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32,
+					0, (new_offset >> 1) + 1, (offset >> 1) + 1, 0) | ((new_offset & 0x1) ? 0x400000 : 0)));
+
+			offset += 2;
+		}
+		else if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F64) {
+			new_offset = 0;
+			mask = 3;
+
+			while (remap & mask) {
+				new_offset += 2;
+				mask <<= 2;
+			}
+			remap |= mask;
+
+			if (offset != new_offset)
+				FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, SLJIT_F32_OP, (new_offset >> 1) + 1, (offset >> 1) + 1, 0)));
+
+			offset += 2;
+		}
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	return SLJIT_SUCCESS;
+}
+
+#endif /* __SOFTFP__ */
+
+#undef EMIT_FPU_OPERATION
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+#ifdef __SOFTFP__
+	struct sljit_jump *jump;
+#endif
+
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+#ifdef __SOFTFP__
+	PTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types, NULL));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	jump = sljit_emit_jump(compiler, type);
+	PTR_FAIL_IF(jump == NULL);
+
+	PTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));
+	return jump;
+#else /* !__SOFTFP__ */
+	PTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_jump(compiler, type);
+#endif /* __SOFTFP__ */
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
 {
 	struct sljit_jump *jump;
@@ -2446,16 +2386,20 @@
 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-	/* In ARM, we don't need to touch the arguments. */
+	SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
+
 	if (!(src & SLJIT_IMM)) {
-		if (FAST_IS_REG(src))
+		if (FAST_IS_REG(src)) {
+			SLJIT_ASSERT(reg_map[src] != 14);
 			return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src));
+		}
 
 		SLJIT_ASSERT(src & SLJIT_MEM);
-		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
-		return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2));
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
+		return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1));
 	}
 
+	/* These jumps are converted to jump/call instructions when possible. */
 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 	FAIL_IF(!jump);
 	set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
@@ -2464,7 +2408,7 @@
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
 	if (type >= SLJIT_FAST_CALL)
 		FAIL_IF(prepare_blx(compiler));
-	FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0));
+	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), 0));
 	if (type >= SLJIT_FAST_CALL)
 		FAIL_IF(emit_blx(compiler));
 #else
@@ -2475,57 +2419,221 @@
 	return SLJIT_SUCCESS;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+#ifdef __SOFTFP__
+	if (src & SLJIT_MEM) {
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
+		src = TMP_REG1;
+	}
+
+	FAIL_IF(softfloat_call_with_args(compiler, arg_types, &src));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
+
+	return softfloat_post_call_with_args(compiler, arg_types);
+#else /* !__SOFTFP__ */
+	FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_ijump(compiler, type, src, srcw);
+#endif /* __SOFTFP__ */
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
-	sljit_s32 dst_r, flags = GET_ALL_FLAGS(op);
+	sljit_s32 dst_reg, flags = GET_ALL_FLAGS(op);
 	sljit_uw cc, ins;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
-	ADJUST_LOCAL_OFFSET(src, srcw);
-
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
 
 	op = GET_OPCODE(op);
 	cc = get_cc(type & 0xff);
-	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+	dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
 
 	if (op < SLJIT_ADD) {
-		FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0)));
-		FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc));
-		return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
+		FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | SRC2_IMM | 0));
+		FAIL_IF(push_inst(compiler, ((MOV | RD(dst_reg) | SRC2_IMM | 1) & ~COND_MASK) | cc));
+		if (dst & SLJIT_MEM)
+			return emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2);
+		return SLJIT_SUCCESS;
 	}
 
-	ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP));
-	if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) {
-		FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc));
-		/* The condition must always be set, even if the ORR/EOR is not executed above. */
-		return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS;
-	}
+	ins = (op == SLJIT_AND ? AND : (op == SLJIT_OR ? ORR : EOR));
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	if (src & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
-		src = TMP_REG1;
-		srcw = 0;
-	} else if (src & SLJIT_IMM) {
+	if (dst & SLJIT_MEM)
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG2));
+
+	FAIL_IF(push_inst(compiler, ((ins | RD(dst_reg) | RN(dst_reg) | SRC2_IMM | 1) & ~COND_MASK) | cc));
+
+	if (op == SLJIT_AND)
+		FAIL_IF(push_inst(compiler, ((ins | RD(dst_reg) | RN(dst_reg) | SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)));
+
+	if (dst & SLJIT_MEM)
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));
+
+	if (flags & SLJIT_SET_Z)
+		return push_inst(compiler, MOV | SET_FLAGS | RD(TMP_REG2) | RM(dst_reg));
+	return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_uw cc, tmp;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+	dst_reg &= ~SLJIT_I32_OP;
+
+	cc = get_cc(type & 0xff);
+
+	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+		tmp = get_imm(srcw);
+		if (tmp)
+			return push_inst(compiler, ((MOV | RD(dst_reg) | tmp) & ~COND_MASK) | cc);
+
+		tmp = get_imm(~srcw);
+		if (tmp)
+			return push_inst(compiler, ((MVN | RD(dst_reg) | tmp) & ~COND_MASK) | cc);
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+		tmp = (sljit_uw) srcw;
+		FAIL_IF(push_inst(compiler, (MOVW & ~COND_MASK) | cc | RD(dst_reg) | ((tmp << 4) & 0xf0000) | (tmp & 0xfff)));
+		if (tmp <= 0xffff)
+			return SLJIT_SUCCESS;
+		return push_inst(compiler, (MOVT & ~COND_MASK) | cc | RD(dst_reg) | ((tmp >> 12) & 0xf0000) | ((tmp >> 16) & 0xfff));
+#else
 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
 		src = TMP_REG1;
-		srcw = 0;
+#endif
 	}
 
-	FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc));
-	FAIL_IF(push_inst(compiler, (EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)));
-	if (dst_r == TMP_REG2)
-		FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0));
+	return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src)) & ~COND_MASK) | cc);
+}
 
-	return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS;
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 reg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	sljit_s32 flags;
+	sljit_uw is_type1_transfer, inst;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
+
+	is_type1_transfer = 1;
+
+	switch (type & 0xff) {
+	case SLJIT_MOV:
+	case SLJIT_MOV_U32:
+	case SLJIT_MOV_S32:
+	case SLJIT_MOV_P:
+		flags = WORD_SIZE;
+		break;
+	case SLJIT_MOV_U8:
+		flags = BYTE_SIZE;
+		break;
+	case SLJIT_MOV_S8:
+		if (!(type & SLJIT_MEM_STORE))
+			is_type1_transfer = 0;
+		flags = BYTE_SIZE | SIGNED;
+		break;
+	case SLJIT_MOV_U16:
+		is_type1_transfer = 0;
+		flags = HALF_SIZE;
+		break;
+	case SLJIT_MOV_S16:
+		is_type1_transfer = 0;
+		flags = HALF_SIZE | SIGNED;
+		break;
+	default:
+		SLJIT_UNREACHABLE();
+		flags = WORD_SIZE;
+		break;
+	}
+
+	if (!(type & SLJIT_MEM_STORE))
+		flags |= LOAD_DATA;
+
+	SLJIT_ASSERT(is_type1_transfer == !!IS_TYPE1_TRANSFER(flags));
+
+	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
+		if (!is_type1_transfer && memw != 0)
+			return SLJIT_ERR_UNSUPPORTED;
+	}
+	else {
+		if (is_type1_transfer) {
+			if (memw > 4095 && memw < -4095)
+				return SLJIT_ERR_UNSUPPORTED;
+		}
+		else {
+			if (memw > 255 && memw < -255)
+				return SLJIT_ERR_UNSUPPORTED;
+		}
+	}
+
+	if (type & SLJIT_MEM_SUPP)
+		return SLJIT_SUCCESS;
+
+	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
+		memw &= 0x3;
+
+		inst = EMIT_DATA_TRANSFER(flags, 1, reg, mem & REG_MASK, RM(OFFS_REG(mem)) | (memw << 7));
+
+		if (is_type1_transfer)
+			inst |= (1 << 25);
+
+		if (type & SLJIT_MEM_PRE)
+			inst |= (1 << 21);
+		else
+			inst ^= (1 << 24);
+
+		return push_inst(compiler, inst);
+	}
+
+	inst = EMIT_DATA_TRANSFER(flags, 0, reg, mem & REG_MASK, 0);
+
+	if (type & SLJIT_MEM_PRE)
+		inst |= (1 << 21);
+	else
+		inst ^= (1 << 24);
+
+	if (is_type1_transfer) {
+		if (memw >= 0)
+			inst |= (1 << 23);
+		else
+			memw = -memw;
+
+		return push_inst(compiler, inst | memw);
+	}
+
+	if (memw >= 0)
+		inst |= (1 << 23);
+	else
+		memw = -memw;
+
+	return push_inst(compiler, inst | TYPE2_TRANSFER_IMM(memw));
 }
 
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
@@ -2543,7 +2651,7 @@
 	reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
 
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
-	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value));
+	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), init_value));
 	compiler->patches++;
 #else
 	PTR_FAIL_IF(emit_imm(compiler, reg, init_value));
@@ -2551,16 +2659,16 @@
 	set_const(const_, compiler);
 
 	if (dst & SLJIT_MEM)
-		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
 	return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
-	inline_set_jump_addr(addr, new_addr, 1);
+	inline_set_jump_addr(addr, executable_offset, new_target, 1);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
-	inline_set_const(addr, new_constant, 1);
+	inline_set_const(addr, executable_offset, new_constant, 1);
 }
diff --git a/dist2/src/sljit/sljitNativeARM_64.c b/dist2/src/sljit/sljitNativeARM_64.c
index d995851..8a437bd 100644
--- a/dist2/src/sljit/sljitNativeARM_64.c
+++ b/dist2/src/sljit/sljitNativeARM_64.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -36,15 +36,19 @@
 
 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
-#define TMP_LR		(SLJIT_NUMBER_OF_REGISTERS + 5)
-#define TMP_SP		(SLJIT_NUMBER_OF_REGISTERS + 6)
+#define TMP_LR		(SLJIT_NUMBER_OF_REGISTERS + 4)
+#define TMP_SP		(SLJIT_NUMBER_OF_REGISTERS + 5)
 
-#define TMP_FREG1	(0)
-#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
 
+/* r18 - platform register, currently not used */
 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
-  31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31
+	31, 0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 30, 31
+};
+
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
+	0, 0, 1, 2, 3, 4, 5, 6, 7
 };
 
 #define W_OP (1 << 31)
@@ -53,10 +57,10 @@
 #define RN(rn) (reg_map[rn] << 5)
 #define RT2(rt2) (reg_map[rt2] << 10)
 #define RM(rm) (reg_map[rm] << 16)
-#define VD(vd) (vd)
-#define VT(vt) (vt)
-#define VN(vn) ((vn) << 5)
-#define VM(vm) ((vm) << 16)
+#define VD(vd) (freg_map[vd])
+#define VT(vt) (freg_map[vt])
+#define VN(vn) (freg_map[vn] << 5)
+#define VM(vm) (freg_map[vm] << 16)
 
 /* --------------------------------------------------------------------- */
 /*  Instrucion forms                                                     */
@@ -76,6 +80,7 @@
 #define BRK 0xd4200000
 #define CBZ 0xb4000000
 #define CLZ 0xdac01000
+#define CSEL 0x9a800000
 #define CSINC 0x9a800400
 #define EOR 0xca000000
 #define EORI 0xd2000000
@@ -111,10 +116,13 @@
 #define SMULH 0x9b403c00
 #define STP 0xa9000000
 #define STP_PRE 0xa9800000
+#define STRB 0x38206800
+#define STRBI 0x39000000
 #define STRI 0xf9000000
 #define STR_FI 0x3d000000
 #define STR_FR 0x3c206800
 #define STUR_FI 0x3c000000
+#define STURBI 0x38000000
 #define SUB 0xcb000000
 #define SUBI 0xd1000000
 #define SUBS 0xeb000000
@@ -151,7 +159,7 @@
 	inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
 }
 
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+static SLJIT_INLINE sljit_s32 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;
@@ -165,9 +173,10 @@
 		target_addr = jump->u.target;
 	else {
 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-		target_addr = (sljit_uw)(code + jump->u.label->size);
+		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
 	}
-	diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4);
+
+	diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset;
 
 	if (jump->flags & IS_COND) {
 		diff += sizeof(sljit_ins);
@@ -191,6 +200,7 @@
 		code_ptr[-2] = code_ptr[0];
 		return 2;
 	}
+
 	if (target_addr <= 0xffffffffffffl) {
 		if (jump->flags & IS_COND)
 			code_ptr[-5] -= (1 << 5);
@@ -211,6 +221,7 @@
 	sljit_ins *buf_ptr;
 	sljit_ins *buf_end;
 	sljit_uw word_count;
+	sljit_sw executable_offset;
 	sljit_uw addr;
 	sljit_s32 dst;
 
@@ -228,6 +239,8 @@
 
 	code_ptr = code;
 	word_count = 0;
+	executable_offset = SLJIT_EXEC_OFFSET(code);
+
 	label = compiler->labels;
 	jump = compiler->jumps;
 	const_ = compiler->consts;
@@ -242,13 +255,13 @@
 			SLJIT_ASSERT(!jump || jump->addr >= word_count);
 			SLJIT_ASSERT(!const_ || const_->addr >= word_count);
 			if (label && label->size == word_count) {
-				label->addr = (sljit_uw)code_ptr;
+				label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 				label->size = code_ptr - code;
 				label = label->next;
 			}
 			if (jump && jump->addr == word_count) {
 					jump->addr = (sljit_uw)(code_ptr - 4);
-					code_ptr -= detect_jump_type(jump, code_ptr, code);
+					code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
 					jump = jump->next;
 			}
 			if (const_ && const_->addr == word_count) {
@@ -263,7 +276,7 @@
 	} while (buf);
 
 	if (label && label->size == word_count) {
-		label->addr = (sljit_uw)code_ptr;
+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 		label->size = code_ptr - code;
 		label = label->next;
 	}
@@ -277,9 +290,10 @@
 	while (jump) {
 		do {
 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-			buf_ptr = (sljit_ins*)jump->addr;
+			buf_ptr = (sljit_ins *)jump->addr;
+
 			if (jump->flags & PATCH_B) {
-				addr = (sljit_sw)(addr - jump->addr) >> 2;
+				addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
 				SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000);
 				buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff);
 				if (jump->flags & IS_COND)
@@ -287,7 +301,7 @@
 				break;
 			}
 			if (jump->flags & PATCH_COND) {
-				addr = (sljit_sw)(addr - jump->addr) >> 2;
+				addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
 				SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000);
 				buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
 				break;
@@ -308,11 +322,36 @@
 	}
 
 	compiler->error = SLJIT_ERR_COMPILED;
+	compiler->executable_offset = executable_offset;
 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+
+	code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+	code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
 	SLJIT_CACHE_FLUSH(code, code_ptr);
 	return code;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	switch (feature_type) {
+	case SLJIT_HAS_FPU:
+#ifdef SLJIT_IS_FPU_AVAILABLE
+		return SLJIT_IS_FPU_AVAILABLE;
+#else
+		/* Available by default. */
+		return 1;
+#endif
+
+	case SLJIT_HAS_CLZ:
+	case SLJIT_HAS_CMOV:
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
 /* --------------------------------------------------------------------- */
 /*  Core code generator functions.                                       */
 /* --------------------------------------------------------------------- */
@@ -362,12 +401,14 @@
 
 	SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1)
 		|| (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1));
+
 	uimm = (sljit_uw)imm;
 	while (1) {
 		if (len <= 0) {
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 			return 0;
 		}
+
 		mask = ((sljit_uw)1 << len) - 1;
 		if ((uimm & mask) != ((uimm >> len) & mask))
 			break;
@@ -416,39 +457,42 @@
 	sljit_s32 i, zeros, ones, first;
 	sljit_ins bitmask;
 
+	/* Handling simple immediates first. */
 	if (imm <= 0xffff)
 		return push_inst(compiler, MOVZ | RD(dst) | (imm << 5));
 
-	if (simm >= -0x10000 && simm < 0)
+	if (simm < 0 && simm >= -0x10000)
 		return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5));
 
 	if (imm <= 0xffffffffl) {
+		if ((imm & 0xffff) == 0)
+			return push_inst(compiler, MOVZ | RD(dst) | ((imm >> 16) << 5) | (1 << 21));
 		if ((imm & 0xffff0000l) == 0xffff0000)
 			return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff) << 5));
 		if ((imm & 0xffff) == 0xffff)
 			return push_inst(compiler, (MOVN ^ W_OP) | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
+
 		bitmask = logical_imm(simm, 16);
 		if (bitmask != 0)
 			return push_inst(compiler, (ORRI ^ W_OP) | RD(dst) | RN(TMP_ZERO) | bitmask);
-	}
-	else {
-		bitmask = logical_imm(simm, 32);
-		if (bitmask != 0)
-			return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask);
-	}
 
-	if (imm <= 0xffffffffl) {
 		FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
 		return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
 	}
 
-	if (simm >= -0x100000000l && simm < 0) {
+	bitmask = logical_imm(simm, 32);
+	if (bitmask != 0)
+		return push_inst(compiler, ORRI | RD(dst) | RN(TMP_ZERO) | bitmask);
+
+	if (simm < 0 && simm >= -0x100000000l) {
+		if ((imm & 0xffff) == 0xffff)
+			return push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
+
 		FAIL_IF(push_inst(compiler, MOVN | RD(dst) | ((~imm & 0xffff) << 5)));
 		return push_inst(compiler, MOVK | RD(dst) | ((imm & 0xffff0000l) >> (16 - 5)) | (1 << 21));
 	}
 
-	/* A large amount of number can be constructed from ORR and MOVx,
-	but computing them is costly. We don't  */
+	/* A large amount of number can be constructed from ORR and MOVx, but computing them is costly. */
 
 	zeros = 0;
 	ones = 0;
@@ -501,9 +545,6 @@
 #define INT_OP		0x0040000
 #define SET_FLAGS	0x0080000
 #define UNUSED_RETURN	0x0100000
-#define SLOW_DEST	0x0200000
-#define SLOW_SRC1	0x0400000
-#define SLOW_SRC2	0x0800000
 
 #define CHECK_FLAGS(flag_bits) \
 	if (flags & SET_FLAGS) { \
@@ -635,7 +676,7 @@
 			}
 			goto set_flags;
 		default:
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 			break;
 		}
 
@@ -661,40 +702,32 @@
 	switch (op) {
 	case SLJIT_MOV:
 	case SLJIT_MOV_P:
-	case SLJIT_MOVU:
-	case SLJIT_MOVU_P:
 		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 		if (dst == arg2)
 			return SLJIT_SUCCESS;
 		return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2));
 	case SLJIT_MOV_U8:
-	case SLJIT_MOVU_U8:
 		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 		return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10));
 	case SLJIT_MOV_S8:
-	case SLJIT_MOVU_S8:
 		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 		if (!(flags & INT_OP))
 			inv_bits |= 1 << 22;
 		return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));
 	case SLJIT_MOV_U16:
-	case SLJIT_MOVU_U16:
 		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 		return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10));
 	case SLJIT_MOV_S16:
-	case SLJIT_MOVU_S16:
 		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 		if (!(flags & INT_OP))
 			inv_bits |= 1 << 22;
 		return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));
 	case SLJIT_MOV_U32:
-	case SLJIT_MOVU_U32:
 		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 		if ((flags & INT_OP) && dst == arg2)
 			return SLJIT_SUCCESS;
 		return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
 	case SLJIT_MOV_S32:
-	case SLJIT_MOVU_S32:
 		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
 		if ((flags & INT_OP) && dst == arg2)
 			return SLJIT_SUCCESS;
@@ -702,7 +735,7 @@
 	case SLJIT_NOT:
 		SLJIT_ASSERT(arg1 == TMP_REG1);
 		FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2)));
-		goto set_flags;
+		break; /* Set flags. */
 	case SLJIT_NEG:
 		SLJIT_ASSERT(arg1 == TMP_REG1);
 		if (flags & SET_FLAGS)
@@ -710,8 +743,7 @@
 		return push_inst(compiler, (SUB ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
 	case SLJIT_CLZ:
 		SLJIT_ASSERT(arg1 == TMP_REG1);
-		FAIL_IF(push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2)));
-		goto set_flags;
+		return push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2));
 	case SLJIT_ADD:
 		CHECK_FLAGS(1 << 29);
 		return push_inst(compiler, (ADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
@@ -740,320 +772,91 @@
 		return push_inst(compiler, (AND ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
 	case SLJIT_OR:
 		FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
-		goto set_flags;
+		break; /* Set flags. */
 	case SLJIT_XOR:
 		FAIL_IF(push_inst(compiler, (EOR ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
-		goto set_flags;
+		break; /* Set flags. */
 	case SLJIT_SHL:
 		FAIL_IF(push_inst(compiler, (LSLV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
-		goto set_flags;
+		break; /* Set flags. */
 	case SLJIT_LSHR:
 		FAIL_IF(push_inst(compiler, (LSRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
-		goto set_flags;
+		break; /* Set flags. */
 	case SLJIT_ASHR:
 		FAIL_IF(push_inst(compiler, (ASRV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2)));
-		goto set_flags;
+		break; /* Set flags. */
+	default:
+		SLJIT_UNREACHABLE();
+		return SLJIT_SUCCESS;
 	}
 
-	SLJIT_ASSERT_STOP();
-	return SLJIT_SUCCESS;
-
 set_flags:
 	if (flags & SET_FLAGS)
 		return push_inst(compiler, (SUBS ^ inv_bits) | RD(TMP_ZERO) | RN(dst) | RM(TMP_ZERO));
 	return SLJIT_SUCCESS;
 }
 
-#define STORE		0x01
-#define SIGNED		0x02
+#define STORE		0x10
+#define SIGNED		0x20
 
-#define UPDATE		0x04
-#define ARG_TEST	0x08
+#define BYTE_SIZE	0x0
+#define HALF_SIZE	0x1
+#define INT_SIZE	0x2
+#define WORD_SIZE	0x3
 
-#define BYTE_SIZE	0x000
-#define HALF_SIZE	0x100
-#define INT_SIZE	0x200
-#define WORD_SIZE	0x300
+#define MEM_SIZE_SHIFT(flags) ((flags) & 0x3)
 
-#define MEM_SIZE_SHIFT(flags) ((flags) >> 8)
-
-static const sljit_ins sljit_mem_imm[4] = {
-/* u l */ 0x39400000 /* ldrb [reg,imm] */,
-/* u s */ 0x39000000 /* strb [reg,imm] */,
-/* s l */ 0x39800000 /* ldrsb [reg,imm] */,
-/* s s */ 0x39000000 /* strb [reg,imm] */,
-};
-
-static const sljit_ins sljit_mem_simm[4] = {
-/* u l */ 0x38400000 /* ldurb [reg,imm] */,
-/* u s */ 0x38000000 /* sturb [reg,imm] */,
-/* s l */ 0x38800000 /* ldursb [reg,imm] */,
-/* s s */ 0x38000000 /* sturb [reg,imm] */,
-};
-
-static const sljit_ins sljit_mem_pre_simm[4] = {
-/* u l */ 0x38400c00 /* ldrb [reg,imm]! */,
-/* u s */ 0x38000c00 /* strb [reg,imm]! */,
-/* s l */ 0x38800c00 /* ldrsb [reg,imm]! */,
-/* s s */ 0x38000c00 /* strb [reg,imm]! */,
-};
-
-static const sljit_ins sljit_mem_reg[4] = {
-/* u l */ 0x38606800 /* ldrb [reg,reg] */,
-/* u s */ 0x38206800 /* strb [reg,reg] */,
-/* s l */ 0x38a06800 /* ldrsb [reg,reg] */,
-/* s s */ 0x38206800 /* strb [reg,reg] */,
-};
-
-/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
-static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
-{
-	if (value >= 0) {
-		if (value <= 0xfff)
-			return push_inst(compiler, ADDI | RD(dst) | RN(reg) | (value << 10));
-		if (value <= 0xffffff && !(value & 0xfff))
-			return push_inst(compiler, ADDI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
-	}
-	else {
-		value = -value;
-		if (value <= 0xfff)
-			return push_inst(compiler, SUBI | RD(dst) | RN(reg) | (value << 10));
-		if (value <= 0xffffff && !(value & 0xfff))
-			return push_inst(compiler, SUBI | (1 << 22) | RD(dst) | RN(reg) | (value >> 2));
-	}
-	return SLJIT_ERR_UNSUPPORTED;
-}
-
-/* Can perform an operation using at most 1 instruction. */
-static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
+	sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
 {
 	sljit_u32 shift = MEM_SIZE_SHIFT(flags);
+	sljit_u32 type = (shift << 30);
+
+	if (!(flags & STORE))
+		type |= (flags & SIGNED) ? 0x00800000 : 0x00400000;
 
 	SLJIT_ASSERT(arg & SLJIT_MEM);
 
-	if (SLJIT_UNLIKELY(flags & UPDATE)) {
-		if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 255 && argw >= -256) {
-			if (SLJIT_UNLIKELY(flags & ARG_TEST))
-				return 1;
-
-			arg &= REG_MASK;
-			argw &= 0x1ff;
-			FAIL_IF(push_inst(compiler, sljit_mem_pre_simm[flags & 0x3]
-				| (shift << 30) | RT(reg) | RN(arg) | (argw << 12)));
-			return -1;
-		}
-		return 0;
-	}
-
 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
 		argw &= 0x3;
-		if (argw && argw != shift)
-			return 0;
 
-		if (SLJIT_UNLIKELY(flags & ARG_TEST))
-			return 1;
+		if (argw == 0 || argw == shift)
+			return push_inst(compiler, STRB | type | RT(reg)
+				| RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
 
-		FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg)
-			| RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0)));
-		return -1;
+		FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw << 10)));
+		return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg));
 	}
 
 	arg &= REG_MASK;
-	if (argw >= 0 && (argw >> shift) <= 0xfff && (argw & ((1 << shift) - 1)) == 0) {
-		if (SLJIT_UNLIKELY(flags & ARG_TEST))
-			return 1;
 
-		FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
-			| RT(reg) | RN(arg) | (argw << (10 - shift))));
-		return -1;
+	if (arg == SLJIT_UNUSED) {
+		FAIL_IF(load_immediate(compiler, tmp_reg, argw & ~(0xfff << shift)));
+
+		argw = (argw >> shift) & 0xfff;
+
+		return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | (argw << 10));
 	}
 
-	if (argw > 255 || argw < -256)
-		return 0;
-
-	if (SLJIT_UNLIKELY(flags & ARG_TEST))
-		return 1;
-
-	FAIL_IF(push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
-		| RT(reg) | RN(arg) | ((argw & 0x1ff) << 12)));
-	return -1;
-}
-
-/* see getput_arg below.
-   Note: can_cache is called only for binary operators. Those
-   operators always uses word arguments without write back. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	sljit_sw diff;
-	if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
-		return 0;
-
-	if (!(arg & REG_MASK)) {
-		diff = argw - next_argw;
-		if (diff <= 0xfff && diff >= -0xfff)
-			return 1;
-		return 0;
-	}
-
-	if (argw == next_argw)
-		return 1;
-
-	diff = argw - next_argw;
-	if (arg == next_arg && diff <= 0xfff && diff >= -0xfff)
-		return 1;
-
-	return 0;
-}
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
-	sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	sljit_u32 shift = MEM_SIZE_SHIFT(flags);
-	sljit_s32 tmp_r, other_r;
-	sljit_sw diff;
-
-	SLJIT_ASSERT(arg & SLJIT_MEM);
-	if (!(next_arg & SLJIT_MEM)) {
-		next_arg = 0;
-		next_argw = 0;
-	}
-
-	tmp_r = (flags & STORE) ? TMP_REG3 : reg;
-
-	if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) {
-		/* Update only applies if a base register exists. */
-		other_r = OFFS_REG(arg);
-		if (!other_r) {
-			other_r = arg & REG_MASK;
-			if (other_r != reg && argw >= 0 && argw <= 0xffffff) {
-				if ((argw & 0xfff) != 0)
-					FAIL_IF(push_inst(compiler, ADDI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
-				if (argw >> 12)
-					FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
-				return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
-			}
-			else if (other_r != reg && argw < 0 && argw >= -0xffffff) {
-				argw = -argw;
-				if ((argw & 0xfff) != 0)
-					FAIL_IF(push_inst(compiler, SUBI | RD(other_r) | RN(other_r) | ((argw & 0xfff) << 10)));
-				if (argw >> 12)
-					FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(other_r) | RN(other_r) | ((argw >> 12) << 10)));
-				return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(other_r));
-			}
-
-			if (compiler->cache_arg == SLJIT_MEM) {
-				if (argw == compiler->cache_argw) {
-					other_r = TMP_REG3;
-					argw = 0;
-				}
-				else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
-					FAIL_IF(compiler->error);
-					compiler->cache_argw = argw;
-					other_r = TMP_REG3;
-					argw = 0;
-				}
-			}
-
-			if (argw) {
-				FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-				compiler->cache_arg = SLJIT_MEM;
-				compiler->cache_argw = argw;
-				other_r = TMP_REG3;
-				argw = 0;
-			}
+	if (argw >= 0 && (argw & ((1 << shift) - 1)) == 0) {
+		if ((argw >> shift) <= 0xfff) {
+			return push_inst(compiler, STRBI | type | RT(reg) | RN(arg) | (argw << (10 - shift)));
 		}
 
-		/* No caching here. */
-		arg &= REG_MASK;
-		argw &= 0x3;
-		if (!argw || argw == shift) {
-			FAIL_IF(push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(other_r) | (argw ? (1 << 12) : 0)));
-			return push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10));
-		}
-		if (arg != reg) {
-			FAIL_IF(push_inst(compiler, ADD | RD(arg) | RN(arg) | RM(other_r) | (argw << 10)));
-			return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
-		}
-		FAIL_IF(push_inst(compiler, ADD | RD(TMP_LR) | RN(arg) | RM(other_r) | (argw << 10)));
-		FAIL_IF(push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_LR)));
-		return push_inst(compiler, ORR | RD(arg) | RN(TMP_ZERO) | RM(TMP_LR));
-	}
+		if (argw <= 0xffffff) {
+			FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_reg) | RN(arg) | ((argw >> 12) << 10)));
 
-	if (arg & OFFS_REG_MASK) {
-		other_r = OFFS_REG(arg);
-		arg &= REG_MASK;
-		FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RN(arg) | RM(other_r) | ((argw & 0x3) << 10)));
-		return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(tmp_r));
-	}
-
-	if (compiler->cache_arg == arg) {
-		diff = argw - compiler->cache_argw;
-		if (diff <= 255 && diff >= -256)
-			return push_inst(compiler, sljit_mem_simm[flags & 0x3] | (shift << 30)
-				| RT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
-		if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg));
+			argw = ((argw & 0xfff) >> shift);
+			return push_inst(compiler, STRBI | type | RT(reg) | RN(tmp_reg) | (argw << 10));
 		}
 	}
 
-	if (argw >= 0 && argw <= 0xffffff && (argw & ((1 << shift) - 1)) == 0) {
-		FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_r) | RN(arg & REG_MASK) | ((argw >> 12) << 10)));
-		return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30)
-			| RT(reg) | RN(tmp_r) | ((argw & 0xfff) << (10 - shift)));
-	}
+	if (argw <= 255 && argw >= -256)
+		return push_inst(compiler, STURBI | type | RT(reg) | RN(arg) | ((argw & 0x1ff) << 12));
 
-	diff = argw - next_argw;
-	next_arg = (arg & REG_MASK) && (arg == next_arg) && diff <= 0xfff && diff >= -0xfff && diff != 0;
-	arg &= REG_MASK;
+	FAIL_IF(load_immediate(compiler, tmp_reg, argw));
 
-	if (arg && compiler->cache_arg == SLJIT_MEM) {
-		if (compiler->cache_argw == argw)
-			return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
-		if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			compiler->cache_argw = argw;
-			return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
-		}
-	}
-
-	compiler->cache_argw = argw;
-	if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
-		FAIL_IF(compiler->error);
-		compiler->cache_arg = SLJIT_MEM | arg;
-		arg = 0;
-	}
-	else {
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-		compiler->cache_arg = SLJIT_MEM;
-
-		if (next_arg) {
-			FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG3) | RN(TMP_REG3) | RM(arg)));
-			compiler->cache_arg = SLJIT_MEM | arg;
-			arg = 0;
-		}
-	}
-
-	if (arg)
-		return push_inst(compiler, sljit_mem_reg[flags & 0x3] | (shift << 30) | RT(reg) | RN(arg) | RM(TMP_REG3));
-	return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3));
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
-	if (getput_arg_fast(compiler, flags, reg, arg, argw))
-		return compiler->error;
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
-	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
-		return compiler->error;
-	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+	return push_inst(compiler, STRB | type | RT(reg) | RN(arg) | RM(tmp_reg));
 }
 
 /* --------------------------------------------------------------------- */
@@ -1061,14 +864,14 @@
 /* --------------------------------------------------------------------- */
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 i, tmp, offs, prev, saved_regs_size;
+	sljit_s32 args, i, tmp, offs, prev, saved_regs_size;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0);
 	local_size += saved_regs_size + SLJIT_LOCALS_OFFSET;
@@ -1138,6 +941,8 @@
 		FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
 	}
 
+	args = get_arg_count(arg_types);
+
 	if (args >= 1)
 		FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0) | RN(TMP_ZERO) | RM(SLJIT_R0)));
 	if (args >= 2)
@@ -1149,12 +954,12 @@
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET;
 	local_size = (local_size + 15) & ~0xf;
@@ -1287,112 +1092,87 @@
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
+		if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) {
+			SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);
+
+			if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8)
+				dst = 5;
+			else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16)
+				dst = 3;
+			else
+				dst = 1;
+
+			/* Signed word sized load is the prefetch instruction. */
+			return emit_op_mem(compiler, WORD_SIZE | SIGNED, dst, src, srcw, TMP_REG1);
+		}
+		return SLJIT_SUCCESS;
+	}
 
 	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
 
 	op = GET_OPCODE(op);
-	if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
+	if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
+		/* Both operands are registers. */
+		if (dst_r != TMP_REG1 && FAST_IS_REG(src))
+			return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
+
 		switch (op) {
 		case SLJIT_MOV:
 		case SLJIT_MOV_P:
-			flags = WORD_SIZE;
+			mem_flags = WORD_SIZE;
 			break;
 		case SLJIT_MOV_U8:
-			flags = BYTE_SIZE;
+			mem_flags = BYTE_SIZE;
 			if (src & SLJIT_IMM)
 				srcw = (sljit_u8)srcw;
 			break;
 		case SLJIT_MOV_S8:
-			flags = BYTE_SIZE | SIGNED;
+			mem_flags = BYTE_SIZE | SIGNED;
 			if (src & SLJIT_IMM)
 				srcw = (sljit_s8)srcw;
 			break;
 		case SLJIT_MOV_U16:
-			flags = HALF_SIZE;
+			mem_flags = HALF_SIZE;
 			if (src & SLJIT_IMM)
 				srcw = (sljit_u16)srcw;
 			break;
 		case SLJIT_MOV_S16:
-			flags = HALF_SIZE | SIGNED;
+			mem_flags = HALF_SIZE | SIGNED;
 			if (src & SLJIT_IMM)
 				srcw = (sljit_s16)srcw;
 			break;
 		case SLJIT_MOV_U32:
-			flags = INT_SIZE;
+			mem_flags = INT_SIZE;
 			if (src & SLJIT_IMM)
 				srcw = (sljit_u32)srcw;
 			break;
 		case SLJIT_MOV_S32:
-			flags = INT_SIZE | SIGNED;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_s32)srcw;
-			break;
-		case SLJIT_MOVU:
-		case SLJIT_MOVU_P:
-			flags = WORD_SIZE | UPDATE;
-			break;
-		case SLJIT_MOVU_U8:
-			flags = BYTE_SIZE | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_u8)srcw;
-			break;
-		case SLJIT_MOVU_S8:
-			flags = BYTE_SIZE | SIGNED | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_s8)srcw;
-			break;
-		case SLJIT_MOVU_U16:
-			flags = HALF_SIZE | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_u16)srcw;
-			break;
-		case SLJIT_MOVU_S16:
-			flags = HALF_SIZE | SIGNED | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_s16)srcw;
-			break;
-		case SLJIT_MOVU_U32:
-			flags = INT_SIZE | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_u32)srcw;
-			break;
-		case SLJIT_MOVU_S32:
-			flags = INT_SIZE | SIGNED | UPDATE;
+			mem_flags = INT_SIZE | SIGNED;
 			if (src & SLJIT_IMM)
 				srcw = (sljit_s32)srcw;
 			break;
 		default:
-			SLJIT_ASSERT_STOP();
-			flags = 0;
+			SLJIT_UNREACHABLE();
+			mem_flags = 0;
 			break;
 		}
 
 		if (src & SLJIT_IMM)
 			FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
-		else if (src & SLJIT_MEM) {
-			if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
-				FAIL_IF(compiler->error);
-			else
-				FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
-		} else {
-			if (dst_r != TMP_REG1)
-				return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
+		else if (!(src & SLJIT_MEM))
 			dst_r = src;
-		}
+		else
+			FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, src, srcw, TMP_REG1));
 
-		if (dst & SLJIT_MEM) {
-			if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
-				return compiler->error;
-			else
-				return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
-		}
+		if (dst & SLJIT_MEM)
+			return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);
 		return SLJIT_SUCCESS;
 	}
 
-	flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0;
+	flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;
 	mem_flags = WORD_SIZE;
+
 	if (op_flags & SLJIT_I32_OP) {
 		flags |= INT_OP;
 		mem_flags = INT_SIZE;
@@ -1402,28 +1182,14 @@
 		flags |= UNUSED_RETURN;
 
 	if (src & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw))
-			FAIL_IF(compiler->error);
-		else
-			FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw));
+		FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, src, srcw, TMP_REG2));
 		src = TMP_REG2;
 	}
 
-	if (src & SLJIT_IMM) {
-		flags |= ARG2_IMM;
-		if (op_flags & SLJIT_I32_OP)
-			srcw = (sljit_s32)srcw;
-	} else
-		srcw = src;
+	emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, src);
 
-	emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw);
-
-	if (dst & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw))
-			return compiler->error;
-		else
-			return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0);
-	}
+	if (SLJIT_UNLIKELY(dst & SLJIT_MEM))
+		return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);
 	return SLJIT_SUCCESS;
 }
 
@@ -1440,12 +1206,13 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
 
 	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
-	flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+	flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 	mem_flags = WORD_SIZE;
+
 	if (op & SLJIT_I32_OP) {
 		flags |= INT_OP;
 		mem_flags = INT_SIZE;
@@ -1454,46 +1221,21 @@
 	if (dst == SLJIT_UNUSED)
 		flags |= UNUSED_RETURN;
 
-	if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, mem_flags | STORE | ARG_TEST, TMP_REG1, dst, dstw))
-		flags |= SLOW_DEST;
-
 	if (src1 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, mem_flags, TMP_REG1, src1, src1w))
-			FAIL_IF(compiler->error);
-		else
-			flags |= SLOW_SRC1;
-	}
-	if (src2 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src2, src2w))
-			FAIL_IF(compiler->error);
-		else
-			flags |= SLOW_SRC2;
-	}
-
-	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
-		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
-			FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, src1, src1w));
-			FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
-		}
-		else {
-			FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, src2, src2w));
-			FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
-		}
-	}
-	else if (flags & SLOW_SRC1)
-		FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG1, src1, src1w, dst, dstw));
-	else if (flags & SLOW_SRC2)
-		FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src2, src2w, dst, dstw));
-
-	if (src1 & SLJIT_MEM)
+		FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG1, src1, src1w, TMP_REG1));
 		src1 = TMP_REG1;
-	if (src2 & SLJIT_MEM)
+	}
+
+	if (src2 & SLJIT_MEM) {
+		FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, src2, src2w, TMP_REG2));
 		src2 = TMP_REG2;
+	}
 
 	if (src1 & SLJIT_IMM)
 		flags |= ARG1_IMM;
 	else
 		src1w = src1;
+
 	if (src2 & SLJIT_IMM)
 		flags |= ARG2_IMM;
 	else
@@ -1501,14 +1243,8 @@
 
 	emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
 
-	if (dst & SLJIT_MEM) {
-		if (!(flags & SLOW_DEST)) {
-			getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw);
-			return compiler->error;
-		}
-		return getput_arg(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
-	}
-
+	if (dst & SLJIT_MEM)
+		return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);
 	return SLJIT_SUCCESS;
 }
 
@@ -1521,7 +1257,7 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
 {
 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
-	return reg;
+	return freg_map[reg];
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
@@ -1537,74 +1273,60 @@
 /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-#ifdef SLJIT_IS_FPU_AVAILABLE
-	return SLJIT_IS_FPU_AVAILABLE;
-#else
-	/* Available by default. */
-	return 1;
-#endif
-}
-
 static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
 {
 	sljit_u32 shift = MEM_SIZE_SHIFT(flags);
-	sljit_ins ins_bits = (shift << 30);
-	sljit_s32 other_r;
-	sljit_sw diff;
+	sljit_ins type = (shift << 30);
 
 	SLJIT_ASSERT(arg & SLJIT_MEM);
 
 	if (!(flags & STORE))
-		ins_bits |= 1 << 22;
+		type |= 0x00400000;
 
 	if (arg & OFFS_REG_MASK) {
 		argw &= 3;
-		if (!argw || argw == shift)
-			return push_inst(compiler, STR_FR | ins_bits | VT(reg)
+		if (argw == 0 || argw == shift)
+			return push_inst(compiler, STR_FR | type | VT(reg)
 				| RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
-		other_r = OFFS_REG(arg);
-		arg &= REG_MASK;
-		FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg) | RM(other_r) | (argw << 10)));
-		arg = TMP_REG1;
-		argw = 0;
+
+		FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw << 10)));
+		return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1));
 	}
 
 	arg &= REG_MASK;
-	if (arg && argw >= 0 && ((argw >> shift) <= 0xfff) && (argw & ((1 << shift) - 1)) == 0)
-		return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(arg) | (argw << (10 - shift)));
 
-	if (arg && argw <= 255 && argw >= -256)
-		return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12));
+	if (arg == SLJIT_UNUSED) {
+		FAIL_IF(load_immediate(compiler, TMP_REG1, argw & ~(0xfff << shift)));
 
-	/* Slow cases */
-	if (compiler->cache_arg == SLJIT_MEM && argw != compiler->cache_argw) {
-		diff = argw - compiler->cache_argw;
-		if (!arg && diff <= 255 && diff >= -256)
-			return push_inst(compiler, STUR_FI | ins_bits | VT(reg) | RN(TMP_REG3) | ((diff & 0x1ff) << 12));
-		if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			compiler->cache_argw = argw;
+		argw = (argw >> shift) & 0xfff;
+
+		return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1) | (argw << 10));
+	}
+
+	if (argw >= 0 && (argw & ((1 << shift) - 1)) == 0) {
+		if ((argw >> shift) <= 0xfff)
+			return push_inst(compiler, STR_FI | type | VT(reg) | RN(arg) | (argw << (10 - shift)));
+
+		if (argw <= 0xffffff) {
+			FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(TMP_REG1) | RN(arg) | ((argw >> 12) << 10)));
+
+			argw = ((argw & 0xfff) >> shift);
+			return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1) | (argw << 10));
 		}
 	}
 
-	if (compiler->cache_arg != SLJIT_MEM || argw != compiler->cache_argw) {
-		compiler->cache_arg = SLJIT_MEM;
-		compiler->cache_argw = argw;
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-	}
+	if (argw <= 255 && argw >= -256)
+		return push_inst(compiler, STUR_FI | type | VT(reg) | RN(arg) | ((argw & 0x1ff) << 12));
 
-	if (arg & REG_MASK)
-		return push_inst(compiler, STR_FR | ins_bits | VT(reg) | RN(arg) | RM(TMP_REG3));
-	return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3));
+	FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
+	return push_inst(compiler, STR_FR | type | VT(reg) | RN(arg) | RM(TMP_REG1));
 }
 
 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
-	sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
 	sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
 
 	if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64)
@@ -1617,8 +1339,8 @@
 
 	FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));
 
-	if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
-		return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw);
+	if (dst & SLJIT_MEM)
+		return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw, TMP_REG2);
 	return SLJIT_SUCCESS;
 }
 
@@ -1633,7 +1355,7 @@
 		inv_bits |= (1 << 31);
 
 	if (src & SLJIT_MEM) {
-		emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw);
+		emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw, TMP_REG1);
 		src = TMP_REG1;
 	} else if (src & SLJIT_IMM) {
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -1679,17 +1401,15 @@
 	sljit_ins inv_bits;
 
 	CHECK_ERROR();
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
 
-	SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference);
+	SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x1) == WORD_SIZE, must_be_one_bit_difference);
 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
 
 	inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
 	if (src & SLJIT_MEM) {
-		emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw);
+		emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x1) : mem_flags, dst_r, src, srcw);
 		src = dst_r;
 	}
 
@@ -1732,9 +1452,6 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 	if (src1 & SLJIT_MEM) {
 		emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
@@ -1775,15 +1492,11 @@
 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	/* For UNUSED dst. Uncommon, but possible. */
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (FAST_IS_REG(dst))
 		return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR));
 
 	/* Memory. */
-	return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw);
+	return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw, TMP_REG1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
@@ -1794,10 +1507,8 @@
 
 	if (FAST_IS_REG(src))
 		FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
-	else if (src & SLJIT_MEM)
-		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw));
-	else if (src & SLJIT_IMM)
-		FAIL_IF(load_immediate(compiler, TMP_LR, srcw));
+	else
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));
 
 	return push_inst(compiler, RET | RN(TMP_LR));
 }
@@ -1856,7 +1567,7 @@
 		return 0x6;
 
 	default:
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 		return 0xe;
 	}
 }
@@ -1903,6 +1614,20 @@
 	return jump;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_jump(compiler, type);
+}
+
 static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type,
 	sljit_s32 src, sljit_sw srcw)
 {
@@ -1918,13 +1643,14 @@
 	jump->flags |= IS_CBZ | IS_COND;
 
 	if (src & SLJIT_MEM) {
-		PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw));
+		PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
 		src = TMP_REG1;
 	}
 	else if (src & SLJIT_IMM) {
 		PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
 		src = TMP_REG1;
 	}
+
 	SLJIT_ASSERT(FAST_IS_REG(src));
 
 	if ((type & 0xff) == SLJIT_EQUAL)
@@ -1945,15 +1671,15 @@
 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-	/* In ARM, we don't need to touch the arguments. */
 	if (!(src & SLJIT_IMM)) {
 		if (src & SLJIT_MEM) {
-			FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw));
+			FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
 			src = TMP_REG1;
 		}
 		return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src));
 	}
 
+	/* These jumps are converted to jump/call instructions when possible. */
 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 	FAIL_IF(!jump);
 	set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
@@ -1964,54 +1690,170 @@
 	return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1));
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_ijump(compiler, type, src, srcw);
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
-	sljit_s32 dst_r, flags, mem_flags;
+	sljit_s32 dst_r, src_r, flags, mem_flags;
 	sljit_ins cc;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
-	ADJUST_LOCAL_OFFSET(src, srcw);
-
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
 
 	cc = get_cc(type & 0xff);
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
 
 	if (GET_OPCODE(op) < SLJIT_ADD) {
 		FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));
-		if (dst_r != TMP_REG1)
-			return SLJIT_SUCCESS;
-		return emit_op_mem(compiler, (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE, TMP_REG1, dst, dstw);
+
+		if (dst_r == TMP_REG1) {
+			mem_flags = (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE;
+			return emit_op_mem(compiler, mem_flags, TMP_REG1, dst, dstw, TMP_REG2);
+		}
+
+		return SLJIT_SUCCESS;
 	}
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+	flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 	mem_flags = WORD_SIZE;
+
 	if (op & SLJIT_I32_OP) {
 		flags |= INT_OP;
 		mem_flags = INT_SIZE;
 	}
 
-	if (src & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, mem_flags, TMP_REG1, src, srcw, dst, dstw));
-		src = TMP_REG1;
-		srcw = 0;
-	} else if (src & SLJIT_IMM)
-		flags |= ARG1_IMM;
+	src_r = dst;
+
+	if (dst & SLJIT_MEM) {
+		FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG1, dst, dstw, TMP_REG1));
+		src_r = TMP_REG1;
+	}
 
 	FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(TMP_ZERO)));
-	emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src, TMP_REG2);
+	emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src_r, TMP_REG2);
 
-	if (dst_r != TMP_REG1)
+	if (dst & SLJIT_MEM)
+		return emit_op_mem(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, TMP_REG2);
+	return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_ins inv_bits = (dst_reg & SLJIT_I32_OP) ? (1 << 31) : 0;
+	sljit_ins cc;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+		if (dst_reg & SLJIT_I32_OP)
+			srcw = (sljit_s32)srcw;
+		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+		src = TMP_REG1;
+		srcw = 0;
+	}
+
+	cc = get_cc(type & 0xff);
+	dst_reg &= ~SLJIT_I32_OP;
+
+	return push_inst(compiler, (CSEL ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(dst_reg) | RM(src));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 reg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	sljit_u32 sign = 0, inst;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
+
+	if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
+		return SLJIT_ERR_UNSUPPORTED;
+
+	if (type & SLJIT_MEM_SUPP)
 		return SLJIT_SUCCESS;
-	return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
+
+	switch (type & 0xff) {
+	case SLJIT_MOV:
+	case SLJIT_MOV_P:
+		inst = STURBI | (MEM_SIZE_SHIFT(WORD_SIZE) << 30) | 0x400;
+		break;
+	case SLJIT_MOV_S8:
+		sign = 1;
+	case SLJIT_MOV_U8:
+		inst = STURBI | (MEM_SIZE_SHIFT(BYTE_SIZE) << 30) | 0x400;
+		break;
+	case SLJIT_MOV_S16:
+		sign = 1;
+	case SLJIT_MOV_U16:
+		inst = STURBI | (MEM_SIZE_SHIFT(HALF_SIZE) << 30) | 0x400;
+		break;
+	case SLJIT_MOV_S32:
+		sign = 1;
+	case SLJIT_MOV_U32:
+		inst = STURBI | (MEM_SIZE_SHIFT(INT_SIZE) << 30) | 0x400;
+		break;
+	default:
+		SLJIT_UNREACHABLE();
+		inst = STURBI | (MEM_SIZE_SHIFT(WORD_SIZE) << 30) | 0x400;
+		break;
+	}
+
+	if (!(type & SLJIT_MEM_STORE))
+		inst |= sign ? 0x00800000 : 0x00400000;
+
+	if (type & SLJIT_MEM_PRE)
+		inst |= 0x800;
+
+	return push_inst(compiler, inst | RT(reg) | RN(mem & REG_MASK) | ((memw & 0x1ff) << 12));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 freg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	sljit_u32 inst;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
+
+	if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
+		return SLJIT_ERR_UNSUPPORTED;
+
+	if (type & SLJIT_MEM_SUPP)
+		return SLJIT_SUCCESS;
+
+	inst = STUR_FI | 0x80000400;
+
+	if (!(type & SLJIT_F32_OP))
+		inst |= 0x40000000;
+
+	if (!(type & SLJIT_MEM_STORE))
+		inst |= 0x00400000;
+
+	if (type & SLJIT_MEM_PRE)
+		inst |= 0x800;
+
+	return push_inst(compiler, inst | VT(freg) | RN(mem & REG_MASK) | ((memw & 0x1ff) << 12));
 }
 
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
@@ -2027,24 +1869,26 @@
 	PTR_FAIL_IF(!const_);
 	set_const(const_, compiler);
 
-	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
 	PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, init_value));
 
 	if (dst & SLJIT_MEM)
-		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
 	return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
 	sljit_ins* inst = (sljit_ins*)addr;
-	modify_imm64_const(inst, new_addr);
+	modify_imm64_const(inst, new_target);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 4);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
 	sljit_ins* inst = (sljit_ins*)addr;
 	modify_imm64_const(inst, new_constant);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 4);
 }
diff --git a/dist2/src/sljit/sljitNativeARM_T2_32.c b/dist2/src/sljit/sljitNativeARM_T2_32.c
index 1ed44a8..75e7a38 100644
--- a/dist2/src/sljit/sljitNativeARM_T2_32.c
+++ b/dist2/src/sljit/sljitNativeARM_T2_32.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -26,7 +26,11 @@
 
 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
 {
-	return "ARM-Thumb2" SLJIT_CPUINFO;
+#ifdef __SOFTFP__
+	return "ARM-Thumb2" SLJIT_CPUINFO " ABI:softfp";
+#else
+	return "ARM-Thumb2" SLJIT_CPUINFO " ABI:hardfp";
+#endif
 }
 
 /* Length of an instruction word. */
@@ -35,15 +39,18 @@
 /* Last register + 1. */
 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
-#define TMP_PC		(SLJIT_NUMBER_OF_REGISTERS + 5)
+#define TMP_PC		(SLJIT_NUMBER_OF_REGISTERS + 4)
 
-#define TMP_FREG1	(0)
-#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
 
 /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
-	0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
+	0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15
+};
+
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
+	0, 0, 1, 2, 3, 4, 5, 6, 7
 };
 
 #define COPY_BITS(src, from, to, bits) \
@@ -70,9 +77,9 @@
 #define RN4(rn) (reg_map[rn] << 16)
 #define RM4(rm) (reg_map[rm])
 #define RT4(rt) (reg_map[rt] << 12)
-#define DD4(dd) ((dd) << 12)
-#define DN4(dn) ((dn) << 16)
-#define DM4(dm) (dm)
+#define DD4(dd) (freg_map[dd] << 12)
+#define DN4(dn) (freg_map[dn] << 16)
+#define DM4(dm) (freg_map[dm])
 #define IMM5(imm) \
 	(COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6))
 #define IMM12(imm) \
@@ -108,7 +115,11 @@
 #define BLX		0x4780
 #define BX		0x4700
 #define CLZ		0xfab0f080
+#define CMNI_W		0xf1100f00
+#define CMP		0x4280
 #define CMPI		0x2800
+#define CMPI_W		0xf1b00f00
+#define CMP_X		0x4500
 #define CMP_W		0xebb00f00
 #define EORI		0xf0800000
 #define EORS		0x4040
@@ -175,6 +186,7 @@
 #define VDIV_F32	0xee800a00
 #define VMOV_F32	0xeeb00a40
 #define VMOV		0xee000a10
+#define VMOV2		0xec400a10
 #define VMRS		0xeef1fa10
 #define VMUL_F32	0xee200a00
 #define VNEG_F32	0xeeb10a40
@@ -205,10 +217,10 @@
 
 static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
 {
-	FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
-		COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
-	return push_inst32(compiler, MOVT | RD4(dst) |
-		COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+	FAIL_IF(push_inst32(compiler, MOVW | RD4(dst)
+		| COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+	return push_inst32(compiler, MOVT | RD4(dst)
+		| COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
 }
 
 static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
@@ -221,7 +233,7 @@
 	inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16);
 }
 
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code)
+static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
 {
 	sljit_sw diff;
 
@@ -232,7 +244,7 @@
 		/* Branch to ARM code is not optimized yet. */
 		if (!(jump->u.target & 0x1))
 			return 0;
-		diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1;
+		diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset) >> 1;
 	}
 	else {
 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
@@ -276,7 +288,7 @@
 	return 0;
 }
 
-static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
+static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset)
 {
 	sljit_s32 type = (jump->flags >> 4) & 0xf;
 	sljit_sw diff;
@@ -290,10 +302,12 @@
 
 	if (jump->flags & JUMP_ADDR) {
 		SLJIT_ASSERT(jump->u.target & 0x1);
-		diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1;
+		diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
 	}
-	else
-		diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1;
+	else {
+		SLJIT_ASSERT(jump->u.label->addr & 0x1);
+		diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
+	}
 	jump_inst = (sljit_u16*)jump->addr;
 
 	switch (type) {
@@ -336,7 +350,7 @@
 	else if (type == 6) /* Encoding T1 of 'BL' instruction */
 		jump_inst[1] |= 0xd000;
 	else
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
@@ -347,6 +361,7 @@
 	sljit_u16 *buf_ptr;
 	sljit_u16 *buf_end;
 	sljit_uw half_count;
+	sljit_sw executable_offset;
 
 	struct sljit_label *label;
 	struct sljit_jump *jump;
@@ -362,6 +377,8 @@
 
 	code_ptr = code;
 	half_count = 0;
+	executable_offset = SLJIT_EXEC_OFFSET(code);
+
 	label = compiler->labels;
 	jump = compiler->jumps;
 	const_ = compiler->consts;
@@ -376,13 +393,13 @@
 			SLJIT_ASSERT(!jump || jump->addr >= half_count);
 			SLJIT_ASSERT(!const_ || const_->addr >= half_count);
 			if (label && label->size == half_count) {
-				label->addr = ((sljit_uw)code_ptr) | 0x1;
+				label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
 				label->size = code_ptr - code;
 				label = label->next;
 			}
 			if (jump && jump->addr == half_count) {
 					jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
-					code_ptr -= detect_jump_type(jump, code_ptr, code);
+					code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
 					jump = jump->next;
 			}
 			if (const_ && const_->addr == half_count) {
@@ -397,7 +414,7 @@
 	} while (buf);
 
 	if (label && label->size == half_count) {
-		label->addr = ((sljit_uw)code_ptr) | 0x1;
+		label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
 		label->size = code_ptr - code;
 		label = label->next;
 	}
@@ -409,17 +426,42 @@
 
 	jump = compiler->jumps;
 	while (jump) {
-		set_jump_instruction(jump);
+		set_jump_instruction(jump, executable_offset);
 		jump = jump->next;
 	}
 
 	compiler->error = SLJIT_ERR_COMPILED;
+	compiler->executable_offset = executable_offset;
 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
+
+	code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+	code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
 	SLJIT_CACHE_FLUSH(code, code_ptr);
 	/* Set thumb mode flag. */
 	return (void*)((sljit_uw)code | 0x1);
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	switch (feature_type) {
+	case SLJIT_HAS_FPU:
+#ifdef SLJIT_IS_FPU_AVAILABLE
+		return SLJIT_IS_FPU_AVAILABLE;
+#else
+		/* Available by default. */
+		return 1;
+#endif
+
+	case SLJIT_HAS_CLZ:
+	case SLJIT_HAS_CMOV:
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
 /* --------------------------------------------------------------------- */
 /*  Core code generator functions.                                       */
 /* --------------------------------------------------------------------- */
@@ -488,36 +530,32 @@
 	}
 
 	/* set low 16 bits, set hi 16 bits to 0. */
-	FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
-		COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+	FAIL_IF(push_inst32(compiler, MOVW | RD4(dst)
+		| COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
 
 	/* set hi 16 bit if needed. */
 	if (imm >= 0x10000)
-		return push_inst32(compiler, MOVT | RD4(dst) |
-			COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+		return push_inst32(compiler, MOVT | RD4(dst)
+			| COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
 	return SLJIT_SUCCESS;
 }
 
 #define ARG1_IMM	0x0010000
 #define ARG2_IMM	0x0020000
-#define KEEP_FLAGS	0x0040000
 /* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */
 #define SET_FLAGS	0x0100000
 #define UNUSED_RETURN	0x0200000
-#define SLOW_DEST	0x0400000
-#define SLOW_SRC1	0x0800000
-#define SLOW_SRC2	0x1000000
 
 static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2)
 {
 	/* dst must be register, TMP_REG1
-	   arg1 must be register, TMP_REG1, imm
-	   arg2 must be register, TMP_REG2, imm */
+	   arg1 must be register, imm
+	   arg2 must be register, imm */
 	sljit_s32 reg;
 	sljit_uw imm, nimm;
 
 	if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
-		/* Both are immediates. */
+		/* Both are immediates, no temporaries are used. */
 		flags &= ~ARG1_IMM;
 		FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
 		arg1 = TMP_REG1;
@@ -533,7 +571,7 @@
 			/* No form with immediate operand. */
 			break;
 		case SLJIT_MOV:
-			SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
+			SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG2);
 			return load_immediate(compiler, dst, imm);
 		case SLJIT_NOT:
 			if (!(flags & SET_FLAGS))
@@ -543,7 +581,7 @@
 			break;
 		case SLJIT_ADD:
 			nimm = -imm;
-			if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) {
+			if (IS_2_LO_REGS(reg, dst)) {
 				if (imm <= 0x7)
 					return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
 				if (nimm <= 0x7)
@@ -561,9 +599,12 @@
 				if (nimm <= 0xfff)
 					return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(nimm));
 			}
-			imm = get_imm(imm);
-			if (imm != INVALID_IMM)
-				return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+			nimm = get_imm(imm);
+			if (nimm != INVALID_IMM)
+				return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
+			nimm = get_imm(-imm);
+			if (nimm != INVALID_IMM)
+				return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
 			break;
 		case SLJIT_ADDC:
 			imm = get_imm(imm);
@@ -571,16 +612,27 @@
 				return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
 			break;
 		case SLJIT_SUB:
+			/* SUB operation can be replaced by ADD because of the negative carry flag. */
 			if (flags & ARG1_IMM) {
-				if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst))
+				if (imm == 0 && IS_2_LO_REGS(reg, dst))
 					return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg));
 				imm = get_imm(imm);
 				if (imm != INVALID_IMM)
 					return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
 				break;
 			}
+			if (flags & UNUSED_RETURN) {
+				if (imm <= 0xff && reg_map[reg] <= 7)
+					return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg));
+				nimm = get_imm(imm);
+				if (nimm != INVALID_IMM)
+					return push_inst32(compiler, CMPI_W | RN4(reg) | nimm);
+				nimm = get_imm(-imm);
+				if (nimm != INVALID_IMM)
+					return push_inst32(compiler, CMNI_W | RN4(reg) | nimm);
+			}
 			nimm = -imm;
-			if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) {
+			if (IS_2_LO_REGS(reg, dst)) {
 				if (imm <= 0x7)
 					return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
 				if (nimm <= 0x7)
@@ -591,8 +643,6 @@
 					if (nimm <= 0xff)
 						return push_inst16(compiler, ADDSI8 | IMM8(nimm) | RDN3(dst));
 				}
-				if (imm <= 0xff && (flags & UNUSED_RETURN))
-					return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg));
 			}
 			if (!(flags & SET_FLAGS)) {
 				if (imm <= 0xfff)
@@ -600,9 +650,12 @@
 				if (nimm <= 0xfff)
 					return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(nimm));
 			}
-			imm = get_imm(imm);
-			if (imm != INVALID_IMM)
-				return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+			nimm = get_imm(imm);
+			if (nimm != INVALID_IMM)
+				return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
+			nimm = get_imm(-imm);
+			if (nimm != INVALID_IMM)
+				return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
 			break;
 		case SLJIT_SUBC:
 			if (flags & ARG1_IMM)
@@ -647,31 +700,35 @@
 			}
 			switch (flags & 0xffff) {
 			case SLJIT_SHL:
-				if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+				if (IS_2_LO_REGS(dst, reg))
 					return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));
 				return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
 			case SLJIT_LSHR:
-				if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+				if (IS_2_LO_REGS(dst, reg))
 					return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));
 				return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
 			default: /* SLJIT_ASHR */
-				if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+				if (IS_2_LO_REGS(dst, reg))
 					return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));
 				return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
 			}
 		default:
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 			break;
 		}
 
 		if (flags & ARG2_IMM) {
-			FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
-			arg2 = TMP_REG2;
+			imm = arg2;
+			arg2 = (arg1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+			FAIL_IF(load_immediate(compiler, arg2, imm));
 		}
 		else {
-			FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
-			arg1 = TMP_REG1;
+			imm = arg1;
+			arg1 = (arg2 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+			FAIL_IF(load_immediate(compiler, arg1, imm));
 		}
+
+		SLJIT_ASSERT(arg1 != arg2);
 	}
 
 	/* Both arguments are registers. */
@@ -680,108 +737,98 @@
 	case SLJIT_MOV_U32:
 	case SLJIT_MOV_S32:
 	case SLJIT_MOV_P:
-	case SLJIT_MOVU:
-	case SLJIT_MOVU_U32:
-	case SLJIT_MOVU_S32:
-	case SLJIT_MOVU_P:
-		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
 		if (dst == arg2)
 			return SLJIT_SUCCESS;
 		return push_inst16(compiler, MOV | SET_REGS44(dst, arg2));
 	case SLJIT_MOV_U8:
-	case SLJIT_MOVU_U8:
-		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
 		if (IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));
 	case SLJIT_MOV_S8:
-	case SLJIT_MOVU_S8:
-		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
 		if (IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));
 	case SLJIT_MOV_U16:
-	case SLJIT_MOVU_U16:
-		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
 		if (IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));
 	case SLJIT_MOV_S16:
-	case SLJIT_MOVU_S16:
-		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+		SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
 		if (IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2));
 	case SLJIT_NOT:
-		SLJIT_ASSERT(arg1 == TMP_REG1);
-		if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		SLJIT_ASSERT(arg1 == TMP_REG2);
+		if (IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2));
 	case SLJIT_CLZ:
-		SLJIT_ASSERT(arg1 == TMP_REG1);
+		SLJIT_ASSERT(arg1 == TMP_REG2);
 		FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2)));
-		if (flags & SET_FLAGS) {
-			if (reg_map[dst] <= 7)
-				return push_inst16(compiler, CMPI | RDN3(dst));
-			return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst));
-		}
 		return SLJIT_SUCCESS;
 	case SLJIT_ADD:
-		if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+		if (IS_3_LO_REGS(dst, arg1, arg2))
 			return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2));
 		if (dst == arg1 && !(flags & SET_FLAGS))
 			return push_inst16(compiler, ADD | SET_REGS44(dst, arg2));
 		return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_ADDC:
-		if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_SUB:
-		if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+		if (flags & UNUSED_RETURN) {
+			if (IS_2_LO_REGS(arg1, arg2))
+				return push_inst16(compiler, CMP | RD3(arg1) | RN3(arg2));
+			return push_inst16(compiler, CMP_X | SET_REGS44(arg1, arg2));
+		}
+		if (IS_3_LO_REGS(dst, arg1, arg2))
 			return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2));
 		return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_SUBC:
-		if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_MUL:
 		if (!(flags & SET_FLAGS))
 			return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2));
-		SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2);
+		SLJIT_ASSERT(dst != TMP_REG2);
 		FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2)));
 		/* cmp TMP_REG2, dst asr #31. */
 		return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst));
 	case SLJIT_AND:
-		if (!(flags & KEEP_FLAGS)) {
-			if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
-				return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));
-			if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2))
-				return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2));
-		}
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
+			return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));
+		if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2))
+			return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2));
 		return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_OR:
-		if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_XOR:
-		if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_SHL:
-		if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_LSHR:
-		if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	case SLJIT_ASHR:
-		if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+		if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
 			return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));
 		return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 }
 
@@ -791,9 +838,7 @@
 #define WORD_SIZE	0x00
 #define BYTE_SIZE	0x04
 #define HALF_SIZE	0x08
-
-#define UPDATE		0x10
-#define ARG_TEST	0x20
+#define PRELOAD		0x0c
 
 #define IS_WORD_SIZE(flags)		(!(flags & (BYTE_SIZE | HALF_SIZE)))
 #define OFFSET_CHECK(imm, shift)	(!(argw & ~(imm << shift)))
@@ -849,7 +894,7 @@
 
 #define MEM_IMM8	0xc00
 #define MEM_IMM12	0x800000
-static const sljit_ins sljit_mem32[12] = {
+static const sljit_ins sljit_mem32[13] = {
 /* w u l */ 0xf8500000 /* ldr.w */,
 /* w u s */ 0xf8400000 /* str.w */,
 /* w s l */ 0xf8500000 /* ldr.w */,
@@ -864,6 +909,8 @@
 /* h u s */ 0xf8200000 /* strsh.w */,
 /* h s l */ 0xf9300000 /* ldrsh.w */,
 /* h s s */ 0xf8200000 /* strsh.w */,
+
+/* p u l */ 0xf8100000 /* pld */,
 };
 
 /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
@@ -887,240 +934,92 @@
 	return SLJIT_ERR_UNSUPPORTED;
 }
 
-/* Can perform an operation using at most 1 instruction. */
-static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
+	sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
 {
-	sljit_s32 other_r, shift;
+	sljit_s32 other_r;
+	sljit_uw tmp;
 
 	SLJIT_ASSERT(arg & SLJIT_MEM);
+	SLJIT_ASSERT((arg & REG_MASK) != tmp_reg);
+	arg &= ~SLJIT_MEM;
 
-	if (SLJIT_UNLIKELY(flags & UPDATE)) {
-		if ((arg & REG_MASK) && !(arg & OFFS_REG_MASK) && argw <= 0xff && argw >= -0xff) {
-			if (SLJIT_UNLIKELY(flags & ARG_TEST))
-				return 1;
-
-			flags &= ~UPDATE;
-			arg &= 0xf;
-			if (argw >= 0)
-				argw |= 0x200;
-			else {
-				argw = -argw;
-			}
-
-			SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff);
-			FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw));
-			return -1;
+	if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
+		tmp = get_imm(argw & ~0xfff);
+		if (tmp != INVALID_IMM) {
+			FAIL_IF(push_inst32(compiler, MOV_WI | RD4(tmp_reg) | tmp));
+			return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(tmp_reg) | (argw & 0xfff));
 		}
-		return 0;
+
+		FAIL_IF(load_immediate(compiler, tmp_reg, argw));
+		if (IS_2_LO_REGS(reg, tmp_reg) && sljit_mem16_imm5[flags])
+			return push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(tmp_reg));
+		return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(tmp_reg));
 	}
 
 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
-		if (SLJIT_UNLIKELY(flags & ARG_TEST))
-			return 1;
-
 		argw &= 0x3;
 		other_r = OFFS_REG(arg);
 		arg &= 0xf;
 
 		if (!argw && IS_3_LO_REGS(reg, arg, other_r))
-			FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r)));
-		else
-			FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4)));
-		return -1;
+			return push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r));
+		return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4));
 	}
 
-	if (!(arg & REG_MASK) || argw > 0xfff || argw < -0xff)
-		return 0;
+	if (argw > 0xfff) {
+		tmp = get_imm(argw & ~0xfff);
+		if (tmp != INVALID_IMM) {
+			push_inst32(compiler, ADD_WI | RD4(tmp_reg) | RN4(arg) | tmp);
+			arg = tmp_reg;
+			argw = argw & 0xfff;
+		}
+	}
+	else if (argw < -0xff) {
+		tmp = get_imm(-argw & ~0xff);
+		if (tmp != INVALID_IMM) {
+			push_inst32(compiler, SUB_WI | RD4(tmp_reg) | RN4(arg) | tmp);
+			arg = tmp_reg;
+			argw = -(-argw & 0xff);
+		}
+	}
 
-	if (SLJIT_UNLIKELY(flags & ARG_TEST))
-		return 1;
-
-	arg &= 0xf;
 	if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) {
-		shift = 3;
+		tmp = 3;
 		if (IS_WORD_SIZE(flags)) {
 			if (OFFSET_CHECK(0x1f, 2))
-				shift = 2;
+				tmp = 2;
 		}
 		else if (flags & BYTE_SIZE)
 		{
 			if (OFFSET_CHECK(0x1f, 0))
-				shift = 0;
+				tmp = 0;
 		}
 		else {
 			SLJIT_ASSERT(flags & HALF_SIZE);
 			if (OFFSET_CHECK(0x1f, 1))
-				shift = 1;
+				tmp = 1;
 		}
 
-		if (shift != 3) {
-			FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - shift))));
-			return -1;
-		}
+		if (tmp < 3)
+			return push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - tmp)));
+	}
+	else if (SLJIT_UNLIKELY(arg == SLJIT_SP) && IS_WORD_SIZE(flags) && OFFSET_CHECK(0xff, 2) && reg_map[reg] <= 7) {
+		/* SP based immediate. */
+		return push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2));
 	}
 
-	/* SP based immediate. */
-	if (SLJIT_UNLIKELY(arg == SLJIT_SP) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) {
-		FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2)));
-		return -1;
-	}
+	if (argw >= 0 && argw <= 0xfff)
+		return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw);
+	else if (argw < 0 && argw >= -0xff)
+		return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw);
 
-	if (argw >= 0)
-		FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
-	else
-		FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw));
-	return -1;
-}
+	SLJIT_ASSERT(arg != tmp_reg);
 
-/* see getput_arg below.
-   Note: can_cache is called only for binary operators. Those
-   operators always uses word arguments without write back. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	sljit_sw diff;
-	if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
-		return 0;
-
-	if (!(arg & REG_MASK)) {
-		diff = argw - next_argw;
-		if (diff <= 0xfff && diff >= -0xfff)
-			return 1;
-		return 0;
-	}
-
-	if (argw == next_argw)
-		return 1;
-
-	diff = argw - next_argw;
-	if (arg == next_arg && diff <= 0xfff && diff >= -0xfff)
-		return 1;
-
-	return 0;
-}
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
-	sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	sljit_s32 tmp_r, other_r;
-	sljit_sw diff;
-
-	SLJIT_ASSERT(arg & SLJIT_MEM);
-	if (!(next_arg & SLJIT_MEM)) {
-		next_arg = 0;
-		next_argw = 0;
-	}
-
-	tmp_r = (flags & STORE) ? TMP_REG3 : reg;
-
-	if (SLJIT_UNLIKELY((flags & UPDATE) && (arg & REG_MASK))) {
-		/* Update only applies if a base register exists. */
-		/* There is no caching here. */
-		other_r = OFFS_REG(arg);
-		arg &= 0xf;
-		flags &= ~UPDATE;
-
-		if (!other_r) {
-			if (!(argw & ~0xfff)) {
-				FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
-				return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw));
-			}
-
-			if (compiler->cache_arg == SLJIT_MEM) {
-				if (argw == compiler->cache_argw) {
-					other_r = TMP_REG3;
-					argw = 0;
-				}
-				else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
-					FAIL_IF(compiler->error);
-					compiler->cache_argw = argw;
-					other_r = TMP_REG3;
-					argw = 0;
-				}
-			}
-
-			if (argw) {
-				FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-				compiler->cache_arg = SLJIT_MEM;
-				compiler->cache_argw = argw;
-				other_r = TMP_REG3;
-				argw = 0;
-			}
-		}
-
-		argw &= 0x3;
-		if (!argw && IS_3_LO_REGS(reg, arg, other_r)) {
-			FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r)));
-			return push_inst16(compiler, ADD | SET_REGS44(arg, other_r));
-		}
-		FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r) | (argw << 4)));
-		return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(other_r) | (argw << 6));
-	}
-	flags &= ~UPDATE;
-
-	SLJIT_ASSERT(!(arg & OFFS_REG_MASK));
-
-	if (compiler->cache_arg == arg) {
-		diff = argw - compiler->cache_argw;
-		if (!(diff & ~0xfff))
-			return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | diff);
-		if (!((compiler->cache_argw - argw) & ~0xff))
-			return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw));
-		if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, diff) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
-		}
-	}
-
-	next_arg = (arg & REG_MASK) && (arg == next_arg) && (argw != next_argw);
-	arg &= 0xf;
-	if (arg && compiler->cache_arg == SLJIT_MEM) {
-		if (compiler->cache_argw == argw)
-			return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
-		if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			compiler->cache_argw = argw;
-			return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
-		}
-	}
-
-	compiler->cache_argw = argw;
-	if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
-		FAIL_IF(compiler->error);
-		compiler->cache_arg = SLJIT_MEM | arg;
-		arg = 0;
-	}
-	else {
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-		compiler->cache_arg = SLJIT_MEM;
-
-		diff = argw - next_argw;
-		if (next_arg && diff <= 0xfff && diff >= -0xfff) {
-			FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg)));
-			compiler->cache_arg = SLJIT_MEM | arg;
-			arg = 0;
-		}
-	}
-
-	if (arg)
-		return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
-	return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
-{
-	if (getput_arg_fast(compiler, flags, reg, arg, argw))
-		return compiler->error;
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
-	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
-		return compiler->error;
-	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+	FAIL_IF(load_immediate(compiler, tmp_reg, argw));
+	if (IS_3_LO_REGS(reg, arg, tmp_reg))
+		return push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp_reg));
+	return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp_reg));
 }
 
 /* --------------------------------------------------------------------- */
@@ -1128,17 +1027,15 @@
 /* --------------------------------------------------------------------- */
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 size, i, tmp;
-	sljit_ins push;
+	sljit_s32 args, size, i, tmp;
+	sljit_ins push = 0;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
-
-	push = (1 << 4);
+	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);
 
 	tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
 	for (i = SLJIT_S0; i >= tmp; i--)
@@ -1152,7 +1049,7 @@
 		: push_inst16(compiler, PUSH | (1 << 8) | push));
 
 	/* Stack must be aligned to 8 bytes: (LR, R4) */
-	size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);
+	size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
 	local_size = ((size + local_size + 7) & ~7) - size;
 	compiler->local_size = local_size;
 	if (local_size > 0) {
@@ -1162,6 +1059,8 @@
 			FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size));
 	}
 
+	args = get_arg_count(arg_types);
+
 	if (args >= 1)
 		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0, SLJIT_R0)));
 	if (args >= 2)
@@ -1173,16 +1072,16 @@
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 size;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
-	size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2);
+	size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
 	compiler->local_size = ((size + local_size + 7) & ~7) - size;
 	return SLJIT_SUCCESS;
 }
@@ -1190,7 +1089,7 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
 {
 	sljit_s32 i, tmp;
-	sljit_ins pop;
+	sljit_ins pop = 0;
 
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_return(compiler, op, src, srcw));
@@ -1204,8 +1103,6 @@
 			FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_SP, SLJIT_SP, compiler->local_size));
 	}
 
-	pop = (1 << 4);
-
 	tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
 	for (i = SLJIT_S0; i >= tmp; i--)
 		pop |= 1 << reg_map[i];
@@ -1263,11 +1160,11 @@
 	case SLJIT_DIV_UW:
 	case SLJIT_DIV_SW:
 		SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
-		SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping);
+		SLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);
 
 		saved_reg_count = 0;
 		if (compiler->scratches >= 4)
-			saved_reg_list[saved_reg_count++] = 12;
+			saved_reg_list[saved_reg_count++] = 3;
 		if (compiler->scratches >= 3)
 			saved_reg_list[saved_reg_count++] = 2;
 		if (op >= SLJIT_DIV_UW)
@@ -1323,13 +1220,17 @@
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
+		/* Since TMP_PC has index 15, IS_2_LO_REGS and IS_3_LO_REGS checks always fail. */
+		if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
+			return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);
+		return SLJIT_SUCCESS;
+	}
 
 	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
 
 	op = GET_OPCODE(op);
-	if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
+	if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
 		switch (op) {
 		case SLJIT_MOV:
 		case SLJIT_MOV_U32:
@@ -1357,58 +1258,26 @@
 			if (src & SLJIT_IMM)
 				srcw = (sljit_s16)srcw;
 			break;
-		case SLJIT_MOVU:
-		case SLJIT_MOVU_U32:
-		case SLJIT_MOVU_S32:
-		case SLJIT_MOVU_P:
-			flags = WORD_SIZE | UPDATE;
-			break;
-		case SLJIT_MOVU_U8:
-			flags = BYTE_SIZE | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_u8)srcw;
-			break;
-		case SLJIT_MOVU_S8:
-			flags = BYTE_SIZE | SIGNED | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_s8)srcw;
-			break;
-		case SLJIT_MOVU_U16:
-			flags = HALF_SIZE | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_u16)srcw;
-			break;
-		case SLJIT_MOVU_S16:
-			flags = HALF_SIZE | SIGNED | UPDATE;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_s16)srcw;
-			break;
 		default:
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 			flags = 0;
 			break;
 		}
 
 		if (src & SLJIT_IMM)
-			FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
+			FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG2, srcw));
 		else if (src & SLJIT_MEM) {
-			if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
-				FAIL_IF(compiler->error);
-			else
-				FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
+			FAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, TMP_REG1));
 		} else {
 			if (dst_r != TMP_REG1)
-				return emit_op_imm(compiler, op, dst_r, TMP_REG1, src);
+				return emit_op_imm(compiler, op, dst_r, TMP_REG2, src);
 			dst_r = src;
 		}
 
-		if (dst & SLJIT_MEM) {
-			if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
-				return compiler->error;
-			else
-				return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
-		}
-		return SLJIT_SUCCESS;
+		if (!(dst & SLJIT_MEM))
+			return SLJIT_SUCCESS;
+
+		return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
 	}
 
 	if (op == SLJIT_NEG) {
@@ -1419,28 +1288,17 @@
 		return sljit_emit_op2(compiler, SLJIT_SUB | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw);
 	}
 
-	flags = (GET_FLAGS(op_flags) ? SET_FLAGS : 0) | ((op_flags & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
+	flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;
+
 	if (src & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw))
-			FAIL_IF(compiler->error);
-		else
-			FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw));
-		src = TMP_REG2;
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
+		src = TMP_REG1;
 	}
 
-	if (src & SLJIT_IMM)
-		flags |= ARG2_IMM;
-	else
-		srcw = src;
+	emit_op_imm(compiler, flags | op, dst_r, TMP_REG2, src);
 
-	emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw);
-
-	if (dst & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
-			return compiler->error;
-		else
-			return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
-	}
+	if (SLJIT_UNLIKELY(dst & SLJIT_MEM))
+		return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
 	return SLJIT_SUCCESS;
 }
 
@@ -1449,7 +1307,7 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
-	sljit_s32 dst_r, flags;
+	sljit_s32 dst_reg, flags, src2_reg;
 
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
@@ -1457,70 +1315,39 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
 
-	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
-	flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
-
-	if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw))
-		flags |= SLOW_DEST;
-
-	if (src1 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w))
-			FAIL_IF(compiler->error);
-		else
-			flags |= SLOW_SRC1;
-	}
-	if (src2 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w))
-			FAIL_IF(compiler->error);
-		else
-			flags |= SLOW_SRC2;
-	}
-
-	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
-		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
-			FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w));
-			FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
-		}
-		else {
-			FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w));
-			FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
-		}
-	}
-	else if (flags & SLOW_SRC1)
-		FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
-	else if (flags & SLOW_SRC2)
-		FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
-
-	if (src1 & SLJIT_MEM)
-		src1 = TMP_REG1;
-	if (src2 & SLJIT_MEM)
-		src2 = TMP_REG2;
+	dst_reg = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+	flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 
 	if (src1 & SLJIT_IMM)
 		flags |= ARG1_IMM;
+	else if (src1 & SLJIT_MEM) {
+		emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1);
+		src1w = TMP_REG1;
+	}
 	else
 		src1w = src1;
+
 	if (src2 & SLJIT_IMM)
 		flags |= ARG2_IMM;
+	else if (src2 & SLJIT_MEM) {
+		src2_reg = (!(flags & ARG1_IMM) && (src1w == TMP_REG1)) ? TMP_REG2 : TMP_REG1;
+		emit_op_mem(compiler, WORD_SIZE, src2_reg, src2, src2w, src2_reg);
+		src2w = src2_reg;
+	}
 	else
 		src2w = src2;
 
 	if (dst == SLJIT_UNUSED)
 		flags |= UNUSED_RETURN;
 
-	emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
+	emit_op_imm(compiler, flags | GET_OPCODE(op), dst_reg, src1w, src2w);
 
-	if (dst & SLJIT_MEM) {
-		if (!(flags & SLOW_DEST)) {
-			getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw);
-			return compiler->error;
-		}
-		return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0);
-	}
-	return SLJIT_SUCCESS;
+	if (!(dst & SLJIT_MEM))
+		return SLJIT_SUCCESS;
+	return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG2);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
@@ -1532,7 +1359,7 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
 {
 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
-	return reg << 1;
+	return (freg_map[reg] << 1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
@@ -1550,21 +1377,10 @@
 /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-#ifdef SLJIT_IS_FPU_AVAILABLE
-	return SLJIT_IS_FPU_AVAILABLE;
-#else
-	/* Available by default. */
-	return 1;
-#endif
-}
-
 #define FPU_LOAD (1 << 20)
 
 static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
 {
-	sljit_sw tmp;
 	sljit_uw imm;
 	sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD));
 
@@ -1572,8 +1388,8 @@
 
 	/* Fast loads and stores. */
 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
-		FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((argw & 0x3) << 6)));
-		arg = SLJIT_MEM | TMP_REG2;
+		FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(arg & REG_MASK) | RM4(OFFS_REG(arg)) | ((argw & 0x3) << 6)));
+		arg = SLJIT_MEM | TMP_REG1;
 		argw = 0;
 	}
 
@@ -1584,21 +1400,6 @@
 			return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | (-argw >> 2));
 	}
 
-	/* Slow cases */
-	SLJIT_ASSERT(!(arg & OFFS_REG_MASK));
-	if (compiler->cache_arg == arg) {
-		tmp = argw - compiler->cache_argw;
-		if (!(tmp & ~0x3fc))
-			return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2));
-		if (!(-tmp & ~0x3fc))
-			return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2));
-		if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) {
-			FAIL_IF(compiler->error);
-			compiler->cache_argw = argw;
-			return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
-		}
-	}
-
 	if (arg & REG_MASK) {
 		if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) {
 			FAIL_IF(compiler->error);
@@ -1617,19 +1418,18 @@
 		}
 	}
 
-	compiler->cache_arg = arg;
-	compiler->cache_argw = argw;
-
-	FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+	FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
 	if (arg & REG_MASK)
-		FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & REG_MASK))));
-	return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
+		FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, (arg & REG_MASK))));
+	return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg));
 }
 
 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
+	op ^= SLJIT_F32_OP;
+
 	if (src & SLJIT_MEM) {
 		FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
 		src = TMP_FREG1;
@@ -1637,9 +1437,6 @@
 
 	FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_F32_OP) | DD4(TMP_FREG1) | DM4(src)));
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (FAST_IS_REG(dst))
 		return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1));
 
@@ -1653,6 +1450,8 @@
 {
 	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
+	op ^= SLJIT_F32_OP;
+
 	if (FAST_IS_REG(src))
 		FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1)));
 	else if (src & SLJIT_MEM) {
@@ -1675,6 +1474,8 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
+	op ^= SLJIT_F32_OP;
+
 	if (src1 & SLJIT_MEM) {
 		emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
 		src1 = TMP_FREG1;
@@ -1696,16 +1497,15 @@
 	sljit_s32 dst_r;
 
 	CHECK_ERROR();
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
-		op ^= SLJIT_F32_OP;
 
 	SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error);
 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
 
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
+	if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
+		op ^= SLJIT_F32_OP;
+
 	if (src & SLJIT_MEM) {
 		emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw);
 		src = dst_r;
@@ -1750,8 +1550,6 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
 	op ^= SLJIT_F32_OP;
 
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
@@ -1796,21 +1594,13 @@
 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	/* For UNUSED dst. Uncommon, but possible. */
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
+	SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
 
 	if (FAST_IS_REG(dst))
-		return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3));
+		return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2));
 
 	/* Memory. */
-	if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw))
-		return compiler->error;
-	/* TMP_REG3 is used for caching. */
-	FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3)));
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0);
+	return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
@@ -1819,21 +1609,14 @@
 	CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
+	SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
+
 	if (FAST_IS_REG(src))
-		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src)));
-	else if (src & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw))
-			FAIL_IF(compiler->error);
-		else {
-			compiler->cache_arg = 0;
-			compiler->cache_argw = 0;
-			FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0));
-			FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2)));
-		}
-	}
-	else if (src & SLJIT_IMM)
-		FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
-	return push_inst16(compiler, BLX | RN3(TMP_REG3));
+		FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
+	else
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
+
+	return push_inst16(compiler, BX | RN3(TMP_REG2));
 }
 
 /* --------------------------------------------------------------------- */
@@ -1890,7 +1673,7 @@
 		return 0x7;
 
 	default: /* SLJIT_JUMP */
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 		return 0xe;
 	}
 }
@@ -1924,7 +1707,6 @@
 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
 	type &= 0xff;
 
-	/* In ARM, we don't need to touch the arguments. */
 	PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
 	if (type < SLJIT_JUMP) {
 		jump->flags |= IS_COND;
@@ -1944,6 +1726,241 @@
 	return jump;
 }
 
+#ifdef __SOFTFP__
+
+static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
+{
+	sljit_s32 stack_offset = 0;
+	sljit_s32 arg_count = 0;
+	sljit_s32 word_arg_offset = 0;
+	sljit_s32 float_arg_count = 0;
+	sljit_s32 types = 0;
+	sljit_s32 src_offset = 4 * sizeof(sljit_sw);
+	sljit_u8 offsets[4];
+
+	if (src && FAST_IS_REG(*src))
+		src_offset = reg_map[*src] * sizeof(sljit_sw);
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
+
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			offsets[arg_count] = (sljit_u8)stack_offset;
+			stack_offset += sizeof(sljit_f32);
+			arg_count++;
+			float_arg_count++;
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (stack_offset & 0x7)
+				stack_offset += sizeof(sljit_sw);
+			offsets[arg_count] = (sljit_u8)stack_offset;
+			stack_offset += sizeof(sljit_f64);
+			arg_count++;
+			float_arg_count++;
+			break;
+		default:
+			offsets[arg_count] = (sljit_u8)stack_offset;
+			stack_offset += sizeof(sljit_sw);
+			arg_count++;
+			word_arg_offset += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	if (stack_offset > 16)
+		FAIL_IF(push_inst16(compiler, SUB_SP | (((stack_offset - 16) + 0x7) & ~0x7) >> 2));
+
+	SLJIT_ASSERT(reg_map[TMP_REG1] == 12);
+
+	/* Process arguments in reversed direction. */
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			arg_count--;
+			float_arg_count--;
+			stack_offset = offsets[arg_count];
+
+			if (stack_offset < 16) {
+				if (src_offset == stack_offset) {
+					FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
+					*src = TMP_REG1;
+				}
+				FAIL_IF(push_inst32(compiler, VMOV | 0x100000 | (float_arg_count << 16) | (stack_offset << 10)));
+			} else
+				FAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800000 | RN4(SLJIT_SP) | (float_arg_count << 12) | ((stack_offset - 16) >> 2)));
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			arg_count--;
+			float_arg_count--;
+			stack_offset = offsets[arg_count];
+
+			SLJIT_ASSERT((stack_offset & 0x7) == 0);
+
+			if (stack_offset < 16) {
+				if (src_offset == stack_offset || src_offset == stack_offset + sizeof(sljit_sw)) {
+					FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
+					*src = TMP_REG1;
+				}
+				FAIL_IF(push_inst32(compiler, VMOV2 | 0x100000 | (stack_offset << 10) | ((stack_offset + sizeof(sljit_sw)) << 14) | float_arg_count));
+			} else
+				FAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800100 | RN4(SLJIT_SP) | (float_arg_count << 12) | ((stack_offset - 16) >> 2)));
+			break;
+		default:
+			arg_count--;
+			word_arg_offset -= sizeof(sljit_sw);
+			stack_offset = offsets[arg_count];
+
+			SLJIT_ASSERT(stack_offset >= word_arg_offset);
+
+			if (stack_offset != word_arg_offset) {
+				if (stack_offset < 16) {
+					if (src_offset == stack_offset) {
+						FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
+						*src = TMP_REG1;
+					}
+					else if (src_offset == word_arg_offset) {
+						*src = 1 + (stack_offset >> 2);
+						src_offset = stack_offset;
+					}
+					FAIL_IF(push_inst16(compiler, MOV | (stack_offset >> 2) | (word_arg_offset << 1)));
+				} else
+					FAIL_IF(push_inst16(compiler, STR_SP | (word_arg_offset << 6) | ((stack_offset - 16) >> 2)));
+			}
+			break;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
+	return SLJIT_SUCCESS;
+}
+
+static sljit_s32 softfloat_post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
+{
+	sljit_s32 stack_size = 0;
+
+	if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32)
+		FAIL_IF(push_inst32(compiler, VMOV | (0 << 16) | (0 << 12)));
+	if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F64)
+		FAIL_IF(push_inst32(compiler, VMOV2 | (1 << 16) | (0 << 12) | 0));
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			stack_size += sizeof(sljit_f32);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (stack_size & 0x7)
+				stack_size += sizeof(sljit_sw);
+			stack_size += sizeof(sljit_f64);
+			break;
+		default:
+			stack_size += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	if (stack_size <= 16)
+		return SLJIT_SUCCESS;
+
+	return push_inst16(compiler, ADD_SP | ((((stack_size - 16) + 0x7) & ~0x7) >> 2));
+}
+
+#else
+
+static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
+{
+	sljit_u32 remap = 0;
+	sljit_u32 offset = 0;
+	sljit_u32 new_offset, mask;
+
+	/* Remove return value. */
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32) {
+			new_offset = 0;
+			mask = 1;
+
+			while (remap & mask) {
+				new_offset++;
+				mask <<= 1;
+			}
+			remap |= mask;
+
+			if (offset != new_offset)
+				FAIL_IF(push_inst32(compiler, VMOV_F32 | DD4((new_offset >> 1) + 1)
+					| ((new_offset & 0x1) ? 0x400000 : 0) | DM4((offset >> 1) + 1)));
+
+			offset += 2;
+		}
+		else if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F64) {
+			new_offset = 0;
+			mask = 3;
+
+			while (remap & mask) {
+				new_offset += 2;
+				mask <<= 2;
+			}
+			remap |= mask;
+
+			if (offset != new_offset)
+				FAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_F32_OP | DD4((new_offset >> 1) + 1) | DM4((offset >> 1) + 1)));
+
+			offset += 2;
+		}
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	return SLJIT_SUCCESS;
+}
+
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+#ifdef __SOFTFP__
+	struct sljit_jump *jump;
+#endif
+
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+#ifdef __SOFTFP__
+	PTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types, NULL));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	jump = sljit_emit_jump(compiler, type);
+	PTR_FAIL_IF(jump == NULL);
+
+	PTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));
+	return jump;
+#else
+	PTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_jump(compiler, type);
+#endif
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
 {
 	struct sljit_jump *jump;
@@ -1952,16 +1969,20 @@
 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-	/* In ARM, we don't need to touch the arguments. */
-	if (!(src & SLJIT_IMM)) {
-		if (FAST_IS_REG(src))
-			return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
+	SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
 
-		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw));
+	if (!(src & SLJIT_IMM)) {
+		if (FAST_IS_REG(src)) {
+			SLJIT_ASSERT(reg_map[src] != 14);
+			return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
+		}
+
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw, TMP_REG1));
 		if (type >= SLJIT_FAST_CALL)
 			return push_inst16(compiler, BLX | RN3(TMP_REG1));
 	}
 
+	/* These jumps are converted to jump/call instructions when possible. */
 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 	FAIL_IF(!jump);
 	set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
@@ -1972,25 +1993,55 @@
 	return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1));
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+#ifdef __SOFTFP__
+	if (src & SLJIT_MEM) {
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
+		src = TMP_REG1;
+	}
+
+	FAIL_IF(softfloat_call_with_args(compiler, arg_types, &src));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
+
+	return softfloat_post_call_with_args(compiler, arg_types);
+#else /* !__SOFTFP__ */
+	FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_ijump(compiler, type, src, srcw);
+#endif /* __SOFTFP__ */
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
 	sljit_s32 dst_r, flags = GET_ALL_FLAGS(op);
-	sljit_ins cc, ins;
+	sljit_ins cc;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
-	ADJUST_LOCAL_OFFSET(src, srcw);
-
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
 
 	op = GET_OPCODE(op);
 	cc = get_cc(type & 0xff);
-	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
 
 	if (op < SLJIT_ADD) {
 		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
@@ -1998,60 +2049,141 @@
 			FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1));
 			FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0));
 		} else {
+			/* The movsi (immediate) instruction does not set flags in IT block. */
 			FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1));
 			FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0));
 		}
-		if (dst_r != TMP_REG2)
+		if (!(dst & SLJIT_MEM))
 			return SLJIT_SUCCESS;
-		return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw);
+		return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2);
 	}
 
-	ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI));
-	if ((op == SLJIT_OR || op == SLJIT_XOR) && FAST_IS_REG(dst) && dst == src) {
-		/* Does not change the other bits. */
-		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
-		FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1));
-		if (flags & SLJIT_SET_E) {
-			/* The condition must always be set, even if the ORRI/EORI is not executed above. */
-			if (reg_map[dst] <= 7)
-				return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst));
-			return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst));
-		}
-		return SLJIT_SUCCESS;
-	}
+	if (dst & SLJIT_MEM)
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	if (src & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw));
-		src = TMP_REG2;
-		srcw = 0;
-	} else if (src & SLJIT_IMM) {
-		FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
-		src = TMP_REG2;
-		srcw = 0;
-	}
-
-	if (op == SLJIT_AND || src != dst_r) {
+	if (op == SLJIT_AND) {
 		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
-		FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1));
-		FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0));
+		FAIL_IF(push_inst32(compiler, ANDI | RN4(dst_r) | RD4(dst_r) | 1));
+		FAIL_IF(push_inst32(compiler, ANDI | RN4(dst_r) | RD4(dst_r) | 0));
 	}
 	else {
 		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
-		FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1));
+		FAIL_IF(push_inst32(compiler, ((op == SLJIT_OR) ? ORRI : EORI) | RN4(dst_r) | RD4(dst_r) | 1));
 	}
 
-	if (dst_r == TMP_REG2)
-		FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0));
+	if (dst & SLJIT_MEM)
+		FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, TMP_REG2));
 
-	if (flags & SLJIT_SET_E) {
-		/* The condition must always be set, even if the ORR/EORI is not executed above. */
-		if (reg_map[dst_r] <= 7)
-			return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r));
-		return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r));
+	if (!(flags & SLJIT_SET_Z))
+		return SLJIT_SUCCESS;
+
+	/* The condition must always be set, even if the ORR/EORI is not executed above. */
+	return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_uw cc, tmp;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+	dst_reg &= ~SLJIT_I32_OP;
+
+	cc = get_cc(type & 0xff);
+
+	if (!(src & SLJIT_IMM)) {
+		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+		return push_inst16(compiler, MOV | SET_REGS44(dst_reg, src));
 	}
-	return SLJIT_SUCCESS;
+
+	tmp = (sljit_uw) srcw;
+
+	if (tmp < 0x10000) {
+		/* set low 16 bits, set hi 16 bits to 0. */
+		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+		return push_inst32(compiler, MOVW | RD4(dst_reg)
+			| COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff));
+	}
+
+	tmp = get_imm(srcw);
+	if (tmp != INVALID_IMM) {
+		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+		return push_inst32(compiler, MOV_WI | RD4(dst_reg) | tmp);
+	}
+
+	tmp = get_imm(~srcw);
+	if (tmp != INVALID_IMM) {
+		FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+		return push_inst32(compiler, MVN_WI | RD4(dst_reg) | tmp);
+	}
+
+	FAIL_IF(push_inst16(compiler, IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4));
+
+	tmp = (sljit_uw) srcw;
+	FAIL_IF(push_inst32(compiler, MOVW | RD4(dst_reg)
+		| COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff)));
+	return push_inst32(compiler, MOVT | RD4(dst_reg)
+		| COPY_BITS(tmp, 12 + 16, 16, 4) | COPY_BITS(tmp, 11 + 16, 26, 1) | COPY_BITS(tmp, 8 + 16, 12, 3) | ((tmp & 0xff0000) >> 16));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 reg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	sljit_s32 flags;
+	sljit_ins inst;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
+
+	if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -255))
+		return SLJIT_ERR_UNSUPPORTED;
+
+	if (type & SLJIT_MEM_SUPP)
+		return SLJIT_SUCCESS;
+
+	switch (type & 0xff) {
+	case SLJIT_MOV:
+	case SLJIT_MOV_U32:
+	case SLJIT_MOV_S32:
+	case SLJIT_MOV_P:
+		flags = WORD_SIZE;
+		break;
+	case SLJIT_MOV_U8:
+		flags = BYTE_SIZE;
+		break;
+	case SLJIT_MOV_S8:
+		flags = BYTE_SIZE | SIGNED;
+		break;
+	case SLJIT_MOV_U16:
+		flags = HALF_SIZE;
+		break;
+	case SLJIT_MOV_S16:
+		flags = HALF_SIZE | SIGNED;
+		break;
+	default:
+		SLJIT_UNREACHABLE();
+		flags = WORD_SIZE;
+		break;
+	}
+
+	if (type & SLJIT_MEM_STORE)
+		flags |= STORE;
+
+	inst = sljit_mem32[flags] | 0x900;
+
+	if (type & SLJIT_MEM_PRE)
+		inst |= 0x400;
+
+	if (memw >= 0)
+		inst |= 0x200;
+	else
+		memw = -memw;
+
+	return push_inst32(compiler, inst | RT4(reg) | RN4(mem & REG_MASK) | memw);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
@@ -2067,24 +2199,26 @@
 	PTR_FAIL_IF(!const_);
 	set_const(const_, compiler);
 
-	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
 	PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value));
 
 	if (dst & SLJIT_MEM)
-		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
+		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
 	return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
 	sljit_u16 *inst = (sljit_u16*)addr;
-	modify_imm32_const(inst, new_addr);
+	modify_imm32_const(inst, new_target);
+	inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 4);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
 	sljit_u16 *inst = (sljit_u16*)addr;
 	modify_imm32_const(inst, new_constant);
+	inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 4);
 }
diff --git a/dist2/src/sljit/sljitNativeMIPS_32.c b/dist2/src/sljit/sljitNativeMIPS_32.c
index 5096e4f..9f9e157 100644
--- a/dist2/src/sljit/sljitNativeMIPS_32.c
+++ b/dist2/src/sljit/sljitNativeMIPS_32.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -40,35 +40,37 @@
 
 #define EMIT_LOGICAL(op_imm, op_norm) \
 	if (flags & SRC2_IMM) { \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
 	} \
 	else { \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
 	}
 
 #define EMIT_SHIFT(op_imm, op_v) \
 	if (flags & SRC2_IMM) { \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
 	} \
 	else { \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \
 	}
 
 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
 	sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
 {
+	sljit_s32 is_overflow, is_carry, is_handled;
+
 	switch (GET_OPCODE(op)) {
 	case SLJIT_MOV:
 	case SLJIT_MOV_U32:
@@ -93,8 +95,9 @@
 			}
 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
 		}
-		else if (dst != src2)
-			SLJIT_ASSERT_STOP();
+		else {
+			SLJIT_ASSERT(dst == src2);
+		}
 		return SLJIT_SUCCESS;
 
 	case SLJIT_MOV_U16:
@@ -111,24 +114,25 @@
 			}
 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
 		}
-		else if (dst != src2)
-			SLJIT_ASSERT_STOP();
+		else {
+			SLJIT_ASSERT(dst == src2);
+		}
 		return SLJIT_SUCCESS;
 
 	case SLJIT_NOT:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
-		if (op & SLJIT_SET_E)
+		if (op & SLJIT_SET_Z)
 			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-		if (CHECK_FLAGS(SLJIT_SET_E))
+		if (!(flags & UNUSED_DEST))
 			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
 		return SLJIT_SUCCESS;
 
 	case SLJIT_CLZ:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
 #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
-		if (op & SLJIT_SET_E)
+		if (op & SLJIT_SET_Z)
 			FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
-		if (CHECK_FLAGS(SLJIT_SET_E))
+		if (!(flags & UNUSED_DEST))
 			FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
 #else
 		if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
@@ -145,130 +149,192 @@
 		FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst)));
 		FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
 		FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
-		if (op & SLJIT_SET_E)
-			return push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
 #endif
 		return SLJIT_SUCCESS;
 
 	case SLJIT_ADD:
+		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_O) {
+			if (is_overflow) {
 				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
 				else
-					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
 			}
-			if (op & SLJIT_SET_E)
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
-			if (op & (SLJIT_SET_C | SLJIT_SET_O)) {
+
+			if (is_overflow || is_carry) {
 				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
 				else {
-					FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
-					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+					FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
+					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
 				}
 			}
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
 		}
 		else {
-			if (op & SLJIT_SET_O)
-				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-			if (op & SLJIT_SET_E)
+			if (is_overflow)
+				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-			if (op & (SLJIT_SET_C | SLJIT_SET_O))
-				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+
+			if (is_overflow || is_carry)
+				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
 
 		/* a + b >= a | b (otherwise, the carry should be set to 1). */
-		if (op & (SLJIT_SET_C | SLJIT_SET_O))
-			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
-		if (!(op & SLJIT_SET_O))
+		if (is_overflow || is_carry)
+			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
+		if (!is_overflow)
 			return SLJIT_SUCCESS;
-		FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
-		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+		FAIL_IF(push_inst(compiler, SLL | TA(OTHER_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
+		if (op & SLJIT_SET_Z)
+			FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		return push_inst(compiler, SRL | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG);
 
 	case SLJIT_ADDC:
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_C) {
+			if (is_carry) {
 				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
 				else {
-					FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
-					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
+					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
 				}
 			}
 			FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
 		} else {
-			if (op & SLJIT_SET_C)
-				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+			if (is_carry)
+				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
 			/* dst may be the same as src1 or src2. */
 			FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
-		if (op & SLJIT_SET_C)
-			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+		if (is_carry)
+			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
 
-		FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
-		if (!(op & SLJIT_SET_C))
+		FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
+		if (!is_carry)
 			return SLJIT_SUCCESS;
 
-		/* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
-		FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+		/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
+		FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
 		/* Set carry flag. */
-		return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG);
+		return push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
 
 	case SLJIT_SUB:
-		if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
+		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
 			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
 			src2 = TMP_REG2;
 			flags &= ~SRC2_IMM;
 		}
 
+		is_handled = 0;
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_O) {
-				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-				else
-					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+			if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
+				is_handled = 1;
 			}
-			if (op & SLJIT_SET_E)
+			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
+				is_handled = 1;
+			}
+		}
+
+		if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
+			is_handled = 1;
+
+			if (flags & SRC2_IMM) {
+				FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+				src2 = TMP_REG2;
+				flags &= ~SRC2_IMM;
+			}
+
+			if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+			else if (GET_FLAG_TYPE(op) == SLJIT_GREATER || GET_FLAG_TYPE(op) == SLJIT_LESS_EQUAL)
+			{
+				FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER || GET_FLAG_TYPE(op) == SLJIT_SIG_LESS_EQUAL)
+			{
+				FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+		}
+
+		if (is_handled) {
+			if (flags & SRC2_IMM) {
+				if (op & SLJIT_SET_Z)
+					FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
+				if (!(flags & UNUSED_DEST))
+					return push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst));
+			}
+			else {
+				if (op & SLJIT_SET_Z)
+					FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+				if (!(flags & UNUSED_DEST))
+					return push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst));
+			}
+			return SLJIT_SUCCESS;
+		}
+
+		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
+		if (flags & SRC2_IMM) {
+			if (is_overflow) {
+				if (src2 >= 0)
+					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
+				else
+					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
+			}
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
-			if (op & (SLJIT_SET_C | SLJIT_SET_O))
-				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+
+			if (is_overflow || is_carry)
+				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
 		}
 		else {
-			if (op & SLJIT_SET_O)
-				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-			if (op & SLJIT_SET_E)
+			if (is_overflow)
+				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-			if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
-				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
-			if (op & SLJIT_SET_U)
-				FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
-			if (op & SLJIT_SET_S) {
-				FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
-				FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
-			}
+
+			if (is_overflow || is_carry)
+				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
 
-		if (!(op & SLJIT_SET_O))
+		if (!is_overflow)
 			return SLJIT_SUCCESS;
-		FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
-		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+		FAIL_IF(push_inst(compiler, SLL | TA(OTHER_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
+		if (op & SLJIT_SET_Z)
+			FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		return push_inst(compiler, SRL | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG);
 
 	case SLJIT_SUBC:
 		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
@@ -277,28 +343,31 @@
 			flags &= ~SRC2_IMM;
 		}
 
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_C)
-				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+			if (is_carry)
+				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
 			/* dst may be the same as src1 or src2. */
 			FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
 		}
 		else {
-			if (op & SLJIT_SET_C)
-				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+			if (is_carry)
+				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
 			/* dst may be the same as src1 or src2. */
 			FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
 
-		if (op & SLJIT_SET_C)
-			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG));
+		if (is_carry)
+			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
 
-		FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
-		return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
+		FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
+		return (is_carry) ? push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG) : SLJIT_SUCCESS;
 
 	case SLJIT_MUL:
 		SLJIT_ASSERT(!(flags & SRC2_IMM));
-		if (!(op & SLJIT_SET_O)) {
+
+		if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
 #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
 			return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
 #else
@@ -307,10 +376,10 @@
 #endif
 		}
 		FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
-		FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG));
+		FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
 		FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
-		FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG));
-		return push_inst(compiler, SUBU | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+		FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
+		return push_inst(compiler, SUBU | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
 
 	case SLJIT_AND:
 		EMIT_LOGICAL(ANDI, AND);
@@ -337,7 +406,7 @@
 		return SLJIT_SUCCESS;
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 }
 
@@ -347,20 +416,251 @@
 	return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
-	inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
-	inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
+	inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+	inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 2);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
 	inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
 	inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 2);
 }
+
+static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
+{
+	sljit_s32 stack_offset = 0;
+	sljit_s32 arg_count = 0;
+	sljit_s32 float_arg_count = 0;
+	sljit_s32 word_arg_count = 0;
+	sljit_s32 types = 0;
+	sljit_s32 arg_count_save, types_save;
+	sljit_ins prev_ins = NOP;
+	sljit_ins ins = NOP;
+	sljit_u8 offsets[4];
+
+	SLJIT_ASSERT(reg_map[TMP_REG3] == 4 && freg_map[TMP_FREG1] == 12);
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
+
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			offsets[arg_count] = (sljit_u8)stack_offset;
+
+			if (word_arg_count == 0 && arg_count <= 1)
+				offsets[arg_count] = 254 + arg_count;
+
+			stack_offset += sizeof(sljit_f32);
+			arg_count++;
+			float_arg_count++;
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (stack_offset & 0x7)
+				stack_offset += sizeof(sljit_sw);
+			offsets[arg_count] = (sljit_u8)stack_offset;
+
+			if (word_arg_count == 0 && arg_count <= 1)
+				offsets[arg_count] = 254 + arg_count;
+
+			stack_offset += sizeof(sljit_f64);
+			arg_count++;
+			float_arg_count++;
+			break;
+		default:
+			offsets[arg_count] = (sljit_u8)stack_offset;
+			stack_offset += sizeof(sljit_sw);
+			arg_count++;
+			word_arg_count++;
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	/* Stack is aligned to 16 bytes, max two doubles can be placed on the stack. */
+	if (stack_offset > 16)
+		FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-16), DR(SLJIT_SP)));
+
+	types_save = types;
+	arg_count_save = arg_count;
+
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			arg_count--;
+			if (offsets[arg_count] < 254)
+				ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(offsets[arg_count]);
+			float_arg_count--;
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			arg_count--;
+			if (offsets[arg_count] < 254)
+				ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(offsets[arg_count]);
+			float_arg_count--;
+			break;
+		default:
+			if (offsets[arg_count - 1] >= 16)
+				ins = SW | S(SLJIT_SP) | T(word_arg_count) | IMM(offsets[arg_count - 1]);
+			else if (arg_count != word_arg_count)
+				ins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (offsets[arg_count - 1] >> 2));
+			else if (arg_count == 1)
+				ins = ADDU | S(SLJIT_R0) | TA(0) | D(TMP_REG3);
+
+			arg_count--;
+			word_arg_count--;
+			break;
+		}
+
+		if (ins != NOP) {
+			if (prev_ins != NOP)
+				FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
+			prev_ins = ins;
+			ins = NOP;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
+	types = types_save;
+	arg_count = arg_count_save;
+
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			arg_count--;
+			if (offsets[arg_count] == 254)
+				ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
+			else if (offsets[arg_count] < 16)
+				ins = LW | S(SLJIT_SP) | TA(4 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count]);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			arg_count--;
+			if (offsets[arg_count] == 254)
+				ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
+			else if (offsets[arg_count] < 16) {
+				if (prev_ins != NOP)
+					FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
+				prev_ins = LW | S(SLJIT_SP) | TA(4 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count]);
+				ins = LW | S(SLJIT_SP) | TA(5 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count] + sizeof(sljit_sw));
+			}
+			break;
+		default:
+			arg_count--;
+			break;
+		}
+
+		if (ins != NOP) {
+			if (prev_ins != NOP)
+				FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
+			prev_ins = ins;
+			ins = NOP;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
+	*ins_ptr = prev_ins;
+
+	return SLJIT_SUCCESS;
+}
+
+static sljit_s32 post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
+{
+	sljit_s32 stack_offset = 0;
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			stack_offset += sizeof(sljit_f32);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (stack_offset & 0x7)
+				stack_offset += sizeof(sljit_sw);
+			stack_offset += sizeof(sljit_f64);
+			break;
+		default:
+			stack_offset += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	/* Stack is aligned to 16 bytes, max two doubles can be placed on the stack. */
+	if (stack_offset > 16)
+		return push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(16), DR(SLJIT_SP));
+
+	return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	struct sljit_jump *jump;
+	sljit_ins ins;
+
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+	PTR_FAIL_IF(!jump);
+	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+	type &= 0xff;
+
+	PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
+
+	SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+
+	PTR_FAIL_IF(emit_const(compiler, PIC_ADDR_REG, 0));
+
+	jump->flags |= IS_JAL | IS_CALL;
+	PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+	jump->addr = compiler->size;
+	PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
+
+	PTR_FAIL_IF(post_call_with_args(compiler, arg_types));
+
+	return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_ins ins;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+	SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+
+	if (src & SLJIT_IMM)
+		FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
+	else if (FAST_IS_REG(src))
+		FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
+	else if (src & SLJIT_MEM) {
+		ADJUST_LOCAL_OFFSET(src, srcw);
+		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
+	}
+
+	FAIL_IF(call_with_args(compiler, arg_types, &ins));
+
+	/* Register input. */
+	FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+	FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
+	return post_call_with_args(compiler, arg_types);
+}
diff --git a/dist2/src/sljit/sljitNativeMIPS_64.c b/dist2/src/sljit/sljitNativeMIPS_64.c
index c7ee8c9..ff6f048 100644
--- a/dist2/src/sljit/sljitNativeMIPS_64.c
+++ b/dist2/src/sljit/sljitNativeMIPS_64.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -123,15 +123,15 @@
 
 #define EMIT_LOGICAL(op_imm, op_norm) \
 	if (flags & SRC2_IMM) { \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
 	} \
 	else { \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
 	}
 
@@ -144,16 +144,16 @@
 		} \
 		else \
 			ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
 	} \
 	else { \
 		ins = (op & SLJIT_I32_OP) ? op_v : op_dv; \
-		if (op & SLJIT_SET_E) \
+		if (op & SLJIT_SET_Z) \
 			FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
-		if (CHECK_FLAGS(SLJIT_SET_E)) \
+		if (!(flags & UNUSED_DEST)) \
 			FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \
 	}
 
@@ -161,6 +161,7 @@
 	sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
 {
 	sljit_ins ins;
+	sljit_s32 is_overflow, is_carry, is_handled;
 
 	switch (GET_OPCODE(op)) {
 	case SLJIT_MOV:
@@ -180,8 +181,9 @@
 			}
 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
 		}
-		else if (dst != src2)
-			SLJIT_ASSERT_STOP();
+		else {
+			SLJIT_ASSERT(dst == src2);
+		}
 		return SLJIT_SUCCESS;
 
 	case SLJIT_MOV_U16:
@@ -194,8 +196,9 @@
 			}
 			return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
 		}
-		else if (dst != src2)
-			SLJIT_ASSERT_STOP();
+		else {
+			SLJIT_ASSERT(dst == src2);
+		}
 		return SLJIT_SUCCESS;
 
 	case SLJIT_MOV_U32:
@@ -209,18 +212,18 @@
 
 	case SLJIT_NOT:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
-		if (op & SLJIT_SET_E)
+		if (op & SLJIT_SET_Z)
 			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-		if (CHECK_FLAGS(SLJIT_SET_E))
+		if (!(flags & UNUSED_DEST))
 			FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
 		return SLJIT_SUCCESS;
 
 	case SLJIT_CLZ:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
 #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
-		if (op & SLJIT_SET_E)
+		if (op & SLJIT_SET_Z)
 			FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
-		if (CHECK_FLAGS(SLJIT_SET_E))
+		if (!(flags & UNUSED_DEST))
 			FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst)));
 #else
 		if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
@@ -237,130 +240,192 @@
 		FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst)));
 		FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
 		FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
-		if (op & SLJIT_SET_E)
-			return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
 #endif
 		return SLJIT_SUCCESS;
 
 	case SLJIT_ADD:
+		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_O) {
+			if (is_overflow) {
 				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
 				else
-					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
 			}
-			if (op & SLJIT_SET_E)
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
-			if (op & (SLJIT_SET_C | SLJIT_SET_O)) {
+
+			if (is_overflow || is_carry) {
 				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
 				else {
-					FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
-					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+					FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
+					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
 				}
 			}
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
 		}
 		else {
-			if (op & SLJIT_SET_O)
-				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-			if (op & SLJIT_SET_E)
+			if (is_overflow)
+				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-			if (op & (SLJIT_SET_C | SLJIT_SET_O))
-				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+
+			if (is_overflow || is_carry)
+				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
 
 		/* a + b >= a | b (otherwise, the carry should be set to 1). */
-		if (op & (SLJIT_SET_C | SLJIT_SET_O))
-			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
-		if (!(op & SLJIT_SET_O))
+		if (is_overflow || is_carry)
+			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
+		if (!is_overflow)
 			return SLJIT_SUCCESS;
-		FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
-		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+		FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(OTHER_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
+		if (op & SLJIT_SET_Z)
+			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG);
 
 	case SLJIT_ADDC:
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_C) {
+			if (is_carry) {
 				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
 				else {
-					FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
-					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+					FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
+					FAIL_IF(push_inst(compiler, OR | S(src1) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
 				}
 			}
 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
 		} else {
-			if (op & SLJIT_SET_C)
-				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+			if (is_carry)
+				FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
 			/* dst may be the same as src1 or src2. */
 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
-		if (op & SLJIT_SET_C)
-			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+		if (is_carry)
+			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
 
-		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
-		if (!(op & SLJIT_SET_C))
+		FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
+		if (!is_carry)
 			return SLJIT_SUCCESS;
 
-		/* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
-		FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+		/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
+		FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
 		/* Set carry flag. */
-		return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG);
+		return push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
 
 	case SLJIT_SUB:
-		if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
+		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
 			FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
 			src2 = TMP_REG2;
 			flags &= ~SRC2_IMM;
 		}
 
+		is_handled = 0;
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_O) {
-				if (src2 >= 0)
-					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-				else
-					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+			if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
+				is_handled = 1;
 			}
-			if (op & SLJIT_SET_E)
+			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
+				is_handled = 1;
+			}
+		}
+
+		if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
+			is_handled = 1;
+
+			if (flags & SRC2_IMM) {
+				FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+				src2 = TMP_REG2;
+				flags &= ~SRC2_IMM;
+			}
+
+			if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+			else if (GET_FLAG_TYPE(op) == SLJIT_GREATER || GET_FLAG_TYPE(op) == SLJIT_LESS_EQUAL)
+			{
+				FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) {
+				FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+			else if (GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER || GET_FLAG_TYPE(op) == SLJIT_SIG_LESS_EQUAL)
+			{
+				FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
+			}
+		}
+
+		if (is_handled) {
+			if (flags & SRC2_IMM) {
+				if (op & SLJIT_SET_Z)
+					FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
+				if (!(flags & UNUSED_DEST))
+					return push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst));
+			}
+			else {
+				if (op & SLJIT_SET_Z)
+					FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+				if (!(flags & UNUSED_DEST))
+					return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst));
+			}
+			return SLJIT_SUCCESS;
+		}
+
+		is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
+		if (flags & SRC2_IMM) {
+			if (is_overflow) {
+				if (src2 >= 0)
+					FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
+				else
+					FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
+			}
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
-			if (op & (SLJIT_SET_C | SLJIT_SET_O))
-				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+
+			if (is_overflow || is_carry)
+				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
 		}
 		else {
-			if (op & SLJIT_SET_O)
-				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-			if (op & SLJIT_SET_E)
+			if (is_overflow)
+				FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+			else if (op & SLJIT_SET_Z)
 				FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-			if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
-				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
-			if (op & SLJIT_SET_U)
-				FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
-			if (op & SLJIT_SET_S) {
-				FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
-				FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
-			}
+
+			if (is_overflow || is_carry)
+				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
 			/* dst may be the same as src1 or src2. */
-			if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
+			if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
 				FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
 
-		if (!(op & SLJIT_SET_O))
+		if (!is_overflow)
 			return SLJIT_SUCCESS;
-		FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
-		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-		return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+		FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(OTHER_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
+		FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
+		if (op & SLJIT_SET_Z)
+			FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
+		return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG);
 
 	case SLJIT_SUBC:
 		if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
@@ -369,28 +434,31 @@
 			flags &= ~SRC2_IMM;
 		}
 
+		is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
+
 		if (flags & SRC2_IMM) {
-			if (op & SLJIT_SET_C)
-				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG));
+			if (is_carry)
+				FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
 			/* dst may be the same as src1 or src2. */
 			FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
 		}
 		else {
-			if (op & SLJIT_SET_C)
-				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+			if (is_carry)
+				FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
 			/* dst may be the same as src1 or src2. */
 			FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
 		}
 
-		if (op & SLJIT_SET_C)
-			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG));
+		if (is_carry)
+			FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
 
-		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
-		return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
+		FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
+		return (is_carry) ? push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG) : SLJIT_SUCCESS;
 
 	case SLJIT_MUL:
 		SLJIT_ASSERT(!(flags & SRC2_IMM));
-		if (!(op & SLJIT_SET_O)) {
+
+		if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
 #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
 			if (op & SLJIT_I32_OP)
 				return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
@@ -402,10 +470,10 @@
 #endif
 		}
 		FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
-		FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG));
+		FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
 		FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
-		FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG));
-		return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+		FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
+		return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
 
 	case SLJIT_AND:
 		EMIT_LOGICAL(ANDI, AND);
@@ -432,7 +500,7 @@
 		return SLJIT_SUCCESS;
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 }
 
@@ -446,24 +514,155 @@
 	return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
-	inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
-	inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
-	inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
-	inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff);
+	inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
+	inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
+	inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+	inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 6);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
 	inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
 	inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
 	inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
 	inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 6);
 }
+
+static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
+{
+	sljit_s32 arg_count = 0;
+	sljit_s32 word_arg_count = 0;
+	sljit_s32 float_arg_count = 0;
+	sljit_s32 types = 0;
+	sljit_ins prev_ins = NOP;
+	sljit_ins ins = NOP;
+
+	SLJIT_ASSERT(reg_map[TMP_REG3] == 4 && freg_map[TMP_FREG1] == 12);
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
+
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+		case SLJIT_ARG_TYPE_F64:
+			arg_count++;
+			float_arg_count++;
+			break;
+		default:
+			arg_count++;
+			word_arg_count++;
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			if (arg_count != float_arg_count)
+				ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count);
+			else if (arg_count == 1)
+				ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
+			arg_count--;
+			float_arg_count--;
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (arg_count != float_arg_count)
+				ins = MOV_S | FMT_D | FS(float_arg_count) | FD(arg_count);
+			else if (arg_count == 1)
+				ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
+			arg_count--;
+			float_arg_count--;
+			break;
+		default:
+			if (arg_count != word_arg_count)
+				ins = DADDU | S(word_arg_count) | TA(0) | D(arg_count);
+			else if (arg_count == 1)
+				ins = DADDU | S(SLJIT_R0) | TA(0) | D(TMP_REG3);
+			arg_count--;
+			word_arg_count--;
+			break;
+		}
+
+		if (ins != NOP) {
+			if (prev_ins != NOP)
+				FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
+			prev_ins = ins;
+			ins = NOP;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
+	*ins_ptr = prev_ins;
+
+	return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	struct sljit_jump *jump;
+	sljit_ins ins;
+
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+	PTR_FAIL_IF(!jump);
+	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+	type &= 0xff;
+
+	PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
+
+	SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+
+	PTR_FAIL_IF(emit_const(compiler, PIC_ADDR_REG, 0));
+
+	jump->flags |= IS_JAL | IS_CALL;
+	PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+	jump->addr = compiler->size;
+	PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
+
+	return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_ins ins;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+	SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+
+	if (src & SLJIT_IMM)
+		FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
+	else if (FAST_IS_REG(src))
+		FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
+	else if (src & SLJIT_MEM) {
+		ADJUST_LOCAL_OFFSET(src, srcw);
+		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
+	}
+
+	FAIL_IF(call_with_args(compiler, arg_types, &ins));
+
+	/* Register input. */
+	FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+	return push_inst(compiler, ins, UNMOVABLE_INS);
+}
diff --git a/dist2/src/sljit/sljitNativeMIPS_common.c b/dist2/src/sljit/sljitNativeMIPS_common.c
index c2c251b..e108433 100644
--- a/dist2/src/sljit/sljitNativeMIPS_common.c
+++ b/dist2/src/sljit/sljitNativeMIPS_common.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -57,21 +57,30 @@
 #define RETURN_ADDR_REG	31
 
 /* Flags are kept in volatile registers. */
-#define EQUAL_FLAG	12
-/* And carry flag as well. */
-#define ULESS_FLAG	13
-#define UGREATER_FLAG	14
-#define LESS_FLAG	15
-#define GREATER_FLAG	31
-#define OVERFLOW_FLAG	1
+#define EQUAL_FLAG	31
+#define OTHER_FLAG	1
 
-#define TMP_FREG1	(0)
-#define TMP_FREG2	((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
+#define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
 
 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
-	0, 2, 5, 6, 7, 8, 9, 10, 11, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4
+	0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4
 };
 
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
+	0, 0, 14, 2, 4, 6, 8, 12, 10
+};
+
+#else
+
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
+	0, 0, 13, 14, 15, 16, 17, 12, 18
+};
+
+#endif
+
 /* --------------------------------------------------------------------- */
 /*  Instrucion forms                                                     */
 /* --------------------------------------------------------------------- */
@@ -79,21 +88,23 @@
 #define S(s)		(reg_map[s] << 21)
 #define T(t)		(reg_map[t] << 16)
 #define D(d)		(reg_map[d] << 11)
+#define FT(t)		(freg_map[t] << 16)
+#define FS(s)		(freg_map[s] << 11)
+#define FD(d)		(freg_map[d] << 6)
 /* Absolute registers. */
 #define SA(s)		((s) << 21)
 #define TA(t)		((t) << 16)
 #define DA(d)		((d) << 11)
-#define FT(t)		((t) << 16)
-#define FS(s)		((s) << 11)
-#define FD(d)		((d) << 6)
 #define IMM(imm)	((imm) & 0xffff)
 #define SH_IMM(imm)	((imm) << 6)
 
 #define DR(dr)		(reg_map[dr])
+#define FR(dr)		(freg_map[dr])
 #define HI(opcode)	((opcode) << 26)
 #define LO(opcode)	(opcode)
 /* S = (16 << 21) D = (17 << 21) */
 #define FMT_S		(16 << 21)
+#define FMT_D		(17 << 21)
 
 #define ABS_S		(HI(17) | FMT_S | LO(5))
 #define ADD_S		(HI(17) | FMT_S | LO(0))
@@ -158,6 +169,7 @@
 #define OR		(HI(0) | LO(37))
 #define ORI		(HI(13))
 #define SD		(HI(63))
+#define SDC1		(HI(61))
 #define SLT		(HI(0) | LO(42))
 #define SLTI		(HI(10))
 #define SLTIU		(HI(11))
@@ -171,6 +183,7 @@
 #define SUB_S		(HI(17) | FMT_S | LO(1))
 #define SUBU		(HI(0) | LO(35))
 #define SW		(HI(43))
+#define SWC1		(HI(57))
 #define TRUNC_W_S	(HI(17) | FMT_S | LO(13))
 #define XOR		(HI(0) | LO(38))
 #define XORI		(HI(14))
@@ -178,7 +191,13 @@
 #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
 #define CLZ		(HI(28) | LO(32))
 #define DCLZ		(HI(28) | LO(36))
+#define MOVF		(HI(0) | (0 << 16) | LO(1))
+#define MOVN		(HI(0) | LO(11))
+#define MOVT		(HI(0) | (1 << 16) | LO(1))
+#define MOVZ		(HI(0) | LO(10))
 #define MUL		(HI(28) | LO(2))
+#define PREF		(HI(51))
+#define PREFX		(HI(19) | LO(15))
 #define SEB		(HI(31) | (16 << 6) | LO(32))
 #define SEH		(HI(31) | (24 << 6) | LO(32))
 #endif
@@ -218,7 +237,7 @@
 	return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
 }
 
-static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+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;
@@ -237,9 +256,10 @@
 		target_addr = jump->u.target;
 	else {
 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-		target_addr = (sljit_uw)(code + jump->u.label->size);
+		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
 	}
-	inst = (sljit_ins*)jump->addr;
+
+	inst = (sljit_ins *)jump->addr;
 	if (jump->flags & IS_COND)
 		inst--;
 
@@ -250,7 +270,7 @@
 
 	/* B instructions. */
 	if (jump->flags & IS_MOVABLE) {
-		diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
+		diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
 		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
 			jump->flags |= PATCH_B;
 
@@ -268,7 +288,7 @@
 		}
 	}
 	else {
-		diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1)) >> 2;
+		diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
 		if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
 			jump->flags |= PATCH_B;
 
@@ -364,6 +384,7 @@
 	sljit_ins *buf_ptr;
 	sljit_ins *buf_end;
 	sljit_uw word_count;
+	sljit_sw executable_offset;
 	sljit_uw addr;
 
 	struct sljit_label *label;
@@ -380,9 +401,12 @@
 
 	code_ptr = code;
 	word_count = 0;
+	executable_offset = SLJIT_EXEC_OFFSET(code);
+
 	label = compiler->labels;
 	jump = compiler->jumps;
 	const_ = compiler->consts;
+
 	do {
 		buf_ptr = (sljit_ins*)buf->memory;
 		buf_end = buf_ptr + (buf->used_size >> 2);
@@ -393,8 +417,7 @@
 			SLJIT_ASSERT(!const_ || const_->addr >= word_count);
 			/* These structures are ordered by their address. */
 			if (label && label->size == word_count) {
-				/* Just recording the address. */
-				label->addr = (sljit_uw)code_ptr;
+				label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 				label->size = code_ptr - code;
 				label = label->next;
 			}
@@ -404,7 +427,7 @@
 #else
 				jump->addr = (sljit_uw)(code_ptr - 7);
 #endif
-				code_ptr = detect_jump_type(jump, code_ptr, code);
+				code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
 				jump = jump->next;
 			}
 			if (const_ && const_->addr == word_count) {
@@ -434,16 +457,16 @@
 	while (jump) {
 		do {
 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-			buf_ptr = (sljit_ins*)jump->addr;
+			buf_ptr = (sljit_ins *)jump->addr;
 
 			if (jump->flags & PATCH_B) {
-				addr = (sljit_sw)(addr - (jump->addr + sizeof(sljit_ins))) >> 2;
+				addr = (sljit_sw)(addr - ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins))) >> 2;
 				SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
 				buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff);
 				break;
 			}
 			if (jump->flags & PATCH_J) {
-				SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff));
+				SLJIT_ASSERT((addr & ~0xfffffff) == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~0xfffffff));
 				buf_ptr[0] |= (addr >> 2) & 0x03ffffff;
 				break;
 			}
@@ -476,7 +499,12 @@
 	}
 
 	compiler->error = SLJIT_ERR_COMPILED;
+	compiler->executable_offset = executable_offset;
 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+
+	code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+	code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
 #ifndef __GNUC__
 	SLJIT_CACHE_FLUSH(code, code_ptr);
 #else
@@ -486,6 +514,32 @@
 	return code;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	sljit_sw fir = 0;
+
+	switch (feature_type) {
+	case SLJIT_HAS_FPU:
+#ifdef SLJIT_IS_FPU_AVAILABLE
+		return SLJIT_IS_FPU_AVAILABLE;
+#elif defined(__GNUC__)
+		asm ("cfc1 %0, $0" : "=r"(fir));
+		return (fir >> 22) & 0x1;
+#else
+#error "FIR check is not implemented for this architecture"
+#endif
+
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+	case SLJIT_HAS_CLZ:
+	case SLJIT_HAS_CMOV:
+		return 1;
+#endif
+
+	default:
+		return fir;
+	}
+}
+
 /* --------------------------------------------------------------------- */
 /*  Entry, exit                                                          */
 /* --------------------------------------------------------------------- */
@@ -504,25 +558,20 @@
 
 #define MEM_MASK	0x1f
 
-#define WRITE_BACK	0x00020
-#define ARG_TEST	0x00040
-#define ALT_KEEP_CACHE	0x00080
-#define CUMULATIVE_OP	0x00100
-#define LOGICAL_OP	0x00200
-#define IMM_OP		0x00400
-#define SRC2_IMM	0x00800
+#define ARG_TEST	0x00020
+#define ALT_KEEP_CACHE	0x00040
+#define CUMULATIVE_OP	0x00080
+#define LOGICAL_OP	0x00100
+#define IMM_OP		0x00200
+#define SRC2_IMM	0x00400
 
-#define UNUSED_DEST	0x01000
-#define REG_DEST	0x02000
-#define REG1_SOURCE	0x04000
-#define REG2_SOURCE	0x08000
-#define SLOW_SRC1	0x10000
-#define SLOW_SRC2	0x20000
-#define SLOW_DEST	0x40000
-
-/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */
-#define CHECK_FLAGS(list) \
-	(!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
+#define UNUSED_DEST	0x00800
+#define REG_DEST	0x01000
+#define REG1_SOURCE	0x02000
+#define REG2_SOURCE	0x04000
+#define SLOW_SRC1	0x08000
+#define SLOW_SRC2	0x10000
+#define SLOW_DEST	0x20000
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #define STACK_STORE	SW
@@ -532,6 +581,8 @@
 #define STACK_LOAD	LD
 #endif
 
+static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
+
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #include "sljitNativeMIPS_32.c"
 #else
@@ -539,15 +590,15 @@
 #endif
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	sljit_ins base;
-	sljit_s32 i, tmp, offs;
+	sljit_s32 args, i, tmp, offs;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
@@ -584,6 +635,8 @@
 		FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS));
 	}
 
+	args = get_arg_count(arg_types);
+
 	if (args >= 1)
 		FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_S0), DR(SLJIT_S0)));
 	if (args >= 2)
@@ -595,12 +648,12 @@
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
@@ -702,7 +755,7 @@
 {
 	SLJIT_ASSERT(arg & SLJIT_MEM);
 
-	if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) && !(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
+	if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
 		/* Works for both absoulte and relative addresses. */
 		if (SLJIT_UNLIKELY(flags & ARG_TEST))
 			return 1;
@@ -760,33 +813,21 @@
 
 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
 		argw &= 0x3;
-		if ((flags & WRITE_BACK) && reg_ar == DR(base)) {
-			SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
-			FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
-			reg_ar = DR(TMP_REG1);
-		}
 
 		/* Using the cache. */
 		if (argw == compiler->cache_argw) {
-			if (!(flags & WRITE_BACK)) {
-				if (arg == compiler->cache_arg)
+			if (arg == compiler->cache_arg)
+				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
+
+			if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
+				if (arg == next_arg && argw == (next_argw & 0x3)) {
+					compiler->cache_arg = arg;
+					compiler->cache_argw = argw;
+					FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
 					return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
-				if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
-					if (arg == next_arg && argw == (next_argw & 0x3)) {
-						compiler->cache_arg = arg;
-						compiler->cache_argw = argw;
-						FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
-						return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
-					}
-					FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
-					return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
 				}
-			}
-			else {
-				if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
-					FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
-					return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
-				}
+				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
+				return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
 			}
 		}
 
@@ -796,55 +837,15 @@
 			FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
 		}
 
-		if (!(flags & WRITE_BACK)) {
-			if (arg == next_arg && argw == (next_argw & 0x3)) {
-				compiler->cache_arg = arg;
-				compiler->cache_argw = argw;
-				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
-				tmp_ar = DR(TMP_REG3);
-			}
-			else
-				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
-			return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
+		if (arg == next_arg && argw == (next_argw & 0x3)) {
+			compiler->cache_arg = arg;
+			compiler->cache_argw = argw;
+			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
+			tmp_ar = DR(TMP_REG3);
 		}
-		FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(base), DR(base)));
-		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
-	}
-
-	if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
-		/* Update only applies if a base register exists. */
-		if (reg_ar == DR(base)) {
-			SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
-			if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
-				FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS));
-				if (argw)
-					return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base));
-				return SLJIT_SUCCESS;
-			}
-			FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
-			reg_ar = DR(TMP_REG1);
-		}
-
-		if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
-			if (argw)
-				FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)));
-		}
-		else {
-			if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
-				if (argw != compiler->cache_argw) {
-					FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
-					compiler->cache_argw = argw;
-				}
-				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
-			}
-			else {
-				compiler->cache_arg = SLJIT_MEM;
-				compiler->cache_argw = argw;
-				FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
-				FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
-			}
-		}
-		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
+		else
+			FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
+		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
 	}
 
 	if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
@@ -914,15 +915,13 @@
 	}
 
 	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
-			return SLJIT_SUCCESS;
-		if (GET_FLAGS(op))
-			flags |= UNUSED_DEST;
+		SLJIT_ASSERT(HAS_FLAGS(op));
+		flags |= UNUSED_DEST;
 	}
 	else if (FAST_IS_REG(dst)) {
 		dst_r = dst;
 		flags |= REG_DEST;
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+		if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
 			sugg_src2_r = dst_r;
 	}
 	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
@@ -976,7 +975,7 @@
 	if (FAST_IS_REG(src2)) {
 		src2_r = src2;
 		flags |= REG2_SOURCE;
-		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
 			dst_r = src2_r;
 	}
 	else if (src2 & SLJIT_IMM) {
@@ -987,7 +986,7 @@
 			}
 			else {
 				src2_r = 0;
-				if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
+				if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))
 					dst_r = 0;
 			}
 		}
@@ -1079,6 +1078,29 @@
 	return SLJIT_SUCCESS;
 }
 
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
+        sljit_s32 src, sljit_sw srcw)
+{
+	if (!(src & OFFS_REG_MASK)) {
+		if (srcw <= SIMM_MAX && srcw >= SIMM_MIN)
+			return push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);
+
+		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
+		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
+	}
+
+	srcw &= 0x3;
+
+	if (SLJIT_UNLIKELY(srcw != 0)) {
+		FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));
+		return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
+	}
+
+	return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
+}
+#endif
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
@@ -1094,12 +1116,17 @@
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-	if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT) {
-		flags |= INT_DATA | SIGNED_DATA;
-		if (src & SLJIT_IMM)
-			srcw = (sljit_s32)srcw;
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+		if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
+			return emit_prefetch(compiler, src, srcw);
+#endif
+		return SLJIT_SUCCESS;
 	}
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+	if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT)
+		flags |= INT_DATA | SIGNED_DATA;
 #endif
 
 	switch (GET_OPCODE(op)) {
@@ -1133,36 +1160,6 @@
 	case SLJIT_MOV_S16:
 		return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
 
-	case SLJIT_MOVU:
-	case SLJIT_MOVU_P:
-		return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
-	case SLJIT_MOVU_U32:
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-#else
-		return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
-#endif
-
-	case SLJIT_MOVU_S32:
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-		return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-#else
-		return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
-#endif
-
-	case SLJIT_MOVU_U8:
-		return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
-
-	case SLJIT_MOVU_S8:
-		return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
-
-	case SLJIT_MOVU_U16:
-		return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
-
-	case SLJIT_MOVU_S16:
-		return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
-
 	case SLJIT_NOT:
 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
 
@@ -1173,6 +1170,7 @@
 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
 	}
 
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
@@ -1197,6 +1195,9 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
+
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
 	if (op & SLJIT_I32_OP) {
 		flags |= INT_DATA | SIGNED_DATA;
@@ -1241,6 +1242,7 @@
 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
 	}
 
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
@@ -1257,7 +1259,7 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
 {
 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
-	return reg << 1;
+	return FR(reg);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
@@ -1273,19 +1275,6 @@
 /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-#ifdef SLJIT_IS_FPU_AVAILABLE
-	return SLJIT_IS_FPU_AVAILABLE;
-#elif defined(__GNUC__)
-	sljit_sw fir;
-	asm ("cfc1 %0, $0" : "=r"(fir));
-	return (fir >> 22) & 0x1;
-#else
-#error "FIR check is not implemented for this architecture"
-#endif
-}
-
 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
 #define FMT(op) (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) << (21 - 8))
 
@@ -1300,22 +1289,17 @@
 #endif
 
 	if (src & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
 		src = TMP_FREG1;
 	}
-	else
-		src <<= 1;
 
 	FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (FAST_IS_REG(dst))
 		return push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS);
 
 	/* Store the integer value from a VFP register. */
-	return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
+	return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #	undef is_long
@@ -1332,13 +1316,13 @@
 	sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21;
 #endif
 
-	sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
 	if (FAST_IS_REG(src))
 		FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
 	else if (src & SLJIT_MEM) {
 		/* Load the integer value into a VFP register. */
-		FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+		FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
 	}
 	else {
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -1352,7 +1336,7 @@
 	FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
 
 	if (dst & SLJIT_MEM)
-		return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
+		return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
 	return SLJIT_SUCCESS;
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
@@ -1364,39 +1348,38 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
+	sljit_ins inst;
+
 	if (src1 & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
 		src1 = TMP_FREG1;
 	}
-	else
-		src1 <<= 1;
 
 	if (src2 & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));
 		src2 = TMP_FREG2;
 	}
-	else
-		src2 <<= 1;
 
-	/* src2 and src1 are swapped. */
-	if (op & SLJIT_SET_E) {
-		FAIL_IF(push_inst(compiler, C_UEQ_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS));
-		FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG));
-		FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG));
-		FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG));
+	switch (GET_FLAG_TYPE(op)) {
+	case SLJIT_EQUAL_F64:
+	case SLJIT_NOT_EQUAL_F64:
+		inst = C_UEQ_S;
+		break;
+	case SLJIT_LESS_F64:
+	case SLJIT_GREATER_EQUAL_F64:
+		inst = C_ULT_S;
+		break;
+	case SLJIT_GREATER_F64:
+	case SLJIT_LESS_EQUAL_F64:
+		inst = C_ULE_S;
+		break;
+	default:
+		SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED_F64 || GET_FLAG_TYPE(op) == SLJIT_ORDERED_F64);
+		inst = C_UN_S;
+		break;
 	}
-	if (op & SLJIT_SET_S) {
-		/* Mixing the instructions for the two checks. */
-		FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS));
-		FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG));
-		FAIL_IF(push_inst(compiler, C_ULT_S | FMT(op) | FT(src1) | FS(src2), UNMOVABLE_INS));
-		FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG));
-		FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG));
-		FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG));
-		FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG));
-		FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG));
-	}
-	return push_inst(compiler, C_UN_S | FMT(op) | FT(src2) | FS(src1), FCSR_FCC);
+
+	return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
@@ -1415,14 +1398,12 @@
 	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
 		op ^= SLJIT_F32_OP;
 
-	dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
 	if (src & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));
 		src = dst_r;
 	}
-	else
-		src <<= 1;
 
 	switch (GET_OPCODE(op)) {
 	case SLJIT_MOV_F64:
@@ -1446,7 +1427,7 @@
 	}
 
 	if (dst & SLJIT_MEM)
-		return emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0);
+		return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);
 	return SLJIT_SUCCESS;
 }
 
@@ -1466,42 +1447,38 @@
 	compiler->cache_arg = 0;
 	compiler->cache_argw = 0;
 
-	dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
 
 	if (src1 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
+		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {
 			FAIL_IF(compiler->error);
 			src1 = TMP_FREG1;
 		} else
 			flags |= SLOW_SRC1;
 	}
-	else
-		src1 <<= 1;
 
 	if (src2 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
+		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {
 			FAIL_IF(compiler->error);
 			src2 = TMP_FREG2;
 		} else
 			flags |= SLOW_SRC2;
 	}
-	else
-		src2 <<= 1;
 
 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
+			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
 		}
 		else {
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
+			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
 		}
 	}
 	else if (flags & SLOW_SRC1)
-		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
+		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
 	else if (flags & SLOW_SRC2)
-		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
+		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
 
 	if (flags & SLOW_SRC1)
 		src1 = TMP_FREG1;
@@ -1527,7 +1504,7 @@
 	}
 
 	if (dst_r == TMP_FREG2)
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
+		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
 
 	return SLJIT_SUCCESS;
 }
@@ -1542,10 +1519,6 @@
 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	/* For UNUSED dst. Uncommon, but possible. */
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (FAST_IS_REG(dst))
 		return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst));
 
@@ -1561,10 +1534,8 @@
 
 	if (FAST_IS_REG(src))
 		FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
-	else if (src & SLJIT_MEM)
+	else
 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
-	else if (src & SLJIT_IMM)
-		FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw));
 
 	FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
 	return push_inst(compiler, NOP, UNMOVABLE_INS);
@@ -1634,55 +1605,39 @@
 
 	switch (type) {
 	case SLJIT_EQUAL:
-	case SLJIT_NOT_EQUAL_F64:
 		BR_NZ(EQUAL_FLAG);
 		break;
 	case SLJIT_NOT_EQUAL:
-	case SLJIT_EQUAL_F64:
 		BR_Z(EQUAL_FLAG);
 		break;
 	case SLJIT_LESS:
-	case SLJIT_LESS_F64:
-		BR_Z(ULESS_FLAG);
-		break;
-	case SLJIT_GREATER_EQUAL:
-	case SLJIT_GREATER_EQUAL_F64:
-		BR_NZ(ULESS_FLAG);
-		break;
 	case SLJIT_GREATER:
-	case SLJIT_GREATER_F64:
-		BR_Z(UGREATER_FLAG);
-		break;
-	case SLJIT_LESS_EQUAL:
-	case SLJIT_LESS_EQUAL_F64:
-		BR_NZ(UGREATER_FLAG);
-		break;
 	case SLJIT_SIG_LESS:
-		BR_Z(LESS_FLAG);
-		break;
-	case SLJIT_SIG_GREATER_EQUAL:
-		BR_NZ(LESS_FLAG);
-		break;
 	case SLJIT_SIG_GREATER:
-		BR_Z(GREATER_FLAG);
-		break;
-	case SLJIT_SIG_LESS_EQUAL:
-		BR_NZ(GREATER_FLAG);
-		break;
 	case SLJIT_OVERFLOW:
 	case SLJIT_MUL_OVERFLOW:
-		BR_Z(OVERFLOW_FLAG);
+		BR_Z(OTHER_FLAG);
 		break;
+	case SLJIT_GREATER_EQUAL:
+	case SLJIT_LESS_EQUAL:
+	case SLJIT_SIG_GREATER_EQUAL:
+	case SLJIT_SIG_LESS_EQUAL:
 	case SLJIT_NOT_OVERFLOW:
 	case SLJIT_MUL_NOT_OVERFLOW:
-		BR_NZ(OVERFLOW_FLAG);
+		BR_NZ(OTHER_FLAG);
 		break;
-	case SLJIT_UNORDERED_F64:
-		BR_F();
-		break;
+	case SLJIT_NOT_EQUAL_F64:
+	case SLJIT_GREATER_EQUAL_F64:
+	case SLJIT_GREATER_F64:
 	case SLJIT_ORDERED_F64:
 		BR_T();
 		break;
+	case SLJIT_EQUAL_F64:
+	case SLJIT_LESS_F64:
+	case SLJIT_LESS_EQUAL_F64:
+	case SLJIT_UNORDERED_F64:
+		BR_F();
+		break;
 	default:
 		/* Not conditional branch. */
 		inst = 0;
@@ -1697,19 +1652,16 @@
 		PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
 
 	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
-	if (type <= SLJIT_JUMP) {
+
+	if (type <= SLJIT_JUMP)
 		PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
-		jump->addr = compiler->size;
-		PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-	} else {
-		SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
-		/* Cannot be optimized out if type is >= CALL0. */
-		jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? IS_CALL : 0);
+	else {
+		jump->flags |= IS_JAL;
 		PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
-		jump->addr = compiler->size;
-		/* A NOP if type < CALL1. */
-		PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS));
 	}
+
+	jump->addr = compiler->size;
+	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
 	return jump;
 }
 
@@ -1854,86 +1806,6 @@
 #undef RESOLVE_IMM1
 #undef RESOLVE_IMM2
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
-	sljit_s32 src1, sljit_sw src1w,
-	sljit_s32 src2, sljit_sw src2w)
-{
-	struct sljit_jump *jump;
-	sljit_ins inst;
-	sljit_s32 if_true;
-
-	CHECK_ERROR_PTR();
-	CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
-
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-
-	if (src1 & SLJIT_MEM) {
-		PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
-		src1 = TMP_FREG1;
-	}
-	else
-		src1 <<= 1;
-
-	if (src2 & SLJIT_MEM) {
-		PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
-		src2 = TMP_FREG2;
-	}
-	else
-		src2 <<= 1;
-
-	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
-	PTR_FAIL_IF(!jump);
-	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
-	jump->flags |= IS_BIT16_COND;
-
-	switch (type & 0xff) {
-	case SLJIT_EQUAL_F64:
-		inst = C_UEQ_S;
-		if_true = 1;
-		break;
-	case SLJIT_NOT_EQUAL_F64:
-		inst = C_UEQ_S;
-		if_true = 0;
-		break;
-	case SLJIT_LESS_F64:
-		inst = C_ULT_S;
-		if_true = 1;
-		break;
-	case SLJIT_GREATER_EQUAL_F64:
-		inst = C_ULT_S;
-		if_true = 0;
-		break;
-	case SLJIT_GREATER_F64:
-		inst = C_ULE_S;
-		if_true = 0;
-		break;
-	case SLJIT_LESS_EQUAL_F64:
-		inst = C_ULE_S;
-		if_true = 1;
-		break;
-	case SLJIT_UNORDERED_F64:
-		inst = C_UN_S;
-		if_true = 1;
-		break;
-	default: /* Make compilers happy. */
-		SLJIT_ASSERT_STOP();
-	case SLJIT_ORDERED_F64:
-		inst = C_UN_S;
-		if_true = 0;
-		break;
-	}
-
-	PTR_FAIL_IF(push_inst(compiler, inst | FMT(type) | FT(src2) | FS(src1), UNMOVABLE_INS));
-	/* Intentionally the other opcode. */
-	PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS));
-	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
-	PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
-	jump->addr = compiler->size;
-	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-	return jump;
-}
-
 #undef JUMP_LENGTH
 #undef BR_Z
 #undef BR_NZ
@@ -1945,41 +1817,12 @@
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
 {
-	sljit_s32 src_r = TMP_REG2;
 	struct sljit_jump *jump = NULL;
 
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-	if (FAST_IS_REG(src)) {
-		if (DR(src) != 4)
-			src_r = src;
-		else
-			FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
-	}
-
-	if (type >= SLJIT_CALL0) {
-		SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
-		if (src & (SLJIT_IMM | SLJIT_MEM)) {
-			if (src & SLJIT_IMM)
-				FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
-			else {
-				SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
-				FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
-			}
-			FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
-			/* We need an extra instruction in any case. */
-			return push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS);
-		}
-
-		/* Register input. */
-		if (type >= SLJIT_CALL1)
-			FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), 4));
-		FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
-		return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS);
-	}
-
 	if (src & SLJIT_IMM) {
 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 		FAIL_IF(!jump);
@@ -1990,11 +1833,14 @@
 			jump->flags |= IS_MOVABLE;
 
 		FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+		src = TMP_REG2;
 	}
-	else if (src & SLJIT_MEM)
-		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+	else if (src & SLJIT_MEM) {
+		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src, srcw));
+		src = TMP_REG2;
+	}
 
-	FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS));
+	FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
 	if (jump)
 		jump->addr = compiler->size;
 	FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
@@ -2003,115 +1849,160 @@
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
-	sljit_s32 sugg_dst_ar, dst_ar;
-	sljit_s32 flags = GET_ALL_FLAGS(op);
+	sljit_s32 src_ar, dst_ar;
+	sljit_s32 saved_op = op;
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#	define mem_type WORD_DATA
+	sljit_s32 mem_type = WORD_DATA;
 #else
 	sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
 #endif
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	op = GET_OPCODE(op);
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-	if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32)
+	if (op == SLJIT_MOV_S32)
 		mem_type = INT_DATA | SIGNED_DATA;
 #endif
-	sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
+	dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
 
 	compiler->cache_arg = 0;
 	compiler->cache_argw = 0;
-	if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
-		ADJUST_LOCAL_OFFSET(src, srcw);
-		FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw));
-		src = TMP_REG1;
-		srcw = 0;
-	}
+
+	if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
+		FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), dst, dstw, dst, dstw));
 
 	switch (type & 0xff) {
 	case SLJIT_EQUAL:
 	case SLJIT_NOT_EQUAL:
-		FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
-		dst_ar = sugg_dst_ar;
-		break;
-	case SLJIT_LESS:
-	case SLJIT_GREATER_EQUAL:
-	case SLJIT_LESS_F64:
-	case SLJIT_GREATER_EQUAL_F64:
-		dst_ar = ULESS_FLAG;
-		break;
-	case SLJIT_GREATER:
-	case SLJIT_LESS_EQUAL:
-	case SLJIT_GREATER_F64:
-	case SLJIT_LESS_EQUAL_F64:
-		dst_ar = UGREATER_FLAG;
-		break;
-	case SLJIT_SIG_LESS:
-	case SLJIT_SIG_GREATER_EQUAL:
-		dst_ar = LESS_FLAG;
-		break;
-	case SLJIT_SIG_GREATER:
-	case SLJIT_SIG_LESS_EQUAL:
-		dst_ar = GREATER_FLAG;
-		break;
-	case SLJIT_OVERFLOW:
-	case SLJIT_NOT_OVERFLOW:
-		dst_ar = OVERFLOW_FLAG;
+		FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
+		src_ar = dst_ar;
 		break;
 	case SLJIT_MUL_OVERFLOW:
 	case SLJIT_MUL_NOT_OVERFLOW:
-		FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
-		dst_ar = sugg_dst_ar;
+		FAIL_IF(push_inst(compiler, SLTIU | SA(OTHER_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
+		src_ar = dst_ar;
 		type ^= 0x1; /* Flip type bit for the XORI below. */
 		break;
+	case SLJIT_GREATER_F64:
+	case SLJIT_LESS_EQUAL_F64:
+		type ^= 0x1; /* Flip type bit for the XORI below. */
 	case SLJIT_EQUAL_F64:
 	case SLJIT_NOT_EQUAL_F64:
-		dst_ar = EQUAL_FLAG;
-		break;
-
+	case SLJIT_LESS_F64:
+	case SLJIT_GREATER_EQUAL_F64:
 	case SLJIT_UNORDERED_F64:
 	case SLJIT_ORDERED_F64:
-		FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar));
-		FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar));
-		FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
-		dst_ar = sugg_dst_ar;
+		FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
+		FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
+		FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
+		src_ar = dst_ar;
 		break;
 
 	default:
-		SLJIT_ASSERT_STOP();
-		dst_ar = sugg_dst_ar;
+		src_ar = OTHER_FLAG;
 		break;
 	}
 
 	if (type & 0x1) {
-		FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
-		dst_ar = sugg_dst_ar;
+		FAIL_IF(push_inst(compiler, XORI | SA(src_ar) | TA(dst_ar) | IMM(1), dst_ar));
+		src_ar = dst_ar;
 	}
 
-	if (op >= SLJIT_ADD) {
-		if (DR(TMP_REG2) != dst_ar)
-			FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
-		return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
+	if (op < SLJIT_ADD) {
+		if (dst & SLJIT_MEM)
+			return emit_op_mem(compiler, mem_type, src_ar, dst, dstw);
+
+		if (src_ar != dst_ar)
+			return push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | DA(dst_ar), dst_ar);
+		return SLJIT_SUCCESS;
 	}
 
+	/* OTHER_FLAG cannot be specified as src2 argument at the moment. */
+	if (DR(TMP_REG2) != src_ar)
+		FAIL_IF(push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+
+	mem_type |= CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE;
+
 	if (dst & SLJIT_MEM)
-		return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);
+		return emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+	return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0);
+}
 
-	if (sugg_dst_ar != dst_ar)
-		return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar);
-	return SLJIT_SUCCESS;
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+	sljit_ins ins;
+#endif
 
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-#	undef mem_type
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+
+	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+		if (dst_reg & SLJIT_I32_OP)
+			srcw = (sljit_s32)srcw;
+#endif
+		FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
+		src = TMP_REG1;
+		srcw = 0;
+	}
+
+	dst_reg &= ~SLJIT_I32_OP;
+
+	switch (type & 0xff) {
+	case SLJIT_EQUAL:
+		ins = MOVZ | TA(EQUAL_FLAG);
+		break;
+	case SLJIT_NOT_EQUAL:
+		ins = MOVN | TA(EQUAL_FLAG);
+		break;
+	case SLJIT_LESS:
+	case SLJIT_GREATER:
+	case SLJIT_SIG_LESS:
+	case SLJIT_SIG_GREATER:
+	case SLJIT_OVERFLOW:
+	case SLJIT_MUL_OVERFLOW:
+		ins = MOVN | TA(OTHER_FLAG);
+		break;
+	case SLJIT_GREATER_EQUAL:
+	case SLJIT_LESS_EQUAL:
+	case SLJIT_SIG_GREATER_EQUAL:
+	case SLJIT_SIG_LESS_EQUAL:
+	case SLJIT_NOT_OVERFLOW:
+	case SLJIT_MUL_NOT_OVERFLOW:
+		ins = MOVZ | TA(OTHER_FLAG);
+		break;
+	case SLJIT_EQUAL_F64:
+	case SLJIT_LESS_F64:
+	case SLJIT_LESS_EQUAL_F64:
+	case SLJIT_UNORDERED_F64:
+		ins = MOVT;
+		break;
+	case SLJIT_NOT_EQUAL_F64:
+	case SLJIT_GREATER_EQUAL_F64:
+	case SLJIT_GREATER_F64:
+	case SLJIT_ORDERED_F64:
+		ins = MOVF;
+		break;
+	default:
+		ins = MOVZ | TA(OTHER_FLAG);
+		SLJIT_UNREACHABLE();
+		break;
+	}
+
+	return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg));
+
+#else
+	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
 #endif
 }
 
@@ -2128,7 +2019,7 @@
 	PTR_FAIL_IF(!const_);
 	set_const(const_, compiler);
 
-	reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+	reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
 
 	PTR_FAIL_IF(emit_const(compiler, reg, init_value));
 
diff --git a/dist2/src/sljit/sljitNativePPC_32.c b/dist2/src/sljit/sljitNativePPC_32.c
index 0f23cf8..fc185f7 100644
--- a/dist2/src/sljit/sljitNativePPC_32.c
+++ b/dist2/src/sljit/sljitNativePPC_32.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -88,77 +88,86 @@
 
 	case SLJIT_NEG:
 		SLJIT_ASSERT(src1 == TMP_REG1);
-		return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+		/* Setting XER SO is not enough, CR SO is also needed. */
+		return push_inst(compiler, NEG | OE((flags & ALT_FORM1) ? ALT_SET_FLAGS : 0) | RC(flags) | D(dst) | A(src2));
 
 	case SLJIT_CLZ:
 		SLJIT_ASSERT(src1 == TMP_REG1);
-		return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
+		return push_inst(compiler, CNTLZW | S(src2) | A(dst));
 
 	case SLJIT_ADD:
 		if (flags & ALT_FORM1) {
-			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
-			SLJIT_ASSERT(src2 == TMP_REG2);
-			return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+			/* Setting XER SO is not enough, CR SO is also needed. */
+			return push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
 		}
+
 		if (flags & ALT_FORM2) {
 			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
 			SLJIT_ASSERT(src2 == TMP_REG2);
-			return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+
+			if (flags & ALT_FORM3)
+				return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+
+			if (flags & ALT_FORM4) {
+				FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))));
+				src1 = dst;
+			}
+
+			return push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff));
 		}
 		if (flags & ALT_FORM3) {
 			SLJIT_ASSERT(src2 == TMP_REG2);
 			return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
 		}
-		if (flags & ALT_FORM4) {
-			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
-			FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
-			return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
-		}
 		if (!(flags & ALT_SET_FLAGS))
 			return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
-		return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+		if (flags & ALT_FORM4)
+			return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+		return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
 
 	case SLJIT_ADDC:
-		if (flags & ALT_FORM1) {
-			FAIL_IF(push_inst(compiler, MFXER | D(0)));
-			FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
-			return push_inst(compiler, MTXER | S(0));
-		}
 		return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
 
 	case SLJIT_SUB:
 		if (flags & ALT_FORM1) {
+			if (flags & ALT_FORM2) {
+				FAIL_IF(push_inst(compiler, CMPLI | CRD(0) | A(src1) | compiler->imm));
+				if (!(flags & ALT_FORM3))
+					return SLJIT_SUCCESS;
+				return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
+			}
+			FAIL_IF(push_inst(compiler, CMPL | CRD(0) | A(src1) | B(src2)));
+			if (!(flags & ALT_FORM3))
+				return SLJIT_SUCCESS;
+			return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+		}
+
+		if (flags & ALT_FORM2) {
+			/* Setting XER SO is not enough, CR SO is also needed. */
+			return push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+		}
+
+		if (flags & ALT_FORM3) {
 			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
 			SLJIT_ASSERT(src2 == TMP_REG2);
 			return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
 		}
-		if (flags & (ALT_FORM2 | ALT_FORM3)) {
-			SLJIT_ASSERT(src2 == TMP_REG2);
-			if (flags & ALT_FORM2)
-				FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));
-			if (flags & ALT_FORM3)
-				return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm);
-			return SLJIT_SUCCESS;
+
+		if (flags & ALT_FORM4) {
+			if (flags & ALT_FORM5) {
+				SLJIT_ASSERT(src2 == TMP_REG2);
+				return push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm);
+			}
+			return push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2));
 		}
-		if (flags & (ALT_FORM4 | ALT_FORM5)) {
-			if (flags & ALT_FORM4)
-				FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
-			if (flags & ALT_FORM5)
-				FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));
-			return SLJIT_SUCCESS;
-		}
+
 		if (!(flags & ALT_SET_FLAGS))
 			return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
-		if (flags & ALT_FORM6)
-			FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
-		return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+		if (flags & ALT_FORM5)
+			return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+		return push_inst(compiler, SUBF | RC(flags) | D(dst) | A(src2) | B(src1));
 
 	case SLJIT_SUBC:
-		if (flags & ALT_FORM1) {
-			FAIL_IF(push_inst(compiler, MFXER | D(0)));
-			FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
-			return push_inst(compiler, MTXER | S(0));
-		}
 		return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
 
 	case SLJIT_MUL:
@@ -166,7 +175,7 @@
 			SLJIT_ASSERT(src2 == TMP_REG2);
 			return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
 		}
-		return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
+		return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
 
 	case SLJIT_AND:
 		if (flags & ALT_FORM1) {
@@ -228,19 +237,15 @@
 		return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
 
 	case SLJIT_ASHR:
-		if (flags & ALT_FORM3)
-			FAIL_IF(push_inst(compiler, MFXER | D(0)));
 		if (flags & ALT_FORM1) {
 			SLJIT_ASSERT(src2 == TMP_REG2);
 			compiler->imm &= 0x1f;
-			FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
+			return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
 		}
-		else
-			FAIL_IF(push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)));
-		return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS;
+		return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 }
 
@@ -250,20 +255,22 @@
 	return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
-	inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
-	inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
+	inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+	inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 2);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
 	inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
 	inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 2);
 }
diff --git a/dist2/src/sljit/sljitNativePPC_64.c b/dist2/src/sljit/sljitNativePPC_64.c
index 8e3223f..706b2ba 100644
--- a/dist2/src/sljit/sljitNativePPC_64.c
+++ b/dist2/src/sljit/sljitNativePPC_64.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -204,84 +204,118 @@
 
 	case SLJIT_NEG:
 		SLJIT_ASSERT(src1 == TMP_REG1);
+
+		if ((flags & (ALT_FORM1 | ALT_SIGN_EXT)) == (ALT_FORM1 | ALT_SIGN_EXT)) {
+			FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
+			FAIL_IF(push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(TMP_REG2)));
+			return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
+		}
+
 		UN_EXTS();
-		return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+		/* Setting XER SO is not enough, CR SO is also needed. */
+		return push_inst(compiler, NEG | OE((flags & ALT_FORM1) ? ALT_SET_FLAGS : 0) | RC(flags) | D(dst) | A(src2));
 
 	case SLJIT_CLZ:
 		SLJIT_ASSERT(src1 == TMP_REG1);
 		if (flags & ALT_FORM1)
-			return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
-		return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst));
+			return push_inst(compiler, CNTLZW | S(src2) | A(dst));
+		return push_inst(compiler, CNTLZD | S(src2) | A(dst));
 
 	case SLJIT_ADD:
 		if (flags & ALT_FORM1) {
-			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
-			SLJIT_ASSERT(src2 == TMP_REG2);
-			return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+			if (flags & ALT_SIGN_EXT) {
+				FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, src1, 32, 31, 1)));
+				src1 = TMP_REG1;
+				FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
+				src2 = TMP_REG2;
+			}
+			/* Setting XER SO is not enough, CR SO is also needed. */
+			FAIL_IF(push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)));
+			if (flags & ALT_SIGN_EXT)
+				return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
+			return SLJIT_SUCCESS;
 		}
+
 		if (flags & ALT_FORM2) {
 			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
 			SLJIT_ASSERT(src2 == TMP_REG2);
-			return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+
+			if (flags & ALT_FORM3)
+				return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+
+			if (flags & ALT_FORM4) {
+				FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))));
+				src1 = dst;
+			}
+
+			return push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff));
 		}
 		if (flags & ALT_FORM3) {
 			SLJIT_ASSERT(src2 == TMP_REG2);
 			BIN_IMM_EXTS();
 			return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
 		}
-		if (flags & ALT_FORM4) {
-			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
-			FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
-			return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
-		}
 		if (!(flags & ALT_SET_FLAGS))
 			return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
 		BIN_EXTS();
-		return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+		if (flags & ALT_FORM4)
+			return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+		return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
 
 	case SLJIT_ADDC:
-		if (flags & ALT_FORM1) {
-			FAIL_IF(push_inst(compiler, MFXER | D(0)));
-			FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
-			return push_inst(compiler, MTXER | S(0));
-		}
 		BIN_EXTS();
 		return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
 
 	case SLJIT_SUB:
 		if (flags & ALT_FORM1) {
+			if (flags & ALT_FORM2) {
+				FAIL_IF(push_inst(compiler, CMPLI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
+				if (!(flags & ALT_FORM3))
+					return SLJIT_SUCCESS;
+				return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
+			}
+			FAIL_IF(push_inst(compiler, CMPL | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+			if (!(flags & ALT_FORM3))
+				return SLJIT_SUCCESS;
+			return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+		}
+
+		if (flags & ALT_FORM2) {
+			if (flags & ALT_SIGN_EXT) {
+				FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, src1, 32, 31, 1)));
+				src1 = TMP_REG1;
+				FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
+				src2 = TMP_REG2;
+			}
+			/* Setting XER SO is not enough, CR SO is also needed. */
+			FAIL_IF(push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)));
+			if (flags & ALT_SIGN_EXT)
+				return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
+			return SLJIT_SUCCESS;
+		}
+
+		if (flags & ALT_FORM3) {
 			/* Flags does not set: BIN_IMM_EXTS unnecessary. */
 			SLJIT_ASSERT(src2 == TMP_REG2);
 			return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
 		}
-		if (flags & (ALT_FORM2 | ALT_FORM3)) {
-			SLJIT_ASSERT(src2 == TMP_REG2);
-			if (flags & ALT_FORM2)
-				FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
-			if (flags & ALT_FORM3)
-				return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
-			return SLJIT_SUCCESS;
+
+		if (flags & ALT_FORM4) {
+			if (flags & ALT_FORM5) {
+				SLJIT_ASSERT(src2 == TMP_REG2);
+				return push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
+			}
+			return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
 		}
-		if (flags & (ALT_FORM4 | ALT_FORM5)) {
-			if (flags & ALT_FORM4)
-				FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
-			if (flags & ALT_FORM5)
-				return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
-			return SLJIT_SUCCESS;
-		}
+
 		if (!(flags & ALT_SET_FLAGS))
 			return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
 		BIN_EXTS();
-		if (flags & ALT_FORM6)
-			FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
-		return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+		if (flags & ALT_FORM5)
+			return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+		return push_inst(compiler, SUBF | RC(flags) | D(dst) | A(src2) | B(src1));
 
 	case SLJIT_SUBC:
-		if (flags & ALT_FORM1) {
-			FAIL_IF(push_inst(compiler, MFXER | D(0)));
-			FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
-			return push_inst(compiler, MTXER | S(0));
-		}
 		BIN_EXTS();
 		return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
 
@@ -292,8 +326,8 @@
 		}
 		BIN_EXTS();
 		if (flags & ALT_FORM2)
-			return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
-		return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1));
+			return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
+		return push_inst(compiler, MULLD | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
 
 	case SLJIT_AND:
 		if (flags & ALT_FORM1) {
@@ -345,10 +379,8 @@
 				compiler->imm &= 0x1f;
 				return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
 			}
-			else {
-				compiler->imm &= 0x3f;
-				return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
-			}
+			compiler->imm &= 0x3f;
+			return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
 		}
 		return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));
 
@@ -359,33 +391,80 @@
 				compiler->imm &= 0x1f;
 				return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
 			}
-			else {
-				compiler->imm &= 0x3f;
-				return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
-			}
+			compiler->imm &= 0x3f;
+			return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
 		}
 		return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));
 
 	case SLJIT_ASHR:
-		if (flags & ALT_FORM3)
-			FAIL_IF(push_inst(compiler, MFXER | D(0)));
 		if (flags & ALT_FORM1) {
 			SLJIT_ASSERT(src2 == TMP_REG2);
 			if (flags & ALT_FORM2) {
 				compiler->imm &= 0x1f;
-				FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
+				return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
 			}
-			else {
-				compiler->imm &= 0x3f;
-				FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4)));
-			}
+			compiler->imm &= 0x3f;
+			return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));
 		}
-		else
-			FAIL_IF(push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2)));
-		return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS;
+		return push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2));
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
+	return SLJIT_SUCCESS;
+}
+
+static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
+{
+	sljit_s32 arg_count = 0;
+	sljit_s32 word_arg_count = 0;
+	sljit_s32 types = 0;
+	sljit_s32 reg = 0;
+
+	if (src)
+		reg = *src & REG_MASK;
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
+
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+		case SLJIT_ARG_TYPE_F64:
+			arg_count++;
+			break;
+		default:
+			arg_count++;
+			word_arg_count++;
+
+			if (arg_count != word_arg_count && arg_count == reg) {
+				FAIL_IF(push_inst(compiler, OR | S(reg) | A(TMP_CALL_REG) | B(reg)));
+				*src = TMP_CALL_REG;
+			}
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+		case SLJIT_ARG_TYPE_F64:
+			arg_count--;
+			break;
+		default:
+			if (arg_count != word_arg_count)
+				FAIL_IF(push_inst(compiler, OR | S(word_arg_count) | A(arg_count) | B(word_arg_count)));
+
+			arg_count--;
+			word_arg_count--;
+			break;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
 	return SLJIT_SUCCESS;
 }
 
@@ -398,18 +477,19 @@
 	return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
 	sljit_ins *inst = (sljit_ins*)addr;
 
-	inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
-	inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
-	inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
-	inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff);
+	inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
+	inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
+	inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
+	inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 5);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
 	sljit_ins *inst = (sljit_ins*)addr;
 
@@ -417,5 +497,6 @@
 	inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
 	inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
 	inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 5);
 }
diff --git a/dist2/src/sljit/sljitNativePPC_common.c b/dist2/src/sljit/sljitNativePPC_common.c
index a364732..5ef4ac9 100644
--- a/dist2/src/sljit/sljitNativePPC_common.c
+++ b/dist2/src/sljit/sljitNativePPC_common.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -93,20 +93,23 @@
 
 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
-#define TMP_ZERO	(SLJIT_NUMBER_OF_REGISTERS + 5)
+#define TMP_ZERO	(SLJIT_NUMBER_OF_REGISTERS + 4)
 
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
-#define TMP_CALL_REG	(SLJIT_NUMBER_OF_REGISTERS + 6)
+#define TMP_CALL_REG	(SLJIT_NUMBER_OF_REGISTERS + 5)
 #else
 #define TMP_CALL_REG	TMP_REG2
 #endif
 
-#define TMP_FREG1	(0)
-#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
 
 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
-	0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12
+	0, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 9, 10, 31, 12
+};
+
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
+	0, 1, 2, 3, 4, 5, 6, 0, 7
 };
 
 /* --------------------------------------------------------------------- */
@@ -117,19 +120,19 @@
 #define A(a)		(reg_map[a] << 16)
 #define B(b)		(reg_map[b] << 11)
 #define C(c)		(reg_map[c] << 6)
-#define FD(fd)		((fd) << 21)
-#define FS(fs)		((fs) << 21)
-#define FA(fa)		((fa) << 16)
-#define FB(fb)		((fb) << 11)
-#define FC(fc)		((fc) << 6)
+#define FD(fd)		(freg_map[fd] << 21)
+#define FS(fs)		(freg_map[fs] << 21)
+#define FA(fa)		(freg_map[fa] << 16)
+#define FB(fb)		(freg_map[fb] << 11)
+#define FC(fc)		(freg_map[fc] << 6)
 #define IMM(imm)	((imm) & 0xffff)
 #define CRD(d)		((d) << 21)
 
 /* Instruction bit sections.
    OE and Rc flag (see ALT_SET_FLAGS). */
-#define OERC(flags)	(((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
+#define OE(flags)	((flags) & ALT_SET_FLAGS)
 /* Rc flag (see ALT_SET_FLAGS). */
-#define RC(flags)	((flags & ALT_SET_FLAGS) >> 10)
+#define RC(flags)	(((flags) & ALT_SET_FLAGS) >> 10)
 #define HI(opcode)	((opcode) << 26)
 #define LO(opcode)	((opcode) << 1)
 
@@ -154,6 +157,7 @@
 #define CMPL		(HI(31) | LO(32))
 #define CMPLI		(HI(10))
 #define CROR		(HI(19) | LO(449))
+#define DCBT		(HI(31) | LO(278))
 #define DIVD		(HI(31) | LO(489))
 #define DIVDU		(HI(31) | LO(457))
 #define DIVW		(HI(31) | LO(491))
@@ -249,7 +253,7 @@
 	return SLJIT_SUCCESS;
 }
 
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+static SLJIT_INLINE sljit_s32 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;
@@ -267,7 +271,7 @@
 		target_addr = jump->u.target;
 	else {
 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-		target_addr = (sljit_uw)(code + jump->u.label->size);
+		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
 	}
 
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
@@ -275,7 +279,7 @@
 		goto keep_address;
 #endif
 
-	diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l;
+	diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;
 
 	extra_jump_flags = 0;
 	if (jump->flags & IS_COND) {
@@ -296,6 +300,7 @@
 		jump->flags |= PATCH_B | extra_jump_flags;
 		return 1;
 	}
+
 	if (target_addr <= 0x03ffffff) {
 		jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
 		return 1;
@@ -309,6 +314,7 @@
 		jump->flags |= PATCH_ABS32;
 		return 1;
 	}
+
 	if (target_addr <= 0x7fffffffffffl) {
 		jump->flags |= PATCH_ABS48;
 		return 1;
@@ -326,6 +332,7 @@
 	sljit_ins *buf_ptr;
 	sljit_ins *buf_end;
 	sljit_uw word_count;
+	sljit_sw executable_offset;
 	sljit_uw addr;
 
 	struct sljit_label *label;
@@ -349,9 +356,12 @@
 
 	code_ptr = code;
 	word_count = 0;
+	executable_offset = SLJIT_EXEC_OFFSET(code);
+
 	label = compiler->labels;
 	jump = compiler->jumps;
 	const_ = compiler->consts;
+
 	do {
 		buf_ptr = (sljit_ins*)buf->memory;
 		buf_end = buf_ptr + (buf->used_size >> 2);
@@ -363,7 +373,7 @@
 			/* These structures are ordered by their address. */
 			if (label && label->size == word_count) {
 				/* Just recording the address. */
-				label->addr = (sljit_uw)code_ptr;
+				label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 				label->size = code_ptr - code;
 				label = label->next;
 			}
@@ -373,7 +383,7 @@
 #else
 				jump->addr = (sljit_uw)(code_ptr - 6);
 #endif
-				if (detect_jump_type(jump, code_ptr, code)) {
+				if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
 					code_ptr[-3] = code_ptr[0];
 					code_ptr -= 3;
@@ -420,7 +430,7 @@
 	} while (buf);
 
 	if (label && label->size == word_count) {
-		label->addr = (sljit_uw)code_ptr;
+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 		label->size = code_ptr - code;
 		label = label->next;
 	}
@@ -438,11 +448,12 @@
 	while (jump) {
 		do {
 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-			buf_ptr = (sljit_ins*)jump->addr;
+			buf_ptr = (sljit_ins *)jump->addr;
+
 			if (jump->flags & PATCH_B) {
 				if (jump->flags & IS_COND) {
 					if (!(jump->flags & PATCH_ABS_B)) {
-						addr = addr - jump->addr;
+						addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
 						SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
 						*buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
 					}
@@ -453,7 +464,7 @@
 				}
 				else {
 					if (!(jump->flags & PATCH_ABS_B)) {
-						addr = addr - jump->addr;
+						addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
 						SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
 						*buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
 					}
@@ -464,6 +475,7 @@
 				}
 				break;
 			}
+
 			/* Set the fields of immediate loads. */
 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
 			buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
@@ -492,24 +504,49 @@
 	}
 
 	compiler->error = SLJIT_ERR_COMPILED;
+	compiler->executable_offset = executable_offset;
 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
-	SLJIT_CACHE_FLUSH(code, code_ptr);
+
+	code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
 
 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 	if (((sljit_sw)code_ptr) & 0x4)
 		code_ptr++;
-	sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
-	return code_ptr;
-#else
-	sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
-	return code_ptr;
 #endif
+	sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
+#endif
+
+	code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+	SLJIT_CACHE_FLUSH(code, code_ptr);
+
+#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+	return code_ptr;
 #else
 	return code;
 #endif
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	switch (feature_type) {
+	case SLJIT_HAS_FPU:
+#ifdef SLJIT_IS_FPU_AVAILABLE
+		return SLJIT_IS_FPU_AVAILABLE;
+#else
+		/* Available by default. */
+		return 1;
+#endif
+
+	case SLJIT_HAS_CLZ:
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
 /* --------------------------------------------------------------------- */
 /*  Entry, exit                                                          */
 /* --------------------------------------------------------------------- */
@@ -519,47 +556,40 @@
 /* Creates an index in data_transfer_insts array. */
 #define LOAD_DATA	0x01
 #define INDEXED		0x02
-#define WRITE_BACK	0x04
+#define SIGNED_DATA	0x04
+
 #define WORD_DATA	0x00
 #define BYTE_DATA	0x08
 #define HALF_DATA	0x10
 #define INT_DATA	0x18
-#define SIGNED_DATA	0x20
 /* Separates integer and floating point registers */
-#define GPR_REG		0x3f
-#define DOUBLE_DATA	0x40
+#define GPR_REG		0x1f
+#define DOUBLE_DATA	0x20
 
 #define MEM_MASK	0x7f
 
 /* Other inp_flags. */
 
-#define ARG_TEST	0x000100
 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
-#define ALT_SIGN_EXT	0x000200
+#define ALT_SIGN_EXT	0x000100
 /* This flag affects the RC() and OERC() macros. */
 #define ALT_SET_FLAGS	0x000400
-#define ALT_KEEP_CACHE	0x000800
-#define ALT_FORM1	0x010000
-#define ALT_FORM2	0x020000
-#define ALT_FORM3	0x040000
-#define ALT_FORM4	0x080000
-#define ALT_FORM5	0x100000
-#define ALT_FORM6	0x200000
+#define ALT_FORM1	0x001000
+#define ALT_FORM2	0x002000
+#define ALT_FORM3	0x004000
+#define ALT_FORM4	0x008000
+#define ALT_FORM5	0x010000
 
 /* Source and destination is register. */
 #define REG_DEST	0x000001
 #define REG1_SOURCE	0x000002
 #define REG2_SOURCE	0x000004
-/* getput_arg_fast returned true. */
-#define FAST_DEST	0x000008
-/* Multiple instructions are required. */
-#define SLOW_DEST	0x000010
 /*
-ALT_SIGN_EXT		0x000200
-ALT_SET_FLAGS		0x000400
-ALT_FORM1		0x010000
+ALT_SIGN_EXT		0x000100
+ALT_SET_FLAGS		0x000200
+ALT_FORM1		0x001000
 ...
-ALT_FORM6		0x200000 */
+ALT_FORM5		0x010000 */
 
 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
 #include "sljitNativePPC_32.c"
@@ -576,14 +606,14 @@
 #endif
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 i, tmp, offs;
+	sljit_s32 args, i, tmp, offs;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	FAIL_IF(push_inst(compiler, MFLR | D(0)));
 	offs = -(sljit_s32)(sizeof(sljit_sw));
@@ -609,6 +639,9 @@
 #endif
 
 	FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0));
+
+	args = get_arg_count(arg_types);
+
 	if (args >= 1)
 		FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0)));
 	if (args >= 2)
@@ -640,12 +673,12 @@
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
 	compiler->local_size = (local_size + 15) & ~0xf;
@@ -704,17 +737,17 @@
 /*  Operators                                                            */
 /* --------------------------------------------------------------------- */
 
-/* i/x - immediate/indexed form
-   n/w - no write-back / write-back (1 bit)
-   s/l - store/load (1 bit)
+/* s/l - store/load (1 bit)
+   i/x - immediate/indexed form
    u/s - signed/unsigned (1 bit)
    w/b/h/i - word/byte/half/int allowed (2 bit)
-   It contans 32 items, but not all are different. */
+
+   Some opcodes are repeated (e.g. store signed / unsigned byte is the same instruction). */
 
 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 #define INT_ALIGNED	0x10000
-/* 64-bit only: there is no lwau instruction. */
-#define UPDATE_REQ	0x20000
+#endif
 
 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
 #define ARCH_32_64(a, b)	a
@@ -723,401 +756,217 @@
 #else
 #define ARCH_32_64(a, b)	b
 #define INST_CODE_AND_DST(inst, flags, reg) \
-	(((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
+	(((inst) & ~INT_ALIGNED) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
 #endif
 
-static const sljit_ins data_transfer_insts[64 + 8] = {
+static const sljit_ins data_transfer_insts[64 + 16] = {
 
-/* -------- Unsigned -------- */
+/* -------- Integer -------- */
 
 /* Word. */
 
-/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
-/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
-/* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
-/* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+/* w u i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
+/* w u i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
+/* w u x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* w u x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
 
-/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
-/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
-/* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
-/* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+/* w s i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
+/* w s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
+/* w s x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* w s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
 
 /* Byte. */
 
-/* u b n i s */ HI(38) /* stb */, 
-/* u b n i l */ HI(34) /* lbz */,
-/* u b n x s */ HI(31) | LO(215) /* stbx */,
-/* u b n x l */ HI(31) | LO(87) /* lbzx */,
+/* b u i s */ HI(38) /* stb */,
+/* b u i l */ HI(34) /* lbz */,
+/* b u x s */ HI(31) | LO(215) /* stbx */,
+/* b u x l */ HI(31) | LO(87) /* lbzx */,
 
-/* u b w i s */ HI(39) /* stbu */,
-/* u b w i l */ HI(35) /* lbzu */,
-/* u b w x s */ HI(31) | LO(247) /* stbux */,
-/* u b w x l */ HI(31) | LO(119) /* lbzux */,
+/* b s i s */ HI(38) /* stb */,
+/* b s i l */ HI(34) /* lbz */ /* EXTS_REQ */,
+/* b s x s */ HI(31) | LO(215) /* stbx */,
+/* b s x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
 
 /* Half. */
 
-/* u h n i s */ HI(44) /* sth */,
-/* u h n i l */ HI(40) /* lhz */,
-/* u h n x s */ HI(31) | LO(407) /* sthx */,
-/* u h n x l */ HI(31) | LO(279) /* lhzx */,
+/* h u i s */ HI(44) /* sth */,
+/* h u i l */ HI(40) /* lhz */,
+/* h u x s */ HI(31) | LO(407) /* sthx */,
+/* h u x l */ HI(31) | LO(279) /* lhzx */,
 
-/* u h w i s */ HI(45) /* sthu */,
-/* u h w i l */ HI(41) /* lhzu */,
-/* u h w x s */ HI(31) | LO(439) /* sthux */,
-/* u h w x l */ HI(31) | LO(311) /* lhzux */,
+/* h s i s */ HI(44) /* sth */,
+/* h s i l */ HI(42) /* lha */,
+/* h s x s */ HI(31) | LO(407) /* sthx */,
+/* h s x l */ HI(31) | LO(343) /* lhax */,
 
 /* Int. */
 
-/* u i n i s */ HI(36) /* stw */,
-/* u i n i l */ HI(32) /* lwz */,
-/* u i n x s */ HI(31) | LO(151) /* stwx */,
-/* u i n x l */ HI(31) | LO(23) /* lwzx */,
+/* i u i s */ HI(36) /* stw */,
+/* i u i l */ HI(32) /* lwz */,
+/* i u x s */ HI(31) | LO(151) /* stwx */,
+/* i u x l */ HI(31) | LO(23) /* lwzx */,
 
-/* u i w i s */ HI(37) /* stwu */,
-/* u i w i l */ HI(33) /* lwzu */,
-/* u i w x s */ HI(31) | LO(183) /* stwux */,
-/* u i w x l */ HI(31) | LO(55) /* lwzux */,
+/* i s i s */ HI(36) /* stw */,
+/* i s i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
+/* i s x s */ HI(31) | LO(151) /* stwx */,
+/* i s x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
 
-/* -------- Signed -------- */
+/* -------- Floating point -------- */
+
+/* d   i s */ HI(54) /* stfd */,
+/* d   i l */ HI(50) /* lfd */,
+/* d   x s */ HI(31) | LO(727) /* stfdx */,
+/* d   x l */ HI(31) | LO(599) /* lfdx */,
+
+/* s   i s */ HI(52) /* stfs */,
+/* s   i l */ HI(48) /* lfs */,
+/* s   x s */ HI(31) | LO(663) /* stfsx */,
+/* s   x l */ HI(31) | LO(535) /* lfsx */,
+};
+
+static const sljit_ins updated_data_transfer_insts[64] = {
+
+/* -------- Integer -------- */
 
 /* Word. */
 
-/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */),
-/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */),
-/* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
-/* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+/* w u i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
+/* w u i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
+/* w u x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* w u x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
 
-/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
-/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
-/* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
-/* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+/* w s i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */),
+/* w s i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */),
+/* w s x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* w s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
 
 /* Byte. */
 
-/* s b n i s */ HI(38) /* stb */,
-/* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */,
-/* s b n x s */ HI(31) | LO(215) /* stbx */,
-/* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
+/* b u i s */ HI(39) /* stbu */,
+/* b u i l */ HI(35) /* lbzu */,
+/* b u x s */ HI(31) | LO(247) /* stbux */,
+/* b u x l */ HI(31) | LO(119) /* lbzux */,
 
-/* s b w i s */ HI(39) /* stbu */,
-/* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */,
-/* s b w x s */ HI(31) | LO(247) /* stbux */,
-/* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
+/* b s i s */ HI(39) /* stbu */,
+/* b s i l */ 0 /* no such instruction */,
+/* b s x s */ HI(31) | LO(247) /* stbux */,
+/* b s x l */ 0 /* no such instruction */,
 
 /* Half. */
 
-/* s h n i s */ HI(44) /* sth */,
-/* s h n i l */ HI(42) /* lha */,
-/* s h n x s */ HI(31) | LO(407) /* sthx */,
-/* s h n x l */ HI(31) | LO(343) /* lhax */,
+/* h u i s */ HI(45) /* sthu */,
+/* h u i l */ HI(41) /* lhzu */,
+/* h u x s */ HI(31) | LO(439) /* sthux */,
+/* h u x l */ HI(31) | LO(311) /* lhzux */,
 
-/* s h w i s */ HI(45) /* sthu */,
-/* s h w i l */ HI(43) /* lhau */,
-/* s h w x s */ HI(31) | LO(439) /* sthux */,
-/* s h w x l */ HI(31) | LO(375) /* lhaux */,
+/* h s i s */ HI(45) /* sthu */,
+/* h s i l */ HI(43) /* lhau */,
+/* h s x s */ HI(31) | LO(439) /* sthux */,
+/* h s x l */ HI(31) | LO(375) /* lhaux */,
 
 /* Int. */
 
-/* s i n i s */ HI(36) /* stw */,
-/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */),
-/* s i n x s */ HI(31) | LO(151) /* stwx */,
-/* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
+/* i u i s */ HI(37) /* stwu */,
+/* i u i l */ HI(33) /* lwzu */,
+/* i u x s */ HI(31) | LO(183) /* stwux */,
+/* i u x l */ HI(31) | LO(55) /* lwzux */,
 
-/* s i w i s */ HI(37) /* stwu */,
-/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */),
-/* s i w x s */ HI(31) | LO(183) /* stwux */,
-/* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
+/* i s i s */ HI(37) /* stwu */,
+/* i s i l */ ARCH_32_64(HI(33) /* lwzu */, 0 /* no such instruction */),
+/* i s x s */ HI(31) | LO(183) /* stwux */,
+/* i s x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
 
-/* -------- Double -------- */
+/* -------- Floating point -------- */
 
-/* d   n i s */ HI(54) /* stfd */,
-/* d   n i l */ HI(50) /* lfd */,
-/* d   n x s */ HI(31) | LO(727) /* stfdx */,
-/* d   n x l */ HI(31) | LO(599) /* lfdx */,
+/* d   i s */ HI(55) /* stfdu */,
+/* d   i l */ HI(51) /* lfdu */,
+/* d   x s */ HI(31) | LO(759) /* stfdux */,
+/* d   x l */ HI(31) | LO(631) /* lfdux */,
 
-/* s   n i s */ HI(52) /* stfs */,
-/* s   n i l */ HI(48) /* lfs */,
-/* s   n x s */ HI(31) | LO(663) /* stfsx */,
-/* s   n x l */ HI(31) | LO(535) /* lfsx */,
-
+/* s   i s */ HI(53) /* stfsu */,
+/* s   i l */ HI(49) /* lfsu */,
+/* s   x s */ HI(31) | LO(695) /* stfsux */,
+/* s   x l */ HI(31) | LO(567) /* lfsux */,
 };
 
 #undef ARCH_32_64
 
 /* Simple cases, (no caching is required). */
-static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
+static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,
+	sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
 {
 	sljit_ins inst;
+	sljit_s32 offs_reg;
+	sljit_sw high_short;
 
 	/* Should work when (arg & REG_MASK) == 0. */
-	SLJIT_COMPILE_ASSERT(A(0) == 0, a0_must_be_0);
+	SLJIT_ASSERT(A(0) == 0);
 	SLJIT_ASSERT(arg & SLJIT_MEM);
 
-	if (arg & OFFS_REG_MASK) {
-		if (argw & 0x3)
-			return 0;
-		if (inp_flags & ARG_TEST)
-			return 1;
-
-		inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
-		SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
-		FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg))));
-		return -1;
-	}
-
-	if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
-		inp_flags &= ~WRITE_BACK;
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-	inst = data_transfer_insts[inp_flags & MEM_MASK];
-	SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
-
-	if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ))
-		return 0;
-	if (inp_flags & ARG_TEST)
-		return 1;
-#endif
-
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-	if (argw > SIMM_MAX || argw < SIMM_MIN)
-		return 0;
-	if (inp_flags & ARG_TEST)
-		return 1;
-
-	inst = data_transfer_insts[inp_flags & MEM_MASK];
-	SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
-#endif
-
-	FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw)));
-	return -1;
-}
-
-/* See getput_arg below.
-   Note: can_cache is called only for binary operators. Those operator always
-   uses word arguments without write back. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	sljit_sw high_short, next_high_short;
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-	sljit_sw diff;
-#endif
-
-	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
-
-	if (arg & OFFS_REG_MASK)
-		return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3));
-
-	if (next_arg & OFFS_REG_MASK)
-		return 0;
-
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-	high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
-	next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
-	return high_short == next_high_short;
-#else
-	if (argw <= 0x7fffffffl && argw >= -0x80000000l) {
-		high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff;
-		next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
-		if (high_short == next_high_short)
-			return 1;
-	}
-
-	diff = argw - next_argw;
-	if (!(arg & REG_MASK))
-		return diff <= SIMM_MAX && diff >= SIMM_MIN;
-
-	if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN)
-		return 1;
-
-	return 0;
-#endif
-}
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-#define ADJUST_CACHED_IMM(imm) \
-	if ((inst & INT_ALIGNED) && (imm & 0x3)) { \
-		/* Adjust cached value. Fortunately this is really a rare case */ \
-		compiler->cache_argw += imm & 0x3; \
-		FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
-		imm &= ~0x3; \
-	}
-#endif
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
-	sljit_s32 tmp_r;
-	sljit_ins inst;
-	sljit_sw high_short, next_high_short;
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-	sljit_sw diff;
-#endif
-
-	SLJIT_ASSERT(arg & SLJIT_MEM);
-
-	tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1;
-	/* Special case for "mov reg, [reg, ... ]". */
-	if ((arg & REG_MASK) == tmp_r)
-		tmp_r = TMP_REG1;
-
 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
 		argw &= 0x3;
-		/* Otherwise getput_arg_fast would capture it. */
-		SLJIT_ASSERT(argw);
+		offs_reg = OFFS_REG(arg);
 
-		if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw)
-			tmp_r = TMP_REG3;
-		else {
-			if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
-				compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
-				compiler->cache_argw = argw;
-				tmp_r = TMP_REG3;
-			}
+		if (argw != 0) {
 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-			FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1)));
+			FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_reg) | (argw << 11) | ((31 - argw) << 1)));
 #else
-			FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1)));
+			FAIL_IF(push_inst(compiler, RLDI(tmp_reg, OFFS_REG(arg), argw, 63 - argw, 1)));
 #endif
+			offs_reg = tmp_reg;
 		}
+
 		inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
-		SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
-		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
-	}
-
-	if (SLJIT_UNLIKELY(!(arg & REG_MASK)))
-		inp_flags &= ~WRITE_BACK;
-
-	inst = data_transfer_insts[inp_flags & MEM_MASK];
-	SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ));
 
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-	if (argw <= 0x7fff7fffl && argw >= -0x80000000l
-			&& (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) {
+		SLJIT_ASSERT(!(inst & INT_ALIGNED));
 #endif
 
-		arg &= REG_MASK;
+		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(offs_reg));
+	}
+
+	inst = data_transfer_insts[inp_flags & MEM_MASK];
+	arg &= REG_MASK;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+	if ((inst & INT_ALIGNED) && (argw & 0x3) != 0) {
+		FAIL_IF(load_immediate(compiler, tmp_reg, argw));
+
+		inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
+	}
+#endif
+
+	if (argw <= SIMM_MAX && argw >= SIMM_MIN)
+		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | IMM(argw));
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+	if (argw <= 0x7fff7fffl && argw >= -0x80000000l) {
+#endif
+
 		high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff;
-		/* The getput_arg_fast should handle this otherwise. */
+
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 		SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l);
 #else
-		SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ)));
+		SLJIT_ASSERT(high_short);
 #endif
 
-		if (inp_flags & WRITE_BACK) {
-			if (arg == reg) {
-				FAIL_IF(push_inst(compiler, OR | S(reg) | A(tmp_r) | B(reg)));
-				reg = tmp_r;
-			}
-			tmp_r = arg;
-			FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16)));
-		}
-		else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) {
-			if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) {
-				next_high_short = (sljit_s32)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff;
-				if (high_short == next_high_short) {
-					compiler->cache_arg = SLJIT_MEM | arg;
-					compiler->cache_argw = high_short;
-					tmp_r = TMP_REG3;
-				}
-			}
-			FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16)));
-		}
-		else
-			tmp_r = TMP_REG3;
-
-		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw));
+		FAIL_IF(push_inst(compiler, ADDIS | D(tmp_reg) | A(arg) | IMM(high_short >> 16)));
+		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_reg) | IMM(argw));
 
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 	}
 
-	/* Everything else is PPC-64 only. */
-	if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
-		diff = argw - compiler->cache_argw;
-		if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
-			ADJUST_CACHED_IMM(diff);
-			return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
-		}
+	/* The rest is PPC-64 only. */
 
-		diff = argw - next_argw;
-		if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
-			SLJIT_ASSERT(inp_flags & LOAD_DATA);
+	FAIL_IF(load_immediate(compiler, tmp_reg, argw));
 
-			compiler->cache_arg = SLJIT_IMM;
-			compiler->cache_argw = argw;
-			tmp_r = TMP_REG3;
-		}
-
-		FAIL_IF(load_immediate(compiler, tmp_r, argw));
-		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r));
-	}
-
-	diff = argw - compiler->cache_argw;
-	if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) {
-		SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ));
-		ADJUST_CACHED_IMM(diff);
-		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff));
-	}
-
-	if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
-		inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
-		SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
-		if (compiler->cache_argw != argw) {
-			FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff)));
-			compiler->cache_argw = argw;
-		}
-		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
-	}
-
-	if (argw == next_argw && (next_arg & SLJIT_MEM)) {
-		SLJIT_ASSERT(inp_flags & LOAD_DATA);
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-
-		compiler->cache_arg = SLJIT_IMM;
-		compiler->cache_argw = argw;
-
-		inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
-		SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
-		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3));
-	}
-
-	diff = argw - next_argw;
-	if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
-		SLJIT_ASSERT(inp_flags & LOAD_DATA);
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-		FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK)));
-
-		compiler->cache_arg = arg;
-		compiler->cache_argw = argw;
-
-		return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3));
-	}
-
-	if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) {
-		SLJIT_ASSERT(inp_flags & LOAD_DATA);
-		FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
-
-		compiler->cache_arg = SLJIT_IMM;
-		compiler->cache_argw = argw;
-		tmp_r = TMP_REG3;
-	}
-	else
-		FAIL_IF(load_immediate(compiler, tmp_r, argw));
-
-	/* Get the indexed version instead of the normal one. */
 	inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
-	SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ)));
-	return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r));
+	return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg) | B(tmp_reg));
 #endif
 }
 
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
-	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
-		return compiler->error;
-	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
-}
-
 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src1, sljit_sw src1w,
@@ -1125,42 +974,21 @@
 {
 	/* arg1 goes to TMP_REG1 or src reg
 	   arg2 goes to TMP_REG2, imm or src reg
-	   TMP_REG3 can be used for caching
-	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
-	sljit_s32 dst_r;
+	   result goes to TMP_REG2, so put result can use TMP_REG1. */
+	sljit_s32 dst_r = TMP_REG2;
 	sljit_s32 src1_r;
 	sljit_s32 src2_r;
 	sljit_s32 sugg_src2_r = TMP_REG2;
-	sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS);
-
-	if (!(input_flags & ALT_KEEP_CACHE)) {
-		compiler->cache_arg = 0;
-		compiler->cache_argw = 0;
-	}
+	sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
 
 	/* Destination check. */
-	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
-			return SLJIT_SUCCESS;
-		dst_r = TMP_REG2;
-	}
-	else if (FAST_IS_REG(dst)) {
+	if (SLOW_IS_REG(dst)) {
 		dst_r = dst;
 		flags |= REG_DEST;
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+
+		if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
 			sugg_src2_r = dst_r;
 	}
-	else {
-		SLJIT_ASSERT(dst & SLJIT_MEM);
-		if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
-			flags |= FAST_DEST;
-			dst_r = TMP_REG2;
-		}
-		else {
-			flags |= SLOW_DEST;
-			dst_r = 0;
-		}
-	}
 
 	/* Source 1. */
 	if (FAST_IS_REG(src1)) {
@@ -1171,80 +999,34 @@
 		FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
 		src1_r = TMP_REG1;
 	}
-	else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
-		FAIL_IF(compiler->error);
+	else {
+		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
 		src1_r = TMP_REG1;
 	}
-	else
-		src1_r = 0;
 
 	/* Source 2. */
 	if (FAST_IS_REG(src2)) {
 		src2_r = src2;
 		flags |= REG2_SOURCE;
-		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+
+		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
 			dst_r = src2_r;
 	}
 	else if (src2 & SLJIT_IMM) {
 		FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
 		src2_r = sugg_src2_r;
 	}
-	else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
-		FAIL_IF(compiler->error);
-		src2_r = sugg_src2_r;
-	}
-	else
-		src2_r = 0;
-
-	/* src1_r, src2_r and dst_r can be zero (=unprocessed).
-	   All arguments are complex addressing modes, and it is a binary operator. */
-	if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
-		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
-			FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
-			FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
-		}
-		else {
-			FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
-			FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
-		}
-		src1_r = TMP_REG1;
-		src2_r = TMP_REG2;
-	}
-	else if (src1_r == 0 && src2_r == 0) {
-		FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
-		src1_r = TMP_REG1;
-	}
-	else if (src1_r == 0 && dst_r == 0) {
-		FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
-		src1_r = TMP_REG1;
-	}
-	else if (src2_r == 0 && dst_r == 0) {
-		FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
-		src2_r = sugg_src2_r;
-	}
-
-	if (dst_r == 0)
-		dst_r = TMP_REG2;
-
-	if (src1_r == 0) {
-		FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
-		src1_r = TMP_REG1;
-	}
-
-	if (src2_r == 0) {
-		FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
+	else {
+		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, TMP_REG2));
 		src2_r = sugg_src2_r;
 	}
 
 	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
 
-	if (flags & (FAST_DEST | SLOW_DEST)) {
-		if (flags & FAST_DEST)
-			FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw));
-		else
-			FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0));
-	}
-	return SLJIT_SUCCESS;
+	if (!(dst & SLJIT_MEM))
+		return SLJIT_SUCCESS;
+
+	return emit_op_mem(compiler, input_flags, dst_r, dst, dstw, TMP_REG1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
@@ -1294,6 +1076,31 @@
 	return SLJIT_SUCCESS;
 }
 
+static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
+        sljit_s32 src, sljit_sw srcw)
+{
+	if (!(src & OFFS_REG_MASK)) {
+		if (srcw == 0 && (src & REG_MASK) != SLJIT_UNUSED)
+			return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK));
+
+		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
+		/* Works with SLJIT_MEM0() case as well. */
+		return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
+	}
+
+	srcw &= 0x3;
+
+	if (srcw == 0)
+		return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src)));
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+	FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(src)) | A(TMP_REG1) | (srcw << 11) | ((31 - srcw) << 1)));
+#else
+	FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(src), srcw, 63 - srcw, 1)));
+#endif
+	return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1));
+}
+
 #define EMIT_MOV(type, type_flags, type_cast) \
 	emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw)
 
@@ -1301,7 +1108,7 @@
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
-	sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+	sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
 	sljit_s32 op_flags = GET_ALL_FLAGS(op);
 
 	CHECK_ERROR();
@@ -1309,39 +1116,45 @@
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
+		if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
+			return emit_prefetch(compiler, src, srcw);
+
+		return SLJIT_SUCCESS;
+	}
+
 	op = GET_OPCODE(op);
 	if ((src & SLJIT_IMM) && srcw == 0)
 		src = TMP_ZERO;
 
-	if (op_flags & SLJIT_SET_O)
+	if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW)
 		FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
 
+	if (op < SLJIT_NOT && FAST_IS_REG(src) && src == dst) {
+		if (!TYPE_CAST_NEEDED(op))
+			return SLJIT_SUCCESS;
+	}
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 	if (op_flags & SLJIT_I32_OP) {
 		if (op < SLJIT_NOT) {
-			if (FAST_IS_REG(src) && src == dst) {
-				if (!TYPE_CAST_NEEDED(op))
-					return SLJIT_SUCCESS;
+			if (src & SLJIT_MEM) {
+				if (op == SLJIT_MOV_S32)
+					op = SLJIT_MOV_U32;
 			}
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-			if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM))
-				op = SLJIT_MOV_U32;
-			if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM))
-				op = SLJIT_MOVU_U32;
-			if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM))
-				op = SLJIT_MOV_S32;
-			if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM))
-				op = SLJIT_MOVU_S32;
-#endif
+			else if (src & SLJIT_IMM) {
+				if (op == SLJIT_MOV_U32)
+					op = SLJIT_MOV_S32;
+			}
 		}
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 		else {
 			/* Most operations expect sign extended arguments. */
 			flags |= INT_DATA | SIGNED_DATA;
-			if (src & SLJIT_IMM)
-				srcw = (sljit_s32)srcw;
+			if (HAS_FLAGS(op_flags))
+				flags |= ALT_SIGN_EXT;
 		}
-#endif
 	}
+#endif
 
 	switch (op) {
 	case SLJIT_MOV:
@@ -1372,39 +1185,11 @@
 	case SLJIT_MOV_S16:
 		return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16));
 
-	case SLJIT_MOVU:
-	case SLJIT_MOVU_P:
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-	case SLJIT_MOVU_U32:
-	case SLJIT_MOVU_S32:
-#endif
-		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-	case SLJIT_MOVU_U32:
-		return EMIT_MOV(SLJIT_MOV_U32, INT_DATA | WRITE_BACK, (sljit_u32));
-
-	case SLJIT_MOVU_S32:
-		return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s32));
-#endif
-
-	case SLJIT_MOVU_U8:
-		return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, (sljit_u8));
-
-	case SLJIT_MOVU_S8:
-		return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s8));
-
-	case SLJIT_MOVU_U16:
-		return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, (sljit_u16));
-
-	case SLJIT_MOVU_S16:
-		return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s16));
-
 	case SLJIT_NOT:
 		return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
 
 	case SLJIT_NEG:
-		return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw);
+		return emit_op(compiler, SLJIT_NEG, flags | (GET_FLAG_TYPE(op_flags) ? ALT_FORM1 : 0), dst, dstw, TMP_REG1, 0, src, srcw);
 
 	case SLJIT_CLZ:
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
@@ -1457,7 +1242,7 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
-	sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+	sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0;
 
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
@@ -1465,6 +1250,9 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
+
 	if ((src1 & SLJIT_IMM) && src1w == 0)
 		src1 = TMP_ZERO;
 	if ((src2 & SLJIT_IMM) && src2w == 0)
@@ -1478,45 +1266,46 @@
 			src1w = (sljit_s32)(src1w);
 		if (src2 & SLJIT_IMM)
 			src2w = (sljit_s32)(src2w);
-		if (GET_FLAGS(op))
+		if (HAS_FLAGS(op))
 			flags |= ALT_SIGN_EXT;
 	}
 #endif
-	if (op & SLJIT_SET_O)
+	if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
 		FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
-	if (src2 == TMP_REG2)
-		flags |= ALT_KEEP_CACHE;
 
 	switch (GET_OPCODE(op)) {
 	case SLJIT_ADD:
-		if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+		if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
+			return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
+
+		if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
 			if (TEST_SL_IMM(src2, src2w)) {
 				compiler->imm = src2w & 0xffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
 			}
 			if (TEST_SL_IMM(src1, src1w)) {
 				compiler->imm = src1w & 0xffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
 			}
 			if (TEST_SH_IMM(src2, src2w)) {
 				compiler->imm = (src2w >> 16) & 0xffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
 			}
 			if (TEST_SH_IMM(src1, src1w)) {
 				compiler->imm = (src1w >> 16) & 0xffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
 			}
 			/* Range between -1 and -32768 is covered above. */
 			if (TEST_ADD_IMM(src2, src2w)) {
 				compiler->imm = src2w & 0xffffffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
 			}
 			if (TEST_ADD_IMM(src1, src1w)) {
 				compiler->imm = src1w & 0xffffffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
 			}
 		}
-		if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) {
+		if (HAS_FLAGS(op)) {
 			if (TEST_SL_IMM(src2, src2w)) {
 				compiler->imm = src2w & 0xffff;
 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1526,75 +1315,75 @@
 				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
 			}
 		}
-		return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w);
+		return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM4 : 0), dst, dstw, src1, src1w, src2, src2w);
 
 	case SLJIT_ADDC:
-		return emit_op(compiler, SLJIT_ADDC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+		return emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w);
 
 	case SLJIT_SUB:
-		if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+		if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {
+			if (dst == SLJIT_UNUSED) {
+				if (TEST_UL_IMM(src2, src2w)) {
+					compiler->imm = src2w & 0xffff;
+					return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+				}
+				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w);
+			}
+
+			if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) {
+				compiler->imm = src2w;
+				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+			}
+			return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
+		}
+
+		if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW)
+			return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, src2, src2w);
+
+		if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
 			if (TEST_SL_IMM(src2, -src2w)) {
 				compiler->imm = (-src2w) & 0xffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
 			}
 			if (TEST_SL_IMM(src1, src1w)) {
 				compiler->imm = src1w & 0xffff;
-				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
 			}
 			if (TEST_SH_IMM(src2, -src2w)) {
 				compiler->imm = ((-src2w) >> 16) & 0xffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags |  ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
 			}
 			/* Range between -1 and -32768 is covered above. */
 			if (TEST_ADD_IMM(src2, -src2w)) {
 				compiler->imm = -src2w & 0xffffffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
 			}
 		}
-		if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) {
-			if (!(op & SLJIT_SET_U)) {
-				/* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
-				if (TEST_SL_IMM(src2, src2w)) {
-					compiler->imm = src2w & 0xffff;
-					return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
-				}
-				if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) {
-					compiler->imm = src1w & 0xffff;
-					return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
-				}
+
+		if (dst == SLJIT_UNUSED && GET_FLAG_TYPE(op) != GET_FLAG_TYPE(SLJIT_SET_CARRY)) {
+			if (TEST_SL_IMM(src2, src2w)) {
+				compiler->imm = src2w & 0xffff;
+				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4 | ALT_FORM5, dst, dstw, src1, src1w, TMP_REG2, 0);
 			}
-			if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) {
-				/* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
-				if (TEST_UL_IMM(src2, src2w)) {
-					compiler->imm = src2w & 0xffff;
-					return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
-				}
-				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
-			}
-			if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) {
-				compiler->imm = src2w;
-				return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
-			}
-			return emit_op(compiler, SLJIT_SUB, flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
+			return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
 		}
-		if (!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))) {
-			if (TEST_SL_IMM(src2, -src2w)) {
-				compiler->imm = (-src2w) & 0xffff;
-				return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
-			}
+
+		if (TEST_SL_IMM(src2, -src2w)) {
+			compiler->imm = (-src2w) & 0xffff;
+			return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
 		}
 		/* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */
-		return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w);
+		return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
 
 	case SLJIT_SUBC:
-		return emit_op(compiler, SLJIT_SUBC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+		return emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w);
 
 	case SLJIT_MUL:
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 		if (op & SLJIT_I32_OP)
 			flags |= ALT_FORM2;
 #endif
-		if (!GET_FLAGS(op)) {
+		if (!HAS_FLAGS(op)) {
 			if (TEST_SL_IMM(src2, src2w)) {
 				compiler->imm = src2w & 0xffff;
 				return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1604,13 +1393,15 @@
 				return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
 			}
 		}
+		else
+			FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));
 		return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
 
 	case SLJIT_AND:
 	case SLJIT_OR:
 	case SLJIT_XOR:
 		/* Commutative unsigned operations. */
-		if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
+		if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
 			if (TEST_UL_IMM(src2, src2w)) {
 				compiler->imm = src2w;
 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1628,7 +1419,8 @@
 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
 			}
 		}
-		if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {
+		if (GET_OPCODE(op) != SLJIT_AND && GET_OPCODE(op) != SLJIT_AND) {
+			/* Unlike or and xor, and resets unwanted bits as well. */
 			if (TEST_UI_IMM(src2, src2w)) {
 				compiler->imm = src2w;
 				return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1640,12 +1432,9 @@
 		}
 		return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
 
-	case SLJIT_ASHR:
-		if (op & SLJIT_KEEP_FLAGS)
-			flags |= ALT_FORM3;
-		/* Fall through. */
 	case SLJIT_SHL:
 	case SLJIT_LSHR:
+	case SLJIT_ASHR:
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 		if (op & SLJIT_I32_OP)
 			flags |= ALT_FORM2;
@@ -1669,7 +1458,7 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
 {
 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
-	return reg;
+	return freg_map[reg];
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
@@ -1685,16 +1474,6 @@
 /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-#ifdef SLJIT_IS_FPU_AVAILABLE
-	return SLJIT_IS_FPU_AVAILABLE;
-#else
-	/* Available by default. */
-	return 1;
-#endif
-}
-
 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6))
 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
 
@@ -1719,7 +1498,7 @@
 {
 	if (src & SLJIT_MEM) {
 		/* We can ignore the temporary data store on the stack from caching point of view. */
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
 		src = TMP_FREG1;
 	}
 
@@ -1727,28 +1506,21 @@
 	op = GET_OPCODE(op);
 	FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src)));
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (op == SLJIT_CONV_SW_FROM_F64) {
 		if (FAST_IS_REG(dst)) {
-			FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0));
-			return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
+			FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
+			return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
 		}
-		return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
+		return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1);
 	}
-
 #else
 	FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src)));
-
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
 #endif
 
 	if (FAST_IS_REG(dst)) {
 		FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET));
 		FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1)));
-		return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0);
+		return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1);
 	}
 
 	SLJIT_ASSERT(dst & SLJIT_MEM);
@@ -1799,21 +1571,21 @@
 		if (FAST_IS_REG(src))
 			FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
 		else
-			FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
+			FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
 		src = TMP_REG1;
 	}
 
 	if (FAST_IS_REG(src)) {
-		FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
-		FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw));
+		FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
+		FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
 	}
 	else
-		FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
+		FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
 
 	FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
 
 	if (dst & SLJIT_MEM)
-		return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
+		return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
 	if (op & SLJIT_F32_OP)
 		return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
 	return SLJIT_SUCCESS;
@@ -1829,7 +1601,7 @@
 		invert_sign = 0;
 	}
 	else if (!FAST_IS_REG(src)) {
-		FAIL_IF(emit_op_mem2(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
+		FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
 		src = TMP_REG1;
 	}
 
@@ -1841,17 +1613,17 @@
 	FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
 	if (invert_sign)
 		FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
-	FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
-	FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI));
+	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1));
+	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
 	FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
-	FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
-	FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
-	FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW));
+	FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
+	FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2));
+	FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1));
 
 	FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
 
 	if (dst & SLJIT_MEM)
-		return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
+		return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
 	if (op & SLJIT_F32_OP)
 		return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r));
 	return SLJIT_SUCCESS;
@@ -1864,12 +1636,12 @@
 	sljit_s32 src2, sljit_sw src2w)
 {
 	if (src1 & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
 		src1 = TMP_FREG1;
 	}
 
 	if (src2 & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
 		src2 = TMP_FREG2;
 	}
 
@@ -1883,8 +1655,6 @@
 	sljit_s32 dst_r;
 
 	CHECK_ERROR();
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
 
 	SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
@@ -1895,7 +1665,7 @@
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
 	if (src & SLJIT_MEM) {
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, TMP_REG1));
 		src = dst_r;
 	}
 
@@ -1924,7 +1694,7 @@
 	}
 
 	if (dst & SLJIT_MEM)
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), dst_r, dst, dstw, TMP_REG1));
 	return SLJIT_SUCCESS;
 }
 
@@ -1933,7 +1703,7 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
-	sljit_s32 dst_r, flags = 0;
+	sljit_s32 dst_r;
 
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
@@ -1941,46 +1711,17 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
 
 	if (src1 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
-			FAIL_IF(compiler->error);
-			src1 = TMP_FREG1;
-		} else
-			flags |= ALT_FORM1;
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, TMP_REG1));
+		src1 = TMP_FREG1;
 	}
 
 	if (src2 & SLJIT_MEM) {
-		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
-			FAIL_IF(compiler->error);
-			src2 = TMP_FREG2;
-		} else
-			flags |= ALT_FORM2;
-	}
-
-	if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) {
-		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
-		}
-		else {
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
-			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
-		}
-	}
-	else if (flags & ALT_FORM1)
-		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
-	else if (flags & ALT_FORM2)
-		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
-
-	if (flags & ALT_FORM1)
-		src1 = TMP_FREG1;
-	if (flags & ALT_FORM2)
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
 		src2 = TMP_FREG2;
+	}
 
 	switch (GET_OPCODE(op)) {
 	case SLJIT_ADD_F64:
@@ -2000,13 +1741,12 @@
 		break;
 	}
 
-	if (dst_r == TMP_FREG2)
-		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
+	if (dst & SLJIT_MEM)
+		FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, TMP_REG1));
 
 	return SLJIT_SUCCESS;
 }
 
-#undef FLOAT_DATA
 #undef SELECT_FOP
 
 /* --------------------------------------------------------------------- */
@@ -2019,10 +1759,6 @@
 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	/* For UNUSED dst. Uncommon, but possible. */
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (FAST_IS_REG(dst))
 		return push_inst(compiler, MFLR | D(dst));
 
@@ -2040,12 +1776,10 @@
 	if (FAST_IS_REG(src))
 		FAIL_IF(push_inst(compiler, MTLR | S(src)));
 	else {
-		if (src & SLJIT_MEM)
-			FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
-		else if (src & SLJIT_IMM)
-			FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
+		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
 		FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
 	}
+
 	return push_inst(compiler, BLR);
 }
 
@@ -2079,33 +1813,33 @@
 		return (4 << 21) | (2 << 16);
 
 	case SLJIT_LESS:
-	case SLJIT_LESS_F64:
-		return (12 << 21) | ((4 + 0) << 16);
-
-	case SLJIT_GREATER_EQUAL:
-	case SLJIT_GREATER_EQUAL_F64:
-		return (4 << 21) | ((4 + 0) << 16);
-
-	case SLJIT_GREATER:
-	case SLJIT_GREATER_F64:
-		return (12 << 21) | ((4 + 1) << 16);
-
-	case SLJIT_LESS_EQUAL:
-	case SLJIT_LESS_EQUAL_F64:
-		return (4 << 21) | ((4 + 1) << 16);
-
 	case SLJIT_SIG_LESS:
 		return (12 << 21) | (0 << 16);
 
+	case SLJIT_GREATER_EQUAL:
 	case SLJIT_SIG_GREATER_EQUAL:
 		return (4 << 21) | (0 << 16);
 
+	case SLJIT_GREATER:
 	case SLJIT_SIG_GREATER:
 		return (12 << 21) | (1 << 16);
 
+	case SLJIT_LESS_EQUAL:
 	case SLJIT_SIG_LESS_EQUAL:
 		return (4 << 21) | (1 << 16);
 
+	case SLJIT_LESS_F64:
+		return (12 << 21) | ((4 + 0) << 16);
+
+	case SLJIT_GREATER_EQUAL_F64:
+		return (4 << 21) | ((4 + 0) << 16);
+
+	case SLJIT_GREATER_F64:
+		return (12 << 21) | ((4 + 1) << 16);
+
+	case SLJIT_LESS_EQUAL_F64:
+		return (4 << 21) | ((4 + 1) << 16);
+
 	case SLJIT_OVERFLOW:
 	case SLJIT_MUL_OVERFLOW:
 		return (12 << 21) | (3 << 16);
@@ -2127,7 +1861,7 @@
 		return (4 << 21) | ((4 + 3) << 16);
 
 	default:
-		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+		SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL_CDECL);
 		return (20 << 21);
 	}
 }
@@ -2153,7 +1887,7 @@
 	if (type < SLJIT_JUMP)
 		jump->flags |= IS_COND;
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
-	if (type >= SLJIT_CALL0)
+	if (type >= SLJIT_CALL)
 		jump->flags |= IS_CALL;
 #endif
 
@@ -2164,6 +1898,24 @@
 	return jump;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+	PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_jump(compiler, type);
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
 {
 	struct sljit_jump *jump = NULL;
@@ -2175,7 +1927,7 @@
 
 	if (FAST_IS_REG(src)) {
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
-		if (type >= SLJIT_CALL0) {
+		if (type >= SLJIT_CALL) {
 			FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
 			src_r = TMP_CALL_REG;
 		}
@@ -2185,12 +1937,13 @@
 		src_r = src;
 #endif
 	} else if (src & SLJIT_IMM) {
+		/* These jumps are converted to jump/call instructions when possible. */
 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 		FAIL_IF(!jump);
 		set_jump(jump, compiler, JUMP_ADDR);
 		jump->u.target = srcw;
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
-		if (type >= SLJIT_CALL0)
+		if (type >= SLJIT_CALL)
 			jump->flags |= IS_CALL;
 #endif
 		FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
@@ -2207,153 +1960,302 @@
 	return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
 }
 
-/* Get a bit from CR, all other bits are zeroed. */
-#define GET_CR_BIT(bit, dst) \
-	FAIL_IF(push_inst(compiler, MFCR | D(dst))); \
-	FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1)));
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
 
-#define INVERT_BIT(dst) \
-	FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1));
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+	if (src & SLJIT_MEM) {
+		ADJUST_LOCAL_OFFSET(src, srcw);
+		FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
+		src = TMP_CALL_REG;
+	}
+
+	FAIL_IF(call_with_args(compiler, arg_types, &src));
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_ijump(compiler, type, src, srcw);
+}
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
-	sljit_s32 reg, input_flags;
-	sljit_s32 flags = GET_ALL_FLAGS(op);
-	sljit_sw original_dstw = dstw;
+	sljit_s32 reg, input_flags, cr_bit, invert;
+	sljit_s32 saved_op = op;
+	sljit_sw saved_dstw = dstw;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+	input_flags = (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
+#else
+	input_flags = WORD_DATA;
+#endif
 
 	op = GET_OPCODE(op);
 	reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
 
-	compiler->cache_arg = 0;
-	compiler->cache_argw = 0;
-	if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
-		ADJUST_LOCAL_OFFSET(src, srcw);
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-		input_flags = (flags & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
-#else
-		input_flags = WORD_DATA;
-#endif
-		FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
-		src = TMP_REG1;
-		srcw = 0;
-	}
+	if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
+		FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, dst, dstw, TMP_REG1));
+
+	invert = 0;
+	cr_bit = 0;
 
 	switch (type & 0xff) {
-	case SLJIT_EQUAL:
-		GET_CR_BIT(2, reg);
-		break;
-
-	case SLJIT_NOT_EQUAL:
-		GET_CR_BIT(2, reg);
-		INVERT_BIT(reg);
-		break;
-
 	case SLJIT_LESS:
-	case SLJIT_LESS_F64:
-		GET_CR_BIT(4 + 0, reg);
+	case SLJIT_SIG_LESS:
 		break;
 
 	case SLJIT_GREATER_EQUAL:
-	case SLJIT_GREATER_EQUAL_F64:
-		GET_CR_BIT(4 + 0, reg);
-		INVERT_BIT(reg);
+	case SLJIT_SIG_GREATER_EQUAL:
+		invert = 1;
 		break;
 
 	case SLJIT_GREATER:
-	case SLJIT_GREATER_F64:
-		GET_CR_BIT(4 + 1, reg);
+	case SLJIT_SIG_GREATER:
+		cr_bit = 1;
 		break;
 
 	case SLJIT_LESS_EQUAL:
-	case SLJIT_LESS_EQUAL_F64:
-		GET_CR_BIT(4 + 1, reg);
-		INVERT_BIT(reg);
-		break;
-
-	case SLJIT_SIG_LESS:
-		GET_CR_BIT(0, reg);
-		break;
-
-	case SLJIT_SIG_GREATER_EQUAL:
-		GET_CR_BIT(0, reg);
-		INVERT_BIT(reg);
-		break;
-
-	case SLJIT_SIG_GREATER:
-		GET_CR_BIT(1, reg);
-		break;
-
 	case SLJIT_SIG_LESS_EQUAL:
-		GET_CR_BIT(1, reg);
-		INVERT_BIT(reg);
+		cr_bit = 1;
+		invert = 1;
+		break;
+
+	case SLJIT_EQUAL:
+		cr_bit = 2;
+		break;
+
+	case SLJIT_NOT_EQUAL:
+		cr_bit = 2;
+		invert = 1;
 		break;
 
 	case SLJIT_OVERFLOW:
 	case SLJIT_MUL_OVERFLOW:
-		GET_CR_BIT(3, reg);
+		cr_bit = 3;
 		break;
 
 	case SLJIT_NOT_OVERFLOW:
 	case SLJIT_MUL_NOT_OVERFLOW:
-		GET_CR_BIT(3, reg);
-		INVERT_BIT(reg);
+		cr_bit = 3;
+		invert = 1;
+		break;
+
+	case SLJIT_LESS_F64:
+		cr_bit = 4 + 0;
+		break;
+
+	case SLJIT_GREATER_EQUAL_F64:
+		cr_bit = 4 + 0;
+		invert = 1;
+		break;
+
+	case SLJIT_GREATER_F64:
+		cr_bit = 4 + 1;
+		break;
+
+	case SLJIT_LESS_EQUAL_F64:
+		cr_bit = 4 + 1;
+		invert = 1;
 		break;
 
 	case SLJIT_EQUAL_F64:
-		GET_CR_BIT(4 + 2, reg);
+		cr_bit = 4 + 2;
 		break;
 
 	case SLJIT_NOT_EQUAL_F64:
-		GET_CR_BIT(4 + 2, reg);
-		INVERT_BIT(reg);
+		cr_bit = 4 + 2;
+		invert = 1;
 		break;
 
 	case SLJIT_UNORDERED_F64:
-		GET_CR_BIT(4 + 3, reg);
+		cr_bit = 4 + 3;
 		break;
 
 	case SLJIT_ORDERED_F64:
-		GET_CR_BIT(4 + 3, reg);
-		INVERT_BIT(reg);
+		cr_bit = 4 + 3;
+		invert = 1;
 		break;
 
 	default:
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 		break;
 	}
 
+	FAIL_IF(push_inst(compiler, MFCR | D(reg)));
+	FAIL_IF(push_inst(compiler, RLWINM | S(reg) | A(reg) | ((1 + (cr_bit)) << 11) | (31 << 6) | (31 << 1)));
+
+	if (invert)
+		FAIL_IF(push_inst(compiler, XORI | S(reg) | A(reg) | 0x1));
+
 	if (op < SLJIT_ADD) {
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-		if (op == SLJIT_MOV)
-			input_flags = WORD_DATA;
-		else {
-			op = SLJIT_MOV_U32;
-			input_flags = INT_DATA;
-		}
-#else
-		op = SLJIT_MOV;
-		input_flags = WORD_DATA;
-#endif
-		if (reg != TMP_REG2)
+		if (!(dst & SLJIT_MEM))
 			return SLJIT_SUCCESS;
-		return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+		return emit_op_mem(compiler, input_flags, reg, dst, dstw, TMP_REG1);
 	}
 
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	compiler->skip_checks = 1;
 #endif
-	return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0);
+	if (dst & SLJIT_MEM)
+		return sljit_emit_op2(compiler, saved_op, dst, saved_dstw, TMP_REG1, 0, TMP_REG2, 0);
+	return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 reg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	sljit_s32 mem_flags;
+	sljit_ins inst;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
+
+	if (type & SLJIT_MEM_POST)
+		return SLJIT_ERR_UNSUPPORTED;
+
+	switch (type & 0xff) {
+	case SLJIT_MOV:
+	case SLJIT_MOV_P:
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+	case SLJIT_MOV_U32:
+	case SLJIT_MOV_S32:
+#endif
+		mem_flags = WORD_DATA;
+		break;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+	case SLJIT_MOV_U32:
+		mem_flags = INT_DATA;
+		break;
+
+	case SLJIT_MOV_S32:
+		mem_flags = INT_DATA;
+
+		if (!(type & SLJIT_MEM_STORE) && !(type & SLJIT_I32_OP)) {
+			if (mem & OFFS_REG_MASK)
+				mem_flags |= SIGNED_DATA;
+			else
+				return SLJIT_ERR_UNSUPPORTED;
+		}
+		break;
+#endif
+
+	case SLJIT_MOV_U8:
+	case SLJIT_MOV_S8:
+		mem_flags = BYTE_DATA;
+		break;
+
+	case SLJIT_MOV_U16:
+		mem_flags = HALF_DATA;
+		break;
+
+	case SLJIT_MOV_S16:
+		mem_flags = HALF_DATA | SIGNED_DATA;
+		break;
+
+	default:
+		SLJIT_UNREACHABLE();
+		mem_flags = WORD_DATA;
+		break;
+	}
+
+	if (!(type & SLJIT_MEM_STORE))
+		mem_flags |= LOAD_DATA;
+
+	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
+		if (memw != 0)
+			return SLJIT_ERR_UNSUPPORTED;
+
+		if (type & SLJIT_MEM_SUPP)
+			return SLJIT_SUCCESS;
+
+		inst = updated_data_transfer_insts[mem_flags | INDEXED];
+		FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | B(OFFS_REG(mem))));
+	}
+	else {
+		if (memw > SIMM_MAX || memw < SIMM_MIN)
+			return SLJIT_ERR_UNSUPPORTED;
+
+		inst = updated_data_transfer_insts[mem_flags];
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+		if ((inst & INT_ALIGNED) && (memw & 0x3) != 0)
+			return SLJIT_ERR_UNSUPPORTED;
+#endif
+
+		if (type & SLJIT_MEM_SUPP)
+			return SLJIT_SUCCESS;
+
+		FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, 0, reg) | A(mem & REG_MASK) | IMM(memw)));
+	}
+
+	if ((mem_flags & LOAD_DATA) && (type & 0xff) == SLJIT_MOV_S8)
+		return push_inst(compiler, EXTSB | S(reg) | A(reg));
+	return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 freg,
+	sljit_s32 mem, sljit_sw memw)
+{
+	sljit_s32 mem_flags;
+	sljit_ins inst;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
+
+	if (type & SLJIT_MEM_POST)
+		return SLJIT_ERR_UNSUPPORTED;
+
+	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
+		if (memw != 0)
+			return SLJIT_ERR_UNSUPPORTED;
+	}
+	else {
+		if (memw > SIMM_MAX || memw < SIMM_MIN)
+			return SLJIT_ERR_UNSUPPORTED;
+	}
+
+	if (type & SLJIT_MEM_SUPP)
+		return SLJIT_SUCCESS;
+
+	mem_flags = FLOAT_DATA(type);
+
+	if (!(type & SLJIT_MEM_STORE))
+		mem_flags |= LOAD_DATA;
+
+	if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
+		inst = updated_data_transfer_insts[mem_flags | INDEXED];
+		return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | B(OFFS_REG(mem)));
+	}
+
+	inst = updated_data_transfer_insts[mem_flags];
+	return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw));
 }
 
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
@@ -2369,7 +2271,7 @@
 	PTR_FAIL_IF(!const_);
 	set_const(const_, compiler);
 
-	reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+	reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
 
 	PTR_FAIL_IF(emit_const(compiler, reg, init_value));
 
diff --git a/dist2/src/sljit/sljitNativeSPARC_32.c b/dist2/src/sljit/sljitNativeSPARC_32.c
index 7e589a1..0671b13 100644
--- a/dist2/src/sljit/sljitNativeSPARC_32.c
+++ b/dist2/src/sljit/sljitNativeSPARC_32.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -60,7 +60,7 @@
 			return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst));
 		}
 		else if (dst != src2)
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 		return SLJIT_SUCCESS;
 
 	case SLJIT_MOV_U16:
@@ -71,7 +71,7 @@
 			return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst));
 		}
 		else if (dst != src2)
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 		return SLJIT_SUCCESS;
 
 	case SLJIT_NOT:
@@ -80,18 +80,17 @@
 
 	case SLJIT_CLZ:
 		SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
-		/* sparc 32 does not support SLJIT_KEEP_FLAGS. Not sure I can fix this. */
 		FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(src2) | S2(0), SET_FLAGS));
 		FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2(src2), DR(TMP_REG1)));
 		FAIL_IF(push_inst(compiler, BICC | DA(0x1) | (7 & DISP_MASK), UNMOVABLE_INS));
-		FAIL_IF(push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(0) | IMM(32), UNMOVABLE_INS | (flags & SET_FLAGS)));
+		FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(32), UNMOVABLE_INS));
 		FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(-1), DR(dst)));
 
 		/* Loop. */
 		FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(0), SET_FLAGS));
 		FAIL_IF(push_inst(compiler, SLL | D(TMP_REG1) | S1(TMP_REG1) | IMM(1), DR(TMP_REG1)));
 		FAIL_IF(push_inst(compiler, BICC | DA(0xe) | (-2 & DISP_MASK), UNMOVABLE_INS));
-		return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS | (flags & SET_FLAGS));
+		return push_inst(compiler, ADD | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS);
 
 	case SLJIT_ADD:
 		return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
@@ -135,7 +134,126 @@
 		return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
+	return SLJIT_SUCCESS;
+}
+
+static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
+{
+	sljit_s32 reg_index = 8;
+	sljit_s32 word_reg_index = 8;
+	sljit_s32 float_arg_index = 1;
+	sljit_s32 double_arg_count = 0;
+	sljit_s32 float_offset = (16 + 6) * sizeof(sljit_sw);
+	sljit_s32 types = 0;
+	sljit_s32 reg = 0;
+	sljit_s32 move_to_tmp2 = 0;
+
+	if (src)
+		reg = reg_map[*src & REG_MASK];
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
+
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			float_arg_index++;
+			if (reg_index == reg)
+				move_to_tmp2 = 1;
+			reg_index++;
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			float_arg_index++;
+			double_arg_count++;
+			if (reg_index == reg || reg_index + 1 == reg)
+				move_to_tmp2 = 1;
+			reg_index += 2;
+			break;
+		default:
+			if (reg_index != word_reg_index && reg_index < 14 && reg_index == reg)
+				move_to_tmp2 = 1;
+			reg_index++;
+			word_reg_index++;
+			break;
+		}
+
+		if (move_to_tmp2) {
+			move_to_tmp2 = 0;
+			if (reg < 14)
+				FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2A(reg), DR(TMP_REG1)));
+			*src = TMP_REG1;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	arg_types = types;
+
+	while (arg_types) {
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			float_arg_index--;
+			FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
+			float_offset -= sizeof(sljit_f64);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			float_arg_index--;
+			if (float_arg_index == 4 && double_arg_count == 4) {
+				FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM((16 + 7) * sizeof(sljit_sw)), MOVABLE_INS));
+				FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | (1 << 25) | S1(SLJIT_SP) | IMM((16 + 8) * sizeof(sljit_sw)), MOVABLE_INS));
+			}
+			else
+				FAIL_IF(push_inst(compiler, STDF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
+			float_offset -= sizeof(sljit_f64);
+			break;
+		default:
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	float_offset = (16 + 6) * sizeof(sljit_sw);
+
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			reg_index--;
+			if (reg_index < 14)
+				FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
+			float_offset -= sizeof(sljit_f64);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			reg_index -= 2;
+			if (reg_index < 14) {
+				if ((reg_index & 0x1) != 0) {
+					FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
+					if (reg_index < 13)
+						FAIL_IF(push_inst(compiler, LDUW | DA(reg_index + 1) | S1(SLJIT_SP) | IMM(float_offset + sizeof(sljit_sw)), reg_index + 1));
+				}
+				else 
+					FAIL_IF(push_inst(compiler, LDD | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
+			}
+			float_offset -= sizeof(sljit_f64);
+			break;
+		default:
+			reg_index--;
+			word_reg_index--;
+
+			if (reg_index != word_reg_index) {
+				if (reg_index < 14)
+					FAIL_IF(push_inst(compiler, OR | DA(reg_index) | S1(0) | S2A(word_reg_index), reg_index));
+				else
+					FAIL_IF(push_inst(compiler, STW | DA(word_reg_index) | S1(SLJIT_SP) | IMM(92), word_reg_index));
+			}
+			break;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
 	return SLJIT_SUCCESS;
 }
 
@@ -145,20 +263,22 @@
 	return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst));
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
-	inst[0] = (inst[0] & 0xffc00000) | ((new_addr >> 10) & 0x3fffff);
-	inst[1] = (inst[1] & 0xfffffc00) | (new_addr & 0x3ff);
+	inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
+	inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 2);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
-	sljit_ins *inst = (sljit_ins*)addr;
+	sljit_ins *inst = (sljit_ins *)addr;
 
 	inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
 	inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
+	inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
 	SLJIT_CACHE_FLUSH(inst, inst + 2);
 }
diff --git a/dist2/src/sljit/sljitNativeSPARC_common.c b/dist2/src/sljit/sljitNativeSPARC_common.c
index f3a33a1..669ecd8 100644
--- a/dist2/src/sljit/sljitNativeSPARC_common.c
+++ b/dist2/src/sljit/sljitNativeSPARC_common.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -90,13 +90,19 @@
 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
 #define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
+/* This register is modified by calls, which affects the instruction
+   in the delay slot if it is used as a source register. */
 #define TMP_LINK	(SLJIT_NUMBER_OF_REGISTERS + 5)
 
-#define TMP_FREG1	(0)
-#define TMP_FREG2	((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
+#define TMP_FREG1	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
+#define TMP_FREG2	(SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
 
 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
-	0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15
+	0, 8, 9, 10, 11, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 12, 13, 15
+};
+
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
+	0, 0, 2, 4, 6, 8, 10, 12, 14
 };
 
 /* --------------------------------------------------------------------- */
@@ -104,10 +110,15 @@
 /* --------------------------------------------------------------------- */
 
 #define D(d)		(reg_map[d] << 25)
+#define FD(d)		(freg_map[d] << 25)
+#define FDN(d)		((freg_map[d] | 0x1) << 25)
 #define DA(d)		((d) << 25)
 #define S1(s1)		(reg_map[s1] << 14)
-#define S2(s2)		(reg_map[s2])
+#define FS1(s1)		(freg_map[s1] << 14)
 #define S1A(s1)		((s1) << 14)
+#define S2(s2)		(reg_map[s2])
+#define FS2(s2)		(freg_map[s2])
+#define FS2N(s2)	(freg_map[s2] | 0x1)
 #define S2A(s2)		(s2)
 #define IMM_ARG		0x2000
 #define DOP(op)		((op) << 5)
@@ -144,6 +155,8 @@
 #define FSUBD		(OPC1(0x2) | OPC3(0x34) | DOP(0x46))
 #define FSUBS		(OPC1(0x2) | OPC3(0x34) | DOP(0x45))
 #define JMPL		(OPC1(0x2) | OPC3(0x38))
+#define LDD		(OPC1(0x3) | OPC3(0x03))
+#define LDUW		(OPC1(0x3) | OPC3(0x00))
 #define NOP		(OPC1(0x0) | OPC2(0x04))
 #define OR		(OPC1(0x2) | OPC3(0x02))
 #define ORN		(OPC1(0x2) | OPC3(0x06))
@@ -157,6 +170,9 @@
 #define SRAX		(OPC1(0x2) | OPC3(0x27) | (1 << 12))
 #define SRL		(OPC1(0x2) | OPC3(0x26))
 #define SRLX		(OPC1(0x2) | OPC3(0x26) | (1 << 12))
+#define STDF		(OPC1(0x3) | OPC3(0x27))
+#define STF		(OPC1(0x3) | OPC3(0x24))
+#define STW		(OPC1(0x3) | OPC3(0x04))
 #define SUB		(OPC1(0x2) | OPC3(0x04))
 #define SUBC		(OPC1(0x2) | OPC3(0x0c))
 #define TA		(OPC1(0x2) | OPC3(0x3a) | (8 << 25))
@@ -199,7 +215,7 @@
 	return SLJIT_SUCCESS;
 }
 
-static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+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;
@@ -213,7 +229,7 @@
 		target_addr = jump->u.target;
 	else {
 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-		target_addr = (sljit_uw)(code + jump->u.label->size);
+		target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
 	}
 	inst = (sljit_ins*)jump->addr;
 
@@ -239,8 +255,9 @@
 	if (jump->flags & IS_COND)
 		inst--;
 
+	diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1) - executable_offset) >> 2;
+
 	if (jump->flags & IS_MOVABLE) {
-		diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2;
 		if (diff <= MAX_DISP && diff >= MIN_DISP) {
 			jump->flags |= PATCH_B;
 			inst--;
@@ -257,7 +274,8 @@
 		}
 	}
 
-	diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
+	diff += sizeof(sljit_ins);
+
 	if (diff <= MAX_DISP && diff >= MIN_DISP) {
 		jump->flags |= PATCH_B;
 		if (jump->flags & IS_COND)
@@ -280,6 +298,7 @@
 	sljit_ins *buf_ptr;
 	sljit_ins *buf_end;
 	sljit_uw word_count;
+	sljit_sw executable_offset;
 	sljit_uw addr;
 
 	struct sljit_label *label;
@@ -296,9 +315,12 @@
 
 	code_ptr = code;
 	word_count = 0;
+	executable_offset = SLJIT_EXEC_OFFSET(code);
+
 	label = compiler->labels;
 	jump = compiler->jumps;
 	const_ = compiler->consts;
+
 	do {
 		buf_ptr = (sljit_ins*)buf->memory;
 		buf_end = buf_ptr + (buf->used_size >> 2);
@@ -310,7 +332,7 @@
 			/* These structures are ordered by their address. */
 			if (label && label->size == word_count) {
 				/* Just recording the address. */
-				label->addr = (sljit_uw)code_ptr;
+				label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 				label->size = code_ptr - code;
 				label = label->next;
 			}
@@ -320,7 +342,7 @@
 #else
 				jump->addr = (sljit_uw)(code_ptr - 6);
 #endif
-				code_ptr = detect_jump_type(jump, code_ptr, code);
+				code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
 				jump = jump->next;
 			}
 			if (const_ && const_->addr == word_count) {
@@ -336,7 +358,7 @@
 	} while (buf);
 
 	if (label && label->size == word_count) {
-		label->addr = (sljit_uw)code_ptr;
+		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 		label->size = code_ptr - code;
 		label = label->next;
 	}
@@ -350,16 +372,16 @@
 	while (jump) {
 		do {
 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-			buf_ptr = (sljit_ins*)jump->addr;
+			buf_ptr = (sljit_ins *)jump->addr;
 
 			if (jump->flags & PATCH_CALL) {
-				addr = (sljit_sw)(addr - jump->addr) >> 2;
+				addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
 				SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
 				buf_ptr[0] = CALL | (addr & 0x3fffffff);
 				break;
 			}
 			if (jump->flags & PATCH_B) {
-				addr = (sljit_sw)(addr - jump->addr) >> 2;
+				addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
 				SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
 				buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
 				break;
@@ -378,11 +400,37 @@
 
 
 	compiler->error = SLJIT_ERR_COMPILED;
+	compiler->executable_offset = executable_offset;
 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+
+	code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+	code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
 	SLJIT_CACHE_FLUSH(code, code_ptr);
 	return code;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	switch (feature_type) {
+	case SLJIT_HAS_FPU:
+#ifdef SLJIT_IS_FPU_AVAILABLE
+		return SLJIT_IS_FPU_AVAILABLE;
+#else
+		/* Available by default. */
+		return 1;
+#endif
+
+#if (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)
+	case SLJIT_HAS_CMOV:
+		return 1;
+#endif
+
+	default:
+		return 0;
+	}
+}
+
 /* --------------------------------------------------------------------- */
 /*  Entry, exit                                                          */
 /* --------------------------------------------------------------------- */
@@ -401,18 +449,17 @@
 
 #define MEM_MASK	0x1f
 
-#define WRITE_BACK	0x00020
-#define ARG_TEST	0x00040
-#define ALT_KEEP_CACHE	0x00080
-#define CUMULATIVE_OP	0x00100
-#define IMM_OP		0x00200
-#define SRC2_IMM	0x00400
+#define ARG_TEST	0x00020
+#define ALT_KEEP_CACHE	0x00040
+#define CUMULATIVE_OP	0x00080
+#define IMM_OP		0x00100
+#define SRC2_IMM	0x00200
 
-#define REG_DEST	0x00800
-#define REG2_SOURCE	0x01000
-#define SLOW_SRC1	0x02000
-#define SLOW_SRC2	0x04000
-#define SLOW_DEST	0x08000
+#define REG_DEST	0x00400
+#define REG2_SOURCE	0x00800
+#define SLOW_SRC1	0x01000
+#define SLOW_SRC2	0x02000
+#define SLOW_DEST	0x04000
 
 /* SET_FLAGS (0x10 << 19) also belong here! */
 
@@ -423,12 +470,12 @@
 #endif
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
 	compiler->local_size = local_size;
@@ -447,12 +494,12 @@
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
 	compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
 	return SLJIT_SUCCESS;
@@ -514,18 +561,16 @@
 {
 	SLJIT_ASSERT(arg & SLJIT_MEM);
 
-	if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) {
-		if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
-				|| ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
-			/* Works for both absoulte and relative addresses (immediate case). */
-			if (SLJIT_UNLIKELY(flags & ARG_TEST))
-				return 1;
-			FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
-				| ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg))
-				| S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
-				((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
-			return -1;
-		}
+	if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
+			|| ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
+		/* Works for both absoulte and relative addresses (immediate case). */
+		if (SLJIT_UNLIKELY(flags & ARG_TEST))
+			return 1;
+		FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
+			| ((flags & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))
+			| S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
+			((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
+		return -1;
 	}
 	return 0;
 }
@@ -567,7 +612,6 @@
 	base = arg & REG_MASK;
 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
 		argw &= 0x3;
-		SLJIT_ASSERT(argw != 0);
 
 		/* Using the cache. */
 		if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw))
@@ -607,14 +651,11 @@
 		}
 	}
 
-	dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg));
+	dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg));
 	delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS;
 	if (!base)
 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot);
-	if (!(flags & WRITE_BACK))
-		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
-	FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot));
-	return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base));
+	return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
 }
 
 static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
@@ -652,18 +693,16 @@
 		compiler->cache_argw = 0;
 	}
 
-	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
-			return SLJIT_SUCCESS;
+	if (dst != SLJIT_UNUSED) {
+		if (FAST_IS_REG(dst)) {
+			dst_r = dst;
+			flags |= REG_DEST;
+			if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
+				sugg_src2_r = dst_r;
+		}
+		else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
+			flags |= SLOW_DEST;
 	}
-	else if (FAST_IS_REG(dst)) {
-		dst_r = dst;
-		flags |= REG_DEST;
-		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
-			sugg_src2_r = dst_r;
-	}
-	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
-		flags |= SLOW_DEST;
 
 	if (flags & IMM_OP) {
 		if ((src2 & SLJIT_IMM) && src2w) {
@@ -709,7 +748,7 @@
 	if (FAST_IS_REG(src2)) {
 		src2_r = src2;
 		flags |= REG2_SOURCE;
-		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
+		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
 			dst_r = src2_r;
 	}
 	else if (src2 & SLJIT_IMM) {
@@ -720,7 +759,7 @@
 			}
 			else {
 				src2_r = 0;
-				if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
+				if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))
 					dst_r = 0;
 			}
 		}
@@ -812,13 +851,16 @@
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
-	sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+	sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
+
 	op = GET_OPCODE(op);
 	switch (op) {
 	case SLJIT_MOV:
@@ -843,28 +885,6 @@
 	case SLJIT_MOV_S16:
 		return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
 
-	case SLJIT_MOVU:
-	case SLJIT_MOVU_P:
-		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
-	case SLJIT_MOVU_U32:
-		return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
-	case SLJIT_MOVU_S32:
-		return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
-	case SLJIT_MOVU_U8:
-		return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
-
-	case SLJIT_MOVU_S8:
-		return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
-
-	case SLJIT_MOVU_U16:
-		return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
-
-	case SLJIT_MOVU_S16:
-		return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
-
 	case SLJIT_NOT:
 	case SLJIT_CLZ:
 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
@@ -881,7 +901,7 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
-	sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+	sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
@@ -889,6 +909,9 @@
 	ADJUST_LOCAL_OFFSET(src1, src1w);
 	ADJUST_LOCAL_OFFSET(src2, src2w);
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
+
 	op = GET_OPCODE(op);
 	switch (op) {
 	case SLJIT_ADD:
@@ -910,7 +933,7 @@
 		if (src2 & SLJIT_IMM)
 			src2w &= 0x1f;
 #else
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 #endif
 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
 	}
@@ -927,7 +950,7 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
 {
 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
-	return reg << 1;
+	return freg_map[reg];
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
@@ -943,16 +966,6 @@
 /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-#ifdef SLJIT_IS_FPU_AVAILABLE
-	return SLJIT_IS_FPU_AVAILABLE;
-#else
-	/* Available by default. */
-	return 1;
-#endif
-}
-
 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
 #define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
@@ -965,13 +978,8 @@
 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
 		src = TMP_FREG1;
 	}
-	else
-		src <<= 1;
 
-	FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS));
-
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
+	FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | FD(TMP_FREG1) | FS2(src), MOVABLE_INS));
 
 	if (FAST_IS_REG(dst)) {
 		FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
@@ -986,7 +994,7 @@
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
-	sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
 	if (src & SLJIT_IMM) {
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -1005,7 +1013,7 @@
 	}
 
 	FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
-	FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS));
+	FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | FD(dst_r) | FS2(TMP_FREG1), MOVABLE_INS));
 
 	if (dst & SLJIT_MEM)
 		return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
@@ -1020,17 +1028,13 @@
 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
 		src1 = TMP_FREG1;
 	}
-	else
-		src1 <<= 1;
 
 	if (src2 & SLJIT_MEM) {
 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
 		src2 = TMP_FREG2;
 	}
-	else
-		src2 <<= 1;
 
-	return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS);
+	return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | FS1(src1) | FS2(src2), FCC_IS_SET | MOVABLE_INS);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
@@ -1049,39 +1053,37 @@
 	if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
 		op ^= SLJIT_F32_OP;
 
-	dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 
 	if (src & SLJIT_MEM) {
 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
 		src = dst_r;
 	}
-	else
-		src <<= 1;
 
 	switch (GET_OPCODE(op)) {
 	case SLJIT_MOV_F64:
 		if (src != dst_r) {
 			if (dst_r != TMP_FREG1) {
-				FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS));
+				FAIL_IF(push_inst(compiler, FMOVS | FD(dst_r) | FS2(src), MOVABLE_INS));
 				if (!(op & SLJIT_F32_OP))
-					FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
+					FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
 			}
 			else
 				dst_r = src;
 		}
 		break;
 	case SLJIT_NEG_F64:
-		FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS));
+		FAIL_IF(push_inst(compiler, FNEGS | FD(dst_r) | FS2(src), MOVABLE_INS));
 		if (dst_r != src && !(op & SLJIT_F32_OP))
-			FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
+			FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
 		break;
 	case SLJIT_ABS_F64:
-		FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS));
+		FAIL_IF(push_inst(compiler, FABSS | FD(dst_r) | FS2(src), MOVABLE_INS));
 		if (dst_r != src && !(op & SLJIT_F32_OP))
-			FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
+			FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
 		break;
 	case SLJIT_CONV_F64_FROM_F32:
-		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS));
+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | FD(dst_r) | FS2(src), MOVABLE_INS));
 		op ^= SLJIT_F32_OP;
 		break;
 	}
@@ -1107,7 +1109,7 @@
 	compiler->cache_arg = 0;
 	compiler->cache_argw = 0;
 
-	dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
 
 	if (src1 & SLJIT_MEM) {
 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
@@ -1116,8 +1118,6 @@
 		} else
 			flags |= SLOW_SRC1;
 	}
-	else
-		src1 <<= 1;
 
 	if (src2 & SLJIT_MEM) {
 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
@@ -1126,8 +1126,6 @@
 		} else
 			flags |= SLOW_SRC2;
 	}
-	else
-		src2 <<= 1;
 
 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
@@ -1151,19 +1149,19 @@
 
 	switch (GET_OPCODE(op)) {
 	case SLJIT_ADD_F64:
-		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 		break;
 
 	case SLJIT_SUB_F64:
-		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 		break;
 
 	case SLJIT_MUL_F64:
-		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 		break;
 
 	case SLJIT_DIV_F64:
-		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
+		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 		break;
 	}
 
@@ -1186,10 +1184,6 @@
 	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	/* For UNUSED dst. Uncommon, but possible. */
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	if (FAST_IS_REG(dst))
 		return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst));
 
@@ -1205,10 +1199,8 @@
 
 	if (FAST_IS_REG(src))
 		FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
-	else if (src & SLJIT_MEM)
+	else
 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
-	else if (src & SLJIT_IMM)
-		FAIL_IF(load_immediate(compiler, TMP_LINK, srcw));
 
 	FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
 	return push_inst(compiler, NOP, UNMOVABLE_INS);
@@ -1285,7 +1277,7 @@
 		return DA(0xf);
 
 	default:
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 		return DA(0x8);
 	}
 }
@@ -1321,21 +1313,38 @@
 #else
 #error "Implementation required"
 #endif
-	} else {
+	}
+	else {
 		if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
 			jump->flags |= IS_MOVABLE;
 		if (type >= SLJIT_FAST_CALL)
 			jump->flags |= IS_CALL;
 	}
 
-	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
-	PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS));
+	PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0));
+	PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG1) | IMM(0), UNMOVABLE_INS));
 	jump->addr = compiler->size;
 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
 
 	return jump;
 }
 
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+	PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_jump(compiler, type);
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
 {
 	struct sljit_jump *jump = NULL;
@@ -1352,17 +1361,18 @@
 		FAIL_IF(!jump);
 		set_jump(jump, compiler, JUMP_ADDR);
 		jump->u.target = srcw;
+
 		if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
 			jump->flags |= IS_MOVABLE;
 		if (type >= SLJIT_FAST_CALL)
 			jump->flags |= IS_CALL;
 
-		FAIL_IF(emit_const(compiler, TMP_REG2, 0));
-		src_r = TMP_REG2;
+		FAIL_IF(emit_const(compiler, TMP_REG1, 0));
+		src_r = TMP_REG1;
 	}
 	else {
-		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
-		src_r = TMP_REG2;
+		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
+		src_r = TMP_REG1;
 	}
 
 	FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS));
@@ -1371,32 +1381,48 @@
 	return push_inst(compiler, NOP, UNMOVABLE_INS);
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+	if (src & SLJIT_MEM) {
+		ADJUST_LOCAL_OFFSET(src, srcw);
+		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
+		src = TMP_REG1;
+	}
+
+	FAIL_IF(call_with_args(compiler, arg_types, &src));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_ijump(compiler, type, src, srcw);
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
-	sljit_s32 reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
+	sljit_s32 reg, flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 	op = GET_OPCODE(op);
 	reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
 
 	compiler->cache_arg = 0;
 	compiler->cache_argw = 0;
-	if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
-		ADJUST_LOCAL_OFFSET(src, srcw);
-		FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
-		src = TMP_REG1;
-		srcw = 0;
-	}
+
+	if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
+		FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, dst, dstw, dst, dstw));
 
 	type &= 0xff;
 	if (type < SLJIT_EQUAL_F64)
@@ -1407,10 +1433,31 @@
 	FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS));
 	FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS));
 
-	if (op >= SLJIT_ADD)
-		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
+	if (op >= SLJIT_ADD) {
+		flags |= CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE;
+		if (dst & SLJIT_MEM)
+			return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+		return emit_op(compiler, op, flags, dst, 0, dst, 0, TMP_REG2, 0);
+	}
 
-	return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
+	if (!(dst & SLJIT_MEM))
+		return SLJIT_SUCCESS;
+
+	return emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw);
+#else
+#error "Implementation required"
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+	return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
 #else
 #error "Implementation required"
 #endif
@@ -1429,7 +1476,7 @@
 	PTR_FAIL_IF(!const_);
 	set_const(const_, compiler);
 
-	reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+	reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
 
 	PTR_FAIL_IF(emit_const(compiler, reg, init_value));
 
diff --git a/dist2/src/sljit/sljitNativeTILEGX-encoder.c b/dist2/src/sljit/sljitNativeTILEGX-encoder.c
index 7196329..dd82eba 100644
--- a/dist2/src/sljit/sljitNativeTILEGX-encoder.c
+++ b/dist2/src/sljit/sljitNativeTILEGX-encoder.c
@@ -2,7 +2,7 @@
  *    Stack-less Just-In-Time compiler
  *
  *    Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
diff --git a/dist2/src/sljit/sljitNativeTILEGX_64.c b/dist2/src/sljit/sljitNativeTILEGX_64.c
index 462a8b9..003f43a 100644
--- a/dist2/src/sljit/sljitNativeTILEGX_64.c
+++ b/dist2/src/sljit/sljitNativeTILEGX_64.c
@@ -2,7 +2,7 @@
  *    Stack-less Just-In-Time compiler
  *
  *    Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -687,7 +687,7 @@
 			inst_buf[0] = inst1;
 			inst_buf_index = 1;
 		} else
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 
 #ifdef TILEGX_JIT_DEBUG
 		return push_inst_nodebug(compiler, bits);
@@ -727,10 +727,10 @@
 			return push_inst(compiler, bits);
 #endif
 		} else
-			SLJIT_ASSERT_STOP();
+			SLJIT_UNREACHABLE();
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 }
 
 static sljit_s32 flush_buffer(struct sljit_compiler *compiler)
@@ -814,7 +814,7 @@
 		break;
 	default:
 		printf("unrecoginzed opc: %s\n", opcode->name);
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 	}
 
 	inst_buf_index++;
@@ -859,7 +859,7 @@
 		break;
 	default:
 		printf("unrecoginzed opc: %s\n", opcode->name);
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 	}
 
 	inst_buf_index++;
@@ -1952,7 +1952,7 @@
 		return SLJIT_SUCCESS;
 	}
 
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 	return SLJIT_SUCCESS;
 }
 
@@ -2092,9 +2092,6 @@
 	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
-
 	op = GET_OPCODE(op);
 	if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32)
 		mem_type = INT_DATA | SIGNED_DATA;
@@ -2143,7 +2140,7 @@
 		break;
 
 	default:
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 		dst_ar = sugg_dst_ar;
 		break;
 	}
@@ -2186,7 +2183,7 @@
 	case SLJIT_DIVMOD_SW:
 	case SLJIT_DIV_UW:
 	case SLJIT_DIV_SW:
-		SLJIT_ASSERT_STOP();
+		SLJIT_UNREACHABLE();
 	}
 
 	return SLJIT_SUCCESS;
@@ -2487,19 +2484,14 @@
 	return jump;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-	return 0;
-}
-
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
 {
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
 {
-	SLJIT_ASSERT_STOP();
+	SLJIT_UNREACHABLE();
 }
 
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
@@ -2526,13 +2518,13 @@
 	return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target)
 {
 	sljit_ins *inst = (sljit_ins *)addr;
 
-	inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_addr >> 32) & 0xffff) << 43);
-	inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_addr >> 16) & 0xffff) << 43);
-	inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_addr & 0xffff) << 43);
+	inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_target >> 32) & 0xffff) << 43);
+	inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_target >> 16) & 0xffff) << 43);
+	inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_target & 0xffff) << 43);
 	SLJIT_CACHE_FLUSH(inst, inst + 3);
 }
 
diff --git a/dist2/src/sljit/sljitNativeX86_32.c b/dist2/src/sljit/sljitNativeX86_32.c
index 78f3dcb..8a83e27 100644
--- a/dist2/src/sljit/sljitNativeX86_32.c
+++ b/dist2/src/sljit/sljitNativeX86_32.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -38,7 +38,7 @@
 	return SLJIT_SUCCESS;
 }
 
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset)
 {
 	if (type == SLJIT_JUMP) {
 		*code_ptr++ = JMP_i32;
@@ -57,27 +57,47 @@
 	if (jump->flags & JUMP_LABEL)
 		jump->flags |= PATCH_MW;
 	else
-		sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4));
+		sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset);
 	code_ptr += 4;
 
 	return code_ptr;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 size;
+	sljit_s32 args, size;
 	sljit_u8 *inst;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
+	args = get_arg_count(arg_types);
 	compiler->args = args;
-	compiler->flags_saved = 0;
 
-	size = 1 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3);
+	/* [esp+0] for saving temporaries and function calls. */
+	compiler->stack_tmp_size = 2 * sizeof(sljit_sw);
+
+#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+	if (scratches > 3)
+		compiler->stack_tmp_size = 3 * sizeof(sljit_sw);
+#endif
+
+	compiler->saveds_offset = compiler->stack_tmp_size;
+	if (scratches > 3)
+		compiler->saveds_offset += ((scratches > (3 + 6)) ? 6 : (scratches - 3)) * sizeof(sljit_sw);
+
+	compiler->locals_offset = compiler->saveds_offset;
+
+	if (saveds > 3)
+		compiler->locals_offset += (saveds - 3) * sizeof(sljit_sw);
+
+	if (options & SLJIT_F64_ALIGNMENT)
+		compiler->locals_offset = (compiler->locals_offset + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1);
+
+	size = 1 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3);
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
 	size += (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
 #else
@@ -94,11 +114,11 @@
 		*inst++ = MOD_REG | (reg_map[TMP_REG1] << 3) | 0x4 /* esp */;
 	}
 #endif
-	if (saveds > 2 || scratches > 7)
+	if (saveds > 2 || scratches > 9)
 		PUSH_REG(reg_map[SLJIT_S2]);
-	if (saveds > 1 || scratches > 8)
+	if (saveds > 1 || scratches > 10)
 		PUSH_REG(reg_map[SLJIT_S1]);
-	if (saveds > 0 || scratches > 9)
+	if (saveds > 0 || scratches > 11)
 		PUSH_REG(reg_map[SLJIT_S0]);
 
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
@@ -134,73 +154,106 @@
 	}
 #endif
 
-	SLJIT_COMPILE_ASSERT(SLJIT_LOCALS_OFFSET >= (2 + 4) * sizeof(sljit_uw), require_at_least_two_words);
+	SLJIT_ASSERT(SLJIT_LOCALS_OFFSET > 0);
+
 #if defined(__APPLE__)
 	/* Ignore pushed registers and SLJIT_LOCALS_OFFSET when computing the aligned local size. */
-	saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
+	saveds = (2 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
 	local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
 #else
-	if (options & SLJIT_DOUBLE_ALIGNMENT) {
-		local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7);
-
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 17);
-		FAIL_IF(!inst);
-
-		INC_SIZE(17);
-		inst[0] = MOV_r_rm;
-		inst[1] = MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[SLJIT_SP];
-		inst[2] = GROUP_F7;
-		inst[3] = MOD_REG | (0 << 3) | reg_map[SLJIT_SP];
-		sljit_unaligned_store_sw(inst + 4, 0x4);
-		inst[8] = JNE_i8;
-		inst[9] = 6;
-		inst[10] = GROUP_BINARY_81;
-		inst[11] = MOD_REG | (5 << 3) | reg_map[SLJIT_SP];
-		sljit_unaligned_store_sw(inst + 12, 0x4);
-		inst[16] = PUSH_r + reg_map[TMP_REG1];
-	}
+	if (options & SLJIT_F64_ALIGNMENT)
+		local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1));
 	else
-		local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3);
+		local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_sw) - 1) & ~(sizeof(sljit_sw) - 1));
 #endif
 
 	compiler->local_size = local_size;
+
 #ifdef _WIN32
 	if (local_size > 1024) {
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
 		FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
 #else
-		local_size -= SLJIT_LOCALS_OFFSET;
+		/* Space for a single argument. This amount is excluded when the stack is allocated below. */
+		local_size -= sizeof(sljit_sw);
 		FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
-		FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
-			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, SLJIT_LOCALS_OFFSET));
+		FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
+			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, sizeof(sljit_sw)));
 #endif
-		FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
+		FAIL_IF(sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARG1(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
 	}
 #endif
 
 	SLJIT_ASSERT(local_size > 0);
-	return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
+
+#if !defined(__APPLE__)
+	if (options & SLJIT_F64_ALIGNMENT) {
+		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_SP, 0);
+
+		/* Some space might allocated during sljit_grow_stack() above on WIN32. */
+		FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
+			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size + sizeof(sljit_sw)));
+
+#if defined _WIN32 && !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+		if (compiler->local_size > 1024)
+			FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
+				TMP_REG1, 0, TMP_REG1, 0, SLJIT_IMM, sizeof(sljit_sw)));
+#endif
+
+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 6);
+		FAIL_IF(!inst);
+
+		INC_SIZE(6);
+		inst[0] = GROUP_BINARY_81;
+		inst[1] = MOD_REG | AND | reg_map[SLJIT_SP];
+		sljit_unaligned_store_sw(inst + 2, ~(sizeof(sljit_f64) - 1));
+
+		/* The real local size must be used. */
+		return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), compiler->local_size, TMP_REG1, 0);
+	}
+#endif
+	return emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
 		SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
 {
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
-	compiler->args = args;
+	compiler->args = get_arg_count(arg_types);
+
+	/* [esp+0] for saving temporaries and function calls. */
+	compiler->stack_tmp_size = 2 * sizeof(sljit_sw);
+
+#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+	if (scratches > 3)
+		compiler->stack_tmp_size = 3 * sizeof(sljit_sw);
+#endif
+
+	compiler->saveds_offset = compiler->stack_tmp_size;
+	if (scratches > 3)
+		compiler->saveds_offset += ((scratches > (3 + 6)) ? 6 : (scratches - 3)) * sizeof(sljit_sw);
+
+	compiler->locals_offset = compiler->saveds_offset;
+
+	if (saveds > 3)
+		compiler->locals_offset += (saveds - 3) * sizeof(sljit_sw);
+
+	if (options & SLJIT_F64_ALIGNMENT)
+		compiler->locals_offset = (compiler->locals_offset + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1);
 
 #if defined(__APPLE__)
-	saveds = (2 + (scratches > 7 ? (scratches - 7) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
+	saveds = (2 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
 	compiler->local_size = ((SLJIT_LOCALS_OFFSET + saveds + local_size + 15) & ~15) - saveds;
 #else
-	if (options & SLJIT_DOUBLE_ALIGNMENT)
-		compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7);
+	if (options & SLJIT_F64_ALIGNMENT)
+		compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_f64) - 1) & ~(sizeof(sljit_f64) - 1));
 	else
-		compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + 3) & ~3);
+		compiler->local_size = SLJIT_LOCALS_OFFSET + ((local_size + sizeof(sljit_sw) - 1) & ~(sizeof(sljit_sw) - 1));
 #endif
 	return SLJIT_SUCCESS;
 }
@@ -214,23 +267,19 @@
 	CHECK(check_sljit_emit_return(compiler, op, src, srcw));
 	SLJIT_ASSERT(compiler->args >= 0);
 
-	compiler->flags_saved = 0;
 	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
 
 	SLJIT_ASSERT(compiler->local_size > 0);
-	FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
-		SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
 
 #if !defined(__APPLE__)
-	if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) {
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
-		FAIL_IF(!inst);
-
-		INC_SIZE(3);
-		inst[0] = MOV_r_rm;
-		inst[1] = (reg_map[SLJIT_SP] << 3) | 0x4 /* SIB */;
-		inst[2] = (4 << 3) | reg_map[SLJIT_SP];
-	}
+	if (compiler->options & SLJIT_F64_ALIGNMENT)
+		EMIT_MOV(compiler, SLJIT_SP, 0, SLJIT_MEM1(SLJIT_SP), compiler->local_size)
+	else
+		FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
+			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
+#else
+	FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
+		SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
 #endif
 
 	size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) +
@@ -247,11 +296,11 @@
 
 	INC_SIZE(size);
 
-	if (compiler->saveds > 0 || compiler->scratches > 9)
+	if (compiler->saveds > 0 || compiler->scratches > 11)
 		POP_REG(reg_map[SLJIT_S0]);
-	if (compiler->saveds > 1 || compiler->scratches > 8)
+	if (compiler->saveds > 1 || compiler->scratches > 10)
 		POP_REG(reg_map[SLJIT_S1]);
-	if (compiler->saveds > 2 || compiler->scratches > 7)
+	if (compiler->saveds > 2 || compiler->scratches > 9)
 		POP_REG(reg_map[SLJIT_S2]);
 	POP_REG(reg_map[TMP_REG1]);
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
@@ -366,7 +415,7 @@
 		if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
 			*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
 
-		if ((a & SLJIT_IMM) || (a == 0))
+		if (a & SLJIT_IMM)
 			*buf_ptr = 0;
 		else if (!(flags & EX86_SSE2_OP1))
 			*buf_ptr = reg_map[a] << 3;
@@ -438,42 +487,324 @@
 /*  Call / return instructions                                           */
 /* --------------------------------------------------------------------- */
 
-static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+
+static sljit_s32 c_fast_call_get_stack_size(sljit_s32 arg_types, sljit_s32 *word_arg_count_ptr)
+{
+	sljit_s32 stack_size = 0;
+	sljit_s32 word_arg_count = 0;
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			stack_size += sizeof(sljit_f32);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			stack_size += sizeof(sljit_f64);
+			break;
+		default:
+			word_arg_count++;
+			if (word_arg_count > 2)
+				stack_size += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	if (word_arg_count_ptr)
+		*word_arg_count_ptr = word_arg_count;
+
+	return stack_size;
+}
+
+static sljit_s32 c_fast_call_with_args(struct sljit_compiler *compiler,
+	sljit_s32 arg_types, sljit_s32 stack_size, sljit_s32 word_arg_count, sljit_s32 swap_args)
 {
 	sljit_u8 *inst;
+	sljit_s32 float_arg_count;
+
+	if (stack_size == sizeof(sljit_sw) && word_arg_count == 3) {
+		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+		FAIL_IF(!inst);
+		INC_SIZE(1);
+		PUSH_REG(reg_map[SLJIT_R2]);
+	}
+	else if (stack_size > 0) {
+		if (word_arg_count >= 4)
+			EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), compiler->saveds_offset - sizeof(sljit_sw));
+
+		FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
+			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, stack_size));
+
+		stack_size = 0;
+		arg_types >>= SLJIT_DEF_SHIFT;
+		word_arg_count = 0;
+		float_arg_count = 0;
+		while (arg_types) {
+			switch (arg_types & SLJIT_DEF_MASK) {
+			case SLJIT_ARG_TYPE_F32:
+				float_arg_count++;
+				FAIL_IF(emit_sse2_store(compiler, 1, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
+				stack_size += sizeof(sljit_f32);
+				break;
+			case SLJIT_ARG_TYPE_F64:
+				float_arg_count++;
+				FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
+				stack_size += sizeof(sljit_f64);
+				break;
+			default:
+				word_arg_count++;
+				if (word_arg_count == 3) {
+					EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), stack_size, SLJIT_R2, 0);
+					stack_size += sizeof(sljit_sw);
+				}
+				else if (word_arg_count == 4) {
+					EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), stack_size, TMP_REG1, 0);
+					stack_size += sizeof(sljit_sw);
+				}
+				break;
+			}
+
+			arg_types >>= SLJIT_DEF_SHIFT;
+		}
+	}
+
+	if (word_arg_count > 0) {
+		if (swap_args) {
+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
+			FAIL_IF(!inst);
+			INC_SIZE(1);
+
+			*inst++ = XCHG_EAX_r | reg_map[SLJIT_R2];
+		}
+		else {
+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
+			FAIL_IF(!inst);
+			INC_SIZE(2);
+
+			*inst++ = MOV_r_rm;
+			*inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
+		}
+	}
+
+	return SLJIT_SUCCESS;
+}
+
+#endif
+
+static sljit_s32 cdecl_call_get_stack_size(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *word_arg_count_ptr)
+{
+	sljit_s32 stack_size = 0;
+	sljit_s32 word_arg_count = 0;
+
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			stack_size += sizeof(sljit_f32);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			stack_size += sizeof(sljit_f64);
+			break;
+		default:
+			word_arg_count++;
+			stack_size += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	if (word_arg_count_ptr)
+		*word_arg_count_ptr = word_arg_count;
+
+	if (stack_size <= compiler->stack_tmp_size)
+		return 0;
+
+#if defined(__APPLE__)
+	return ((stack_size - compiler->stack_tmp_size + 15) & ~15);
+#else
+	return stack_size - compiler->stack_tmp_size;
+#endif
+}
+
+static sljit_s32 cdecl_call_with_args(struct sljit_compiler *compiler,
+	sljit_s32 arg_types, sljit_s32 stack_size, sljit_s32 word_arg_count)
+{
+	sljit_s32 float_arg_count = 0;
+
+	if (word_arg_count >= 4)
+		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), compiler->saveds_offset - sizeof(sljit_sw));
+
+	if (stack_size > 0)
+		FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
+			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, stack_size));
+
+	stack_size = 0;
+	word_arg_count = 0;
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			float_arg_count++;
+			FAIL_IF(emit_sse2_store(compiler, 1, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
+			stack_size += sizeof(sljit_f32);
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			float_arg_count++;
+			FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
+			stack_size += sizeof(sljit_f64);
+			break;
+		default:
+			word_arg_count++;
+			EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), stack_size, (word_arg_count >= 4) ? TMP_REG1 : word_arg_count, 0);
+			stack_size += sizeof(sljit_sw);
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
+	}
+
+	return SLJIT_SUCCESS;
+}
+
+static sljit_s32 post_call_with_args(struct sljit_compiler *compiler,
+	sljit_s32 arg_types, sljit_s32 stack_size)
+{
+	sljit_u8 *inst;
+	sljit_s32 single;
+
+	if (stack_size > 0)
+		FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
+			SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, stack_size));
+
+	if ((arg_types & SLJIT_DEF_MASK) < SLJIT_ARG_TYPE_F32)
+		return SLJIT_SUCCESS;
+
+	single = ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32);
+
+	inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
+	FAIL_IF(!inst);
+	INC_SIZE(3);
+	inst[0] = single ? FSTPS : FSTPD;
+	inst[1] = (0x03 << 3) | 0x04;
+	inst[2] = (0x04 << 3) | reg_map[SLJIT_SP];
+
+	return emit_sse2_load(compiler, single, SLJIT_FR0, SLJIT_MEM1(SLJIT_SP), 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	struct sljit_jump *jump;
+	sljit_s32 stack_size = 0;
+	sljit_s32 word_arg_count;
+
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
 
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
-	inst = (sljit_u8*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
-	FAIL_IF(!inst);
-	INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
+	if ((type & 0xff) == SLJIT_CALL) {
+		stack_size = c_fast_call_get_stack_size(arg_types, &word_arg_count);
+		PTR_FAIL_IF(c_fast_call_with_args(compiler, arg_types, stack_size, word_arg_count, 0));
 
-	if (type >= SLJIT_CALL3)
-		PUSH_REG(reg_map[SLJIT_R2]);
-	*inst++ = MOV_r_rm;
-	*inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
-#else
-	inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
-	FAIL_IF(!inst);
-	INC_SIZE(4 * (type - SLJIT_CALL0));
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+		compiler->skip_checks = 1;
+#endif
 
-	*inst++ = MOV_rm_r;
-	*inst++ = MOD_DISP8 | (reg_map[SLJIT_R0] << 3) | 0x4 /* SIB */;
-	*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
-	*inst++ = 0;
-	if (type >= SLJIT_CALL2) {
-		*inst++ = MOV_rm_r;
-		*inst++ = MOD_DISP8 | (reg_map[SLJIT_R1] << 3) | 0x4 /* SIB */;
-		*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
-		*inst++ = sizeof(sljit_sw);
-	}
-	if (type >= SLJIT_CALL3) {
-		*inst++ = MOV_rm_r;
-		*inst++ = MOD_DISP8 | (reg_map[SLJIT_R2] << 3) | 0x4 /* SIB */;
-		*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
-		*inst++ = 2 * sizeof(sljit_sw);
+		jump = sljit_emit_jump(compiler, type);
+		PTR_FAIL_IF(jump == NULL);
+
+		PTR_FAIL_IF(post_call_with_args(compiler, arg_types, 0));
+		return jump;
 	}
 #endif
-	return SLJIT_SUCCESS;
+
+	stack_size = cdecl_call_get_stack_size(compiler, arg_types, &word_arg_count);
+	PTR_FAIL_IF(cdecl_call_with_args(compiler, arg_types, stack_size, word_arg_count));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	jump = sljit_emit_jump(compiler, type);
+	PTR_FAIL_IF(jump == NULL);
+
+	PTR_FAIL_IF(post_call_with_args(compiler, arg_types, stack_size));
+	return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_s32 stack_size = 0;
+	sljit_s32 word_arg_count;
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+	sljit_s32 swap_args;
+#endif
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+	SLJIT_ASSERT(reg_map[SLJIT_R0] == 0 && reg_map[SLJIT_R2] == 1 && SLJIT_R0 == 1 && SLJIT_R2 == 3);
+
+	if ((type & 0xff) == SLJIT_CALL) {
+		stack_size = c_fast_call_get_stack_size(arg_types, &word_arg_count);
+		swap_args = 0;
+
+		if (word_arg_count > 0) {
+			if ((src & REG_MASK) == SLJIT_R2 || OFFS_REG(src) == SLJIT_R2) {
+				swap_args = 1;
+				if (((src & REG_MASK) | 0x2) == SLJIT_R2)
+					src ^= 0x2;
+				if ((OFFS_REG(src) | 0x2) == SLJIT_R2)
+					src ^= TO_OFFS_REG(0x2);
+			}
+		}
+
+		FAIL_IF(c_fast_call_with_args(compiler, arg_types, stack_size, word_arg_count, swap_args));
+
+		compiler->saveds_offset += stack_size;
+		compiler->locals_offset += stack_size;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+		compiler->skip_checks = 1;
+#endif
+		FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
+
+		compiler->saveds_offset -= stack_size;
+		compiler->locals_offset -= stack_size;
+
+		return post_call_with_args(compiler, arg_types, 0);
+	}
+#endif
+
+	stack_size = cdecl_call_get_stack_size(compiler, arg_types, &word_arg_count);
+	FAIL_IF(cdecl_call_with_args(compiler, arg_types, stack_size, word_arg_count));
+
+	compiler->saveds_offset += stack_size;
+	compiler->locals_offset += stack_size;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+	FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
+
+	compiler->saveds_offset -= stack_size;
+	compiler->locals_offset -= stack_size;
+
+	return post_call_with_args(compiler, arg_types, stack_size);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
@@ -524,7 +855,7 @@
 		INC_SIZE(1 + 1);
 		PUSH_REG(reg_map[src]);
 	}
-	else if (src & SLJIT_MEM) {
+	else {
 		inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
 		FAIL_IF(!inst);
 		*inst++ = GROUP_FF;
@@ -534,16 +865,6 @@
 		FAIL_IF(!inst);
 		INC_SIZE(1);
 	}
-	else {
-		/* SLJIT_IMM. */
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
-		FAIL_IF(!inst);
-
-		INC_SIZE(5 + 1);
-		*inst++ = PUSH_i32;
-		sljit_unaligned_store_sw(inst, srcw);
-		inst += sizeof(sljit_sw);
-	}
 
 	RET();
 	return SLJIT_SUCCESS;
diff --git a/dist2/src/sljit/sljitNativeX86_64.c b/dist2/src/sljit/sljitNativeX86_64.c
index e88dded..635ebd0 100644
--- a/dist2/src/sljit/sljitNativeX86_64.c
+++ b/dist2/src/sljit/sljitNativeX86_64.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -41,64 +41,55 @@
 
 static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
 {
+	int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
+
+	/* The relative jump below specialized for this case. */
+	SLJIT_ASSERT(reg_map[TMP_REG2] >= 8);
+
 	if (type < SLJIT_JUMP) {
 		/* Invert type. */
 		*code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
-		*code_ptr++ = 10 + 3;
+		*code_ptr++ = short_addr ? (6 + 3) : (10 + 3);
 	}
 
-	SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
-	*code_ptr++ = REX_W | REX_B;
-	*code_ptr++ = MOV_r_i32 + 1;
+	*code_ptr++ = short_addr ? REX_B : (REX_W | REX_B);
+	*code_ptr++ = MOV_r_i32 | reg_lmap[TMP_REG2];
 	jump->addr = (sljit_uw)code_ptr;
 
 	if (jump->flags & JUMP_LABEL)
 		jump->flags |= PATCH_MD;
+	else if (short_addr)
+		sljit_unaligned_store_s32(code_ptr, (sljit_s32)jump->u.target);
 	else
 		sljit_unaligned_store_sw(code_ptr, jump->u.target);
 
-	code_ptr += sizeof(sljit_sw);
+	code_ptr += short_addr ? sizeof(sljit_s32) : sizeof(sljit_sw);
+
 	*code_ptr++ = REX_B;
 	*code_ptr++ = GROUP_FF;
-	*code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
-
-	return code_ptr;
-}
-
-static sljit_u8* generate_fixed_jump(sljit_u8 *code_ptr, sljit_sw addr, sljit_s32 type)
-{
-	sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_s32));
-
-	if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) {
-		*code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32;
-		sljit_unaligned_store_sw(code_ptr, delta);
-	}
-	else {
-		SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
-		*code_ptr++ = REX_W | REX_B;
-		*code_ptr++ = MOV_r_i32 + 1;
-		sljit_unaligned_store_sw(code_ptr, addr);
-		code_ptr += sizeof(sljit_sw);
-		*code_ptr++ = REX_B;
-		*code_ptr++ = GROUP_FF;
-		*code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
-	}
+	*code_ptr++ = MOD_REG | (type >= SLJIT_FAST_CALL ? CALL_rm : JMP_rm) | reg_lmap[TMP_REG2];
 
 	return code_ptr;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 i, tmp, size, saved_register_size;
+	sljit_s32 args, i, tmp, size, saved_register_size;
 	sljit_u8 *inst;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
 
-	compiler->flags_saved = 0;
+#ifdef _WIN64
+	/* Two/four register slots for parameters plus space for xmm6 register if needed. */
+	if (fscratches >= 6 || fsaveds >= 1)
+		compiler->locals_offset = 6 * sizeof(sljit_sw);
+	else
+		compiler->locals_offset = ((scratches > 2) ? 4 : 2) * sizeof(sljit_sw);
+#endif
 
 	/* Including the return address saved by the call instruction. */
 	saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
@@ -124,6 +115,8 @@
 		PUSH_REG(reg_lmap[i]);
 	}
 
+	args = get_arg_count(arg_types);
+
 	if (args > 0) {
 		size = args * 3;
 		inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
@@ -177,7 +170,7 @@
 		INC_SIZE(4 + (3 + sizeof(sljit_s32)));
 		*inst++ = REX_W;
 		*inst++ = GROUP_BINARY_83;
-		*inst++ = MOD_REG | SUB | 4;
+		*inst++ = MOD_REG | SUB | reg_map[SLJIT_SP];
 		/* Allocated size for registers must be divisible by 8. */
 		SLJIT_ASSERT(!(saved_register_size & 0x7));
 		/* Aligned to 16 byte. */
@@ -189,7 +182,7 @@
 			local_size -= 4 * sizeof(sljit_sw);
 		}
 		/* Second instruction */
-		SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] < 8, temporary_reg1_is_loreg);
+		SLJIT_ASSERT(reg_map[SLJIT_R0] < 8);
 		*inst++ = REX_W;
 		*inst++ = MOV_rm_i32;
 		*inst++ = MOD_REG | reg_lmap[SLJIT_R0];
@@ -198,29 +191,30 @@
 			|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 		compiler->skip_checks = 1;
 #endif
-		FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
+		FAIL_IF(sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARG1(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
 	}
 #endif
 
-	SLJIT_ASSERT(local_size > 0);
-	if (local_size <= 127) {
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
-		FAIL_IF(!inst);
-		INC_SIZE(4);
-		*inst++ = REX_W;
-		*inst++ = GROUP_BINARY_83;
-		*inst++ = MOD_REG | SUB | 4;
-		*inst++ = local_size;
-	}
-	else {
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
-		FAIL_IF(!inst);
-		INC_SIZE(7);
-		*inst++ = REX_W;
-		*inst++ = GROUP_BINARY_81;
-		*inst++ = MOD_REG | SUB | 4;
-		sljit_unaligned_store_s32(inst, local_size);
-		inst += sizeof(sljit_s32);
+	if (local_size > 0) {
+		if (local_size <= 127) {
+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+			FAIL_IF(!inst);
+			INC_SIZE(4);
+			*inst++ = REX_W;
+			*inst++ = GROUP_BINARY_83;
+			*inst++ = MOD_REG | SUB | reg_map[SLJIT_SP];
+			*inst++ = local_size;
+		}
+		else {
+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
+			FAIL_IF(!inst);
+			INC_SIZE(7);
+			*inst++ = REX_W;
+			*inst++ = GROUP_BINARY_81;
+			*inst++ = MOD_REG | SUB | reg_map[SLJIT_SP];
+			sljit_unaligned_store_s32(inst, local_size);
+			inst += sizeof(sljit_s32);
+		}
 	}
 
 #ifdef _WIN64
@@ -238,14 +232,22 @@
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
-	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
+	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 saved_register_size;
 
 	CHECK_ERROR();
-	CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
-	set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
+	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);
+
+#ifdef _WIN64
+	/* Two/four register slots for parameters plus space for xmm6 register if needed. */
+	if (fscratches >= 6 || fsaveds >= 1)
+		compiler->locals_offset = 6 * sizeof(sljit_sw);
+	else
+		compiler->locals_offset = ((scratches > 2) ? 4 : 2) * sizeof(sljit_sw);
+#endif
 
 	/* Including the return address saved by the call instruction. */
 	saved_register_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
@@ -261,7 +263,6 @@
 	CHECK_ERROR();
 	CHECK(check_sljit_emit_return(compiler, op, src, srcw));
 
-	compiler->flags_saved = 0;
 	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
 
 #ifdef _WIN64
@@ -275,24 +276,25 @@
 	}
 #endif
 
-	SLJIT_ASSERT(compiler->local_size > 0);
-	if (compiler->local_size <= 127) {
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
-		FAIL_IF(!inst);
-		INC_SIZE(4);
-		*inst++ = REX_W;
-		*inst++ = GROUP_BINARY_83;
-		*inst++ = MOD_REG | ADD | 4;
-		*inst = compiler->local_size;
-	}
-	else {
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
-		FAIL_IF(!inst);
-		INC_SIZE(7);
-		*inst++ = REX_W;
-		*inst++ = GROUP_BINARY_81;
-		*inst++ = MOD_REG | ADD | 4;
-		sljit_unaligned_store_s32(inst, compiler->local_size);
+	if (compiler->local_size > 0) {
+		if (compiler->local_size <= 127) {
+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+			FAIL_IF(!inst);
+			INC_SIZE(4);
+			*inst++ = REX_W;
+			*inst++ = GROUP_BINARY_83;
+			*inst++ = MOD_REG | ADD | 4;
+			*inst = compiler->local_size;
+		}
+		else {
+			inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
+			FAIL_IF(!inst);
+			INC_SIZE(7);
+			*inst++ = REX_W;
+			*inst++ = GROUP_BINARY_81;
+			*inst++ = MOD_REG | ADD | 4;
+			sljit_unaligned_store_s32(inst, compiler->local_size);
+		}
 	}
 
 	tmp = compiler->scratches;
@@ -387,13 +389,12 @@
 	if (b & SLJIT_MEM) {
 		if (!(b & OFFS_REG_MASK)) {
 			if (NOT_HALFWORD(immb)) {
-				if (emit_load_imm64(compiler, TMP_REG3, immb))
-					return NULL;
+				PTR_FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immb));
 				immb = 0;
 				if (b & REG_MASK)
-					b |= TO_OFFS_REG(TMP_REG3);
+					b |= TO_OFFS_REG(TMP_REG2);
 				else
-					b |= TMP_REG3;
+					b |= TMP_REG2;
 			}
 			else if (reg_lmap[b & REG_MASK] == 4)
 				b |= TO_OFFS_REG(SLJIT_SP);
@@ -422,7 +423,11 @@
 			}
 		}
 	}
-	else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8)
+	else if (!(flags & EX86_SSE2_OP2)) {
+		if (reg_map[b] >= 8)
+			rex |= REX_B;
+	}
+	else if (freg_map[b] >= 8)
 		rex |= REX_B;
 
 	if (a & SLJIT_IMM) {
@@ -449,7 +454,11 @@
 	else {
 		SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
 		/* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
-		if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8)
+		if (!(flags & EX86_SSE2_OP1)) {
+			if (reg_map[a] >= 8)
+				rex |= REX_R;
+		}
+		else if (freg_map[a] >= 8)
 			rex |= REX_R;
 	}
 
@@ -476,12 +485,12 @@
 		if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
 			*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
 
-		if ((a & SLJIT_IMM) || (a == 0))
+		if (a & SLJIT_IMM)
 			*buf_ptr = 0;
 		else if (!(flags & EX86_SSE2_OP1))
 			*buf_ptr = reg_lmap[a] << 3;
 		else
-			*buf_ptr = a << 3;
+			*buf_ptr = freg_lmap[a] << 3;
 	}
 	else {
 		if (a & SLJIT_IMM) {
@@ -495,7 +504,7 @@
 	}
 
 	if (!(b & SLJIT_MEM))
-		*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b);
+		*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : freg_lmap[b]);
 	else if ((b & REG_MASK) != SLJIT_UNUSED) {
 		if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
 			if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
@@ -553,42 +562,161 @@
 /*  Call / return instructions                                           */
 /* --------------------------------------------------------------------- */
 
-static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
-{
-	sljit_u8 *inst;
-
 #ifndef _WIN64
-	SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
 
-	inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
-	FAIL_IF(!inst);
-	INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
-	if (type >= SLJIT_CALL3) {
-		*inst++ = REX_W;
-		*inst++ = MOV_r_rm;
-		*inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_R2];
+static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr, sljit_sw srcw)
+{
+	sljit_s32 src = src_ptr ? (*src_ptr) : 0;
+	sljit_s32 word_arg_count = 0;
+
+	SLJIT_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R3] == 1 && reg_map[TMP_REG1] == 2);
+
+	compiler->mode32 = 0;
+
+	/* Remove return value. */
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		if ((arg_types & SLJIT_DEF_MASK) < SLJIT_ARG_TYPE_F32)
+			word_arg_count++;
+		arg_types >>= SLJIT_DEF_SHIFT;
 	}
-	*inst++ = REX_W;
-	*inst++ = MOV_r_rm;
-	*inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_R0];
+
+	if (word_arg_count == 0)
+		return SLJIT_SUCCESS;
+
+	if (src & SLJIT_MEM) {
+		ADJUST_LOCAL_OFFSET(src, srcw);
+		EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
+		*src_ptr = TMP_REG2;
+	}
+	else if (src == SLJIT_R2 && word_arg_count >= SLJIT_R2)
+		*src_ptr = TMP_REG1;
+
+	if (word_arg_count >= 3)
+		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R2, 0);
+	return emit_mov(compiler, SLJIT_R2, 0, SLJIT_R0, 0);
+}
+
 #else
-	SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
 
-	inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
-	FAIL_IF(!inst);
-	INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
-	if (type >= SLJIT_CALL3) {
-		*inst++ = REX_W | REX_R;
-		*inst++ = MOV_r_rm;
-		*inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_R2];
+static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr, sljit_sw srcw)
+{
+	sljit_s32 src = src_ptr ? (*src_ptr) : 0;
+	sljit_s32 arg_count = 0;
+	sljit_s32 word_arg_count = 0;
+	sljit_s32 float_arg_count = 0;
+	sljit_s32 types = 0;
+	sljit_s32 data_trandfer = 0;
+	static sljit_u8 word_arg_regs[5] = { 0, SLJIT_R3, SLJIT_R1, SLJIT_R2, TMP_REG1 };
+
+	SLJIT_ASSERT(reg_map[SLJIT_R3] == 1 && reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R2] == 8 && reg_map[TMP_REG1] == 9);
+
+	compiler->mode32 = 0;
+	arg_types >>= SLJIT_DEF_SHIFT;
+
+	while (arg_types) {
+		types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
+
+		switch (arg_types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+		case SLJIT_ARG_TYPE_F64:
+			arg_count++;
+			float_arg_count++;
+
+			if (arg_count != float_arg_count)
+				data_trandfer = 1;
+			break;
+		default:
+			arg_count++;
+			word_arg_count++;
+
+			if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count]) {
+				data_trandfer = 1;
+
+				if (src == word_arg_regs[arg_count]) {
+					EMIT_MOV(compiler, TMP_REG2, 0, src, 0);
+					*src_ptr = TMP_REG2;
+				}
+			}
+			break;
+		}
+
+		arg_types >>= SLJIT_DEF_SHIFT;
 	}
-	*inst++ = REX_W;
-	*inst++ = MOV_r_rm;
-	*inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_R0];
-#endif
+
+	if (!data_trandfer)
+		return SLJIT_SUCCESS;
+
+	if (src & SLJIT_MEM) {
+		ADJUST_LOCAL_OFFSET(src, srcw);
+		EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
+		*src_ptr = TMP_REG2;
+	}
+
+	while (types) {
+		switch (types & SLJIT_DEF_MASK) {
+		case SLJIT_ARG_TYPE_F32:
+			if (arg_count != float_arg_count)
+				FAIL_IF(emit_sse2_load(compiler, 1, arg_count, float_arg_count, 0));
+			arg_count--;
+			float_arg_count--;
+			break;
+		case SLJIT_ARG_TYPE_F64:
+			if (arg_count != float_arg_count)
+				FAIL_IF(emit_sse2_load(compiler, 0, arg_count, float_arg_count, 0));
+			arg_count--;
+			float_arg_count--;
+			break;
+		default:
+			if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count])
+				EMIT_MOV(compiler, word_arg_regs[arg_count], 0, word_arg_count, 0);
+			arg_count--;
+			word_arg_count--;
+			break;
+		}
+
+		types >>= SLJIT_DEF_SHIFT;
+	}
+
 	return SLJIT_SUCCESS;
 }
 
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types)
+{
+	CHECK_ERROR_PTR();
+	CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+	PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL, 0));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_jump(compiler, type);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 arg_types,
+	sljit_s32 src, sljit_sw srcw)
+{
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+	FAIL_IF(call_with_args(compiler, arg_types, &src, srcw));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+	compiler->skip_checks = 1;
+#endif
+
+	return sljit_emit_ijump(compiler, type, src, srcw);
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
 	sljit_u8 *inst;
@@ -634,11 +762,6 @@
 	CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
-	if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
-		FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));
-		src = TMP_REG1;
-	}
-
 	if (FAST_IS_REG(src)) {
 		if (reg_map[src] < 8) {
 			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
@@ -656,7 +779,7 @@
 			PUSH_REG(reg_lmap[src]);
 		}
 	}
-	else if (src & SLJIT_MEM) {
+	else {
 		/* REX_W is not necessary (src is not immediate). */
 		compiler->mode32 = 1;
 		inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
@@ -668,23 +791,11 @@
 		FAIL_IF(!inst);
 		INC_SIZE(1);
 	}
-	else {
-		SLJIT_ASSERT(IS_HALFWORD(srcw));
-		/* SLJIT_IMM. */
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
-		FAIL_IF(!inst);
-
-		INC_SIZE(5 + 1);
-		*inst++ = PUSH_i32;
-		sljit_unaligned_store_s32(inst, srcw);
-		inst += sizeof(sljit_s32);
-	}
 
 	RET();
 	return SLJIT_SUCCESS;
 }
 
-
 /* --------------------------------------------------------------------- */
 /*  Extend input                                                         */
 /* --------------------------------------------------------------------- */
diff --git a/dist2/src/sljit/sljitNativeX86_common.c b/dist2/src/sljit/sljitNativeX86_common.c
index aa5ba08..ab7b36a 100644
--- a/dist2/src/sljit/sljitNativeX86_common.c
+++ b/dist2/src/sljit/sljitNativeX86_common.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -26,7 +26,11 @@
 
 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
 {
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+	return "x86" SLJIT_CPUINFO " ABI:fastcall";
+#else
 	return "x86" SLJIT_CPUINFO;
+#endif
 }
 
 /*
@@ -35,7 +39,7 @@
      1 - ECX
      2 - EDX
      3 - EBX
-     4 - none
+     4 - ESP
      5 - EBP
      6 - ESI
      7 - EDI
@@ -47,7 +51,7 @@
      1 - RCX
      2 - RDX
      3 - RBX
-     4 - none
+     4 - RSP
      5 - RBP
      6 - RSI
      7 - RDI
@@ -67,12 +71,15 @@
 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
 
 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {
-	0, 0, 2, 1, 0, 0, 0, 0, 7, 6, 3, 4, 5
+	0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 7, 6, 3, 4, 5
 };
 
 #define CHECK_EXTRA_REGS(p, w, do) \
-	if (p >= SLJIT_R3 && p <= SLJIT_R6) { \
-		w = SLJIT_LOCALS_OFFSET + ((p) - (SLJIT_R3 + 4)) * sizeof(sljit_sw); \
+	if (p >= SLJIT_R3 && p <= SLJIT_S3) { \
+		if (p <= compiler->scratches) \
+			w = compiler->saveds_offset - ((p) - SLJIT_R2) * (sljit_sw)sizeof(sljit_sw); \
+		else \
+			w = compiler->locals_offset + ((p) - SLJIT_S2) * (sljit_sw)sizeof(sljit_sw); \
 		p = SLJIT_MEM1(SLJIT_SP); \
 		do; \
 	}
@@ -82,31 +89,39 @@
 /* Last register + 1. */
 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
 
 /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
    Note: avoid to use r12 and r13 for memory addessing
-   therefore r12 is better for SAVED_EREG than SAVED_REG. */
+   therefore r12 is better to be a higher saved register. */
 #ifndef _WIN64
-/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
-	0, 0, 6, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 7, 9
+/* Args: rdi(=7), rsi(=6), rdx(=2), rcx(=1), r8, r9. Scratches: rax(=0), r10, r11 */
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
+	0, 0, 6, 7, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 9
 };
 /* low-map. reg_map & 0x7. */
-static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = {
-	0, 0, 6, 1, 0, 3,  2,  4,  5,  5,  6,  7, 3, 4, 2, 7, 1
+static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
+	0, 0, 6, 7, 1, 0, 3,  2,  4,  5,  5,  6,  7, 3, 4, 2, 1
 };
 #else
-/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
-	0, 0, 2, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 10, 8, 9
+/* Args: rcx(=1), rdx(=2), r8, r9. Scratches: rax(=0), r10, r11 */
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
+	0, 0, 2, 8, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 9, 10
 };
 /* low-map. reg_map & 0x7. */
-static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = {
-	0, 0, 2, 1, 3,  4,  5,  5, 6,  7,  7, 6, 3, 4, 2,  0, 1
+static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
+	0, 0, 2, 0, 1,  3,  4, 5,  5,  6,  7, 7, 6, 3, 4, 1,  2
 };
 #endif
 
+/* Args: xmm0-xmm3 */
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
+	4, 0, 1, 2, 3, 5, 6
+};
+/* low-map. freg_map & 0x7. */
+static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
+	4, 0, 1, 2, 3, 5, 6
+};
+
 #define REX_W		0x48
 #define REX_R		0x44
 #define REX_X		0x42
@@ -166,7 +181,7 @@
 #define CALL_i32	0xe8
 #define CALL_rm		(/* GROUP_FF */ 2 << 3)
 #define CDQ		0x99
-#define CMOVNE_r_rm	(/* GROUP_0F */ 0x45)
+#define CMOVE_r_rm	(/* GROUP_0F */ 0x44)
 #define CMP		(/* BINARY */ 7 << 3)
 #define CMP_EAX_i32	0x3d
 #define CMP_r_rm	0x3b
@@ -176,6 +191,8 @@
 #define CVTTSD2SI_r_xm	0x2c
 #define DIV		(/* GROUP_F7 */ 6 << 3)
 #define DIVSD_x_xm	0x5e
+#define FSTPS		0xd9
+#define FSTPD		0xdd
 #define INT3		0xcc
 #define IDIV		(/* GROUP_F7 */ 7 << 3)
 #define IMUL		(/* GROUP_F7 */ 5 << 3)
@@ -214,6 +231,7 @@
 #define POP_r		0x58
 #define POP_rm		0x8f
 #define POPF		0x9d
+#define PREFETCH	0x18
 #define PUSH_i32	0x68
 #define PUSH_r		0x50
 #define PUSH_rm		(/* GROUP_FF */ 6 << 3)
@@ -409,13 +427,13 @@
 	return 0;
 }
 
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset);
+#else
 static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-static sljit_u8* generate_fixed_jump(sljit_u8 *code_ptr, sljit_sw addr, sljit_s32 type);
 #endif
 
-static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type)
+static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset)
 {
 	sljit_s32 short_jump;
 	sljit_uw label_addr;
@@ -423,7 +441,8 @@
 	if (jump->flags & JUMP_LABEL)
 		label_addr = (sljit_uw)(code + jump->u.label->size);
 	else
-		label_addr = jump->u.target;
+		label_addr = jump->u.target - executable_offset;
+
 	short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127;
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -458,11 +477,7 @@
 		code_ptr += sizeof(sljit_s8);
 	} else {
 		jump->flags |= PATCH_MW;
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-		code_ptr += sizeof(sljit_sw);
-#else
 		code_ptr += sizeof(sljit_s32);
-#endif
 	}
 
 	return code_ptr;
@@ -476,6 +491,8 @@
 	sljit_u8 *buf_ptr;
 	sljit_u8 *buf_end;
 	sljit_u8 len;
+	sljit_sw executable_offset;
+	sljit_sw jump_addr;
 
 	struct sljit_label *label;
 	struct sljit_jump *jump;
@@ -494,6 +511,8 @@
 	label = compiler->labels;
 	jump = compiler->jumps;
 	const_ = compiler->consts;
+	executable_offset = SLJIT_EXEC_OFFSET(code);
+
 	do {
 		buf_ptr = buf->memory;
 		buf_end = buf_ptr + buf->used_size;
@@ -506,35 +525,28 @@
 				buf_ptr += len;
 			}
 			else {
-				if (*buf_ptr >= 4) {
+				if (*buf_ptr >= 2) {
 					jump->addr = (sljit_uw)code_ptr;
 					if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
-						code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4);
-					else
-						code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4);
+						code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset);
+					else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+						code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2, executable_offset);
+#else
+						code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2);
+#endif
+					}
 					jump = jump->next;
 				}
 				else if (*buf_ptr == 0) {
-					label->addr = (sljit_uw)code_ptr;
+					label->addr = ((sljit_uw)code_ptr) + executable_offset;
 					label->size = code_ptr - code;
 					label = label->next;
 				}
-				else if (*buf_ptr == 1) {
+				else { /* *buf_ptr is 1 */
 					const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
 					const_ = const_->next;
 				}
-				else {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-					*code_ptr++ = (*buf_ptr == 2) ? CALL_i32 : JMP_i32;
-					buf_ptr++;
-					sljit_unaligned_store_sw(code_ptr, *(sljit_sw*)buf_ptr - ((sljit_sw)code_ptr + sizeof(sljit_sw)));
-					code_ptr += sizeof(sljit_sw);
-					buf_ptr += sizeof(sljit_sw) - 1;
-#else
-					code_ptr = generate_fixed_jump(code_ptr, *(sljit_sw*)(buf_ptr + 1), *buf_ptr);
-					buf_ptr += sizeof(sljit_sw);
-#endif
-				}
 				buf_ptr++;
 			}
 		} while (buf_ptr < buf_end);
@@ -548,24 +560,26 @@
 
 	jump = compiler->jumps;
 	while (jump) {
+		jump_addr = jump->addr + executable_offset;
+
 		if (jump->flags & PATCH_MB) {
-			SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))) <= 127);
-			*(sljit_u8*)jump->addr = (sljit_u8)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8)));
+			SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8))) <= 127);
+			*(sljit_u8*)jump->addr = (sljit_u8)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8)));
 		} else if (jump->flags & PATCH_MW) {
 			if (jump->flags & JUMP_LABEL) {
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-				sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))));
+				sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_sw))));
 #else
-				SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))) <= HALFWORD_MAX);
-				sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))));
+				SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s32))) <= HALFWORD_MAX);
+				sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.label->addr - (jump_addr + sizeof(sljit_s32))));
 #endif
 			}
 			else {
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-				sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))));
+				sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)(jump->u.target - (jump_addr + sizeof(sljit_sw))));
 #else
-				SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_s32))) <= HALFWORD_MAX);
-				sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.target - (jump->addr + sizeof(sljit_s32))));
+				SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump_addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump_addr + sizeof(sljit_s32))) <= HALFWORD_MAX);
+				sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)(jump->u.target - (jump_addr + sizeof(sljit_s32))));
 #endif
 			}
 		}
@@ -577,25 +591,67 @@
 		jump = jump->next;
 	}
 
-	/* Maybe we waste some space because of short jumps. */
+	/* Some space may be wasted because of short jumps. */
 	SLJIT_ASSERT(code_ptr <= code + compiler->size);
 	compiler->error = SLJIT_ERR_COMPILED;
+	compiler->executable_offset = executable_offset;
 	compiler->executable_size = code_ptr - code;
-	return (void*)code;
+	return (void*)(code + executable_offset);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+	switch (feature_type) {
+	case SLJIT_HAS_FPU:
+#ifdef SLJIT_IS_FPU_AVAILABLE
+		return SLJIT_IS_FPU_AVAILABLE;
+#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
+		if (cpu_has_sse2 == -1)
+			get_cpu_features();
+		return cpu_has_sse2;
+#else /* SLJIT_DETECT_SSE2 */
+		return 1;
+#endif /* SLJIT_DETECT_SSE2 */
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+	case SLJIT_HAS_VIRTUAL_REGISTERS:
+		return 1;
+#endif
+
+	case SLJIT_HAS_CLZ:
+	case SLJIT_HAS_CMOV:
+		if (cpu_has_cmov == -1)
+			get_cpu_features();
+		return cpu_has_cmov;
+
+	case SLJIT_HAS_SSE2:
+#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
+		if (cpu_has_sse2 == -1)
+			get_cpu_features();
+		return cpu_has_sse2;
+#else
+		return 1;
+#endif
+
+	default:
+		return 0;
+	}
 }
 
 /* --------------------------------------------------------------------- */
 /*  Operators                                                            */
 /* --------------------------------------------------------------------- */
 
+#define BINARY_OPCODE(opcode) (((opcode ## _EAX_i32) << 24) | ((opcode ## _r_rm) << 16) | ((opcode ## _rm_r) << 8) | (opcode))
+
 static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
-	sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+	sljit_u32 op_types,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w);
 
 static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
-	sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+	sljit_u32 op_types,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w);
@@ -604,57 +660,19 @@
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw);
 
-static SLJIT_INLINE sljit_s32 emit_save_flags(struct sljit_compiler *compiler)
-{
-	sljit_u8 *inst;
+#define EMIT_MOV(compiler, dst, dstw, src, srcw) \
+	FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
 
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-	inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
-	FAIL_IF(!inst);
-	INC_SIZE(5);
-#else
-	inst = (sljit_u8*)ensure_buf(compiler, 1 + 6);
-	FAIL_IF(!inst);
-	INC_SIZE(6);
-	*inst++ = REX_W;
-#endif
-	*inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */
-	*inst++ = 0x64;
-	*inst++ = 0x24;
-	*inst++ = (sljit_u8)sizeof(sljit_sw);
-	*inst++ = PUSHF;
-	compiler->flags_saved = 1;
-	return SLJIT_SUCCESS;
-}
+static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,
+	sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src);
 
-static SLJIT_INLINE sljit_s32 emit_restore_flags(struct sljit_compiler *compiler, sljit_s32 keep_flags)
-{
-	sljit_u8 *inst;
-
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-	inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
-	FAIL_IF(!inst);
-	INC_SIZE(5);
-	*inst++ = POPF;
-#else
-	inst = (sljit_u8*)ensure_buf(compiler, 1 + 6);
-	FAIL_IF(!inst);
-	INC_SIZE(6);
-	*inst++ = POPF;
-	*inst++ = REX_W;
-#endif
-	*inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */
-	*inst++ = 0x64;
-	*inst++ = 0x24;
-	*inst++ = (sljit_u8)(-(sljit_s8)sizeof(sljit_sw));
-	compiler->flags_saved = keep_flags;
-	return SLJIT_SUCCESS;
-}
+static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,
+	sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw);
 
 #ifdef _WIN32
 #include <malloc.h>
 
-static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size)
+static void SLJIT_FUNC sljit_grow_stack(sljit_sw local_size)
 {
 	/* Workaround for calling the internal _chkstk() function on Windows.
 	This function touches all 4k pages belongs to the requested stack space,
@@ -680,15 +698,8 @@
 {
 	sljit_u8* inst;
 
-	if (dst == SLJIT_UNUSED) {
-		/* No destination, doesn't need to setup flags. */
-		if (src & SLJIT_MEM) {
-			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw);
-			FAIL_IF(!inst);
-			*inst = MOV_r_rm;
-		}
-		return SLJIT_SUCCESS;
-	}
+	SLJIT_ASSERT(dst != SLJIT_UNUSED);
+
 	if (FAST_IS_REG(src)) {
 		inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
 		FAIL_IF(!inst);
@@ -710,8 +721,10 @@
 		}
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 		if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
-			FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw));
-			inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw);
+			/* Immediate to memory move. Only SLJIT_MOV operation copies
+			   an immediate directly into memory so TMP_REG1 can be used. */
+			FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));
+			inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst, dstw);
 			FAIL_IF(!inst);
 			*inst = MOV_rm_r;
 			return SLJIT_SUCCESS;
@@ -729,7 +742,8 @@
 		return SLJIT_SUCCESS;
 	}
 
-	/* Memory to memory move. Requires two instruction. */
+	/* Memory to memory move. Only SLJIT_MOV operation copies
+	   data from memory to memory so TMP_REG1 can be used. */
 	inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src, srcw);
 	FAIL_IF(!inst);
 	*inst = MOV_r_rm;
@@ -739,9 +753,6 @@
 	return SLJIT_SUCCESS;
 }
 
-#define EMIT_MOV(compiler, dst, dstw, src, srcw) \
-	FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
-
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
 {
 	sljit_u8 *inst;
@@ -771,20 +782,17 @@
 	case SLJIT_DIVMOD_SW:
 	case SLJIT_DIV_UW:
 	case SLJIT_DIV_SW:
-		compiler->flags_saved = 0;
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 #ifdef _WIN64
-		SLJIT_COMPILE_ASSERT(
+		SLJIT_ASSERT(
 			reg_map[SLJIT_R0] == 0
 			&& reg_map[SLJIT_R1] == 2
-			&& reg_map[TMP_REG1] > 7,
-			invalid_register_assignment_for_div_mul);
+			&& reg_map[TMP_REG1] > 7);
 #else
-		SLJIT_COMPILE_ASSERT(
+		SLJIT_ASSERT(
 			reg_map[SLJIT_R0] == 0
 			&& reg_map[SLJIT_R1] < 7
-			&& reg_map[TMP_REG1] == 2,
-			invalid_register_assignment_for_div_mul);
+			&& reg_map[TMP_REG1] == 2);
 #endif
 		compiler->mode32 = op & SLJIT_I32_OP;
 #endif
@@ -908,9 +916,6 @@
 	compiler->mode32 = 0;
 #endif
 
-	if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
-		return SLJIT_SUCCESS; /* Empty instruction. */
-
 	if (src & SLJIT_IMM) {
 		if (FAST_IS_REG(dst)) {
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
@@ -1039,6 +1044,30 @@
 	return SLJIT_SUCCESS;
 }
 
+static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_u8* inst;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+	compiler->mode32 = 1;
+#endif
+
+	inst = emit_x86_instruction(compiler, 2, 0, 0, src, srcw);
+	FAIL_IF(!inst);
+	*inst++ = GROUP_0F;
+	*inst++ = PREFETCH;
+
+	if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8)
+		*inst |= (3 << 3);
+	else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16)
+		*inst |= (2 << 3);
+	else
+		*inst |= (1 << 3);
+
+	return SLJIT_SUCCESS;
+}
+
 static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
@@ -1050,9 +1079,6 @@
 	compiler->mode32 = 0;
 #endif
 
-	if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
-		return SLJIT_SUCCESS; /* Empty instruction. */
-
 	if (src & SLJIT_IMM) {
 		if (FAST_IS_REG(dst)) {
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
@@ -1096,14 +1122,6 @@
 {
 	sljit_u8* inst;
 
-	if (dst == SLJIT_UNUSED) {
-		EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
-		inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
-		FAIL_IF(!inst);
-		*inst++ = GROUP_F7;
-		*inst |= opcode;
-		return SLJIT_SUCCESS;
-	}
 	if (dst == src && dstw == srcw) {
 		/* Same input and output */
 		inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
@@ -1112,14 +1130,19 @@
 		*inst |= opcode;
 		return SLJIT_SUCCESS;
 	}
+
+	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED))
+		dst = TMP_REG1;
+
 	if (FAST_IS_REG(dst)) {
 		EMIT_MOV(compiler, dst, 0, src, srcw);
-		inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+		inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0);
 		FAIL_IF(!inst);
 		*inst++ = GROUP_F7;
 		*inst |= opcode;
 		return SLJIT_SUCCESS;
 	}
+
 	EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
 	inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
 	FAIL_IF(!inst);
@@ -1135,20 +1158,12 @@
 {
 	sljit_u8* inst;
 
-	if (dst == SLJIT_UNUSED) {
-		EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
-		inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
-		FAIL_IF(!inst);
-		*inst++ = GROUP_F7;
-		*inst |= NOT_rm;
-		inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0);
-		FAIL_IF(!inst);
-		*inst = OR_r_rm;
-		return SLJIT_SUCCESS;
-	}
+	if (dst == SLJIT_UNUSED)
+		dst = TMP_REG1;
+
 	if (FAST_IS_REG(dst)) {
 		EMIT_MOV(compiler, dst, 0, src, srcw);
-		inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+		inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0);
 		FAIL_IF(!inst);
 		*inst++ = GROUP_F7;
 		*inst |= NOT_rm;
@@ -1157,6 +1172,7 @@
 		*inst = OR_r_rm;
 		return SLJIT_SUCCESS;
 	}
+
 	EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
 	inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
 	FAIL_IF(!inst);
@@ -1169,6 +1185,10 @@
 	return SLJIT_SUCCESS;
 }
 
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+static const sljit_sw emit_clz_arg = 32 + 31;
+#endif
+
 static sljit_s32 emit_clz(struct sljit_compiler *compiler, sljit_s32 op_flags,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
@@ -1177,104 +1197,54 @@
 	sljit_s32 dst_r;
 
 	SLJIT_UNUSED_ARG(op_flags);
-	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
-		/* Just set the zero flag. */
-		EMIT_MOV(compiler, TMP_REG1, 0, src, srcw);
-		inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0);
-		FAIL_IF(!inst);
-		*inst++ = GROUP_F7;
-		*inst |= NOT_rm;
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-		inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REG1, 0);
-#else
-		inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, TMP_REG1, 0);
-#endif
-		FAIL_IF(!inst);
-		*inst |= SHR;
-		return SLJIT_SUCCESS;
-	}
 
-	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
-		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
-		src = TMP_REG1;
-		srcw = 0;
-	}
+	if (cpu_has_cmov == -1)
+		get_cpu_features();
 
-	inst = emit_x86_instruction(compiler, 2, TMP_REG1, 0, src, srcw);
+	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+	inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
 	FAIL_IF(!inst);
 	*inst++ = GROUP_0F;
 	*inst = BSR_r_rm;
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-	if (FAST_IS_REG(dst))
-		dst_r = dst;
-	else {
-		/* Find an unused temporary register. */
-		if ((dst & REG_MASK) != SLJIT_R0 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0))
-			dst_r = SLJIT_R0;
-		else if ((dst & REG_MASK) != SLJIT_R1 && (dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R1))
-			dst_r = SLJIT_R1;
-		else
-			dst_r = SLJIT_R2;
-		EMIT_MOV(compiler, dst, dstw, dst_r, 0);
-	}
-	EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
-#else
-	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
-	compiler->mode32 = 0;
-	EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 64 + 63 : 32 + 31);
-	compiler->mode32 = op_flags & SLJIT_I32_OP;
-#endif
-
-	if (cpu_has_cmov == -1)
-		get_cpu_features();
-
 	if (cpu_has_cmov) {
-		inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0);
+		if (dst_r != TMP_REG1) {
+			EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 32 + 31);
+			inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG1, 0);
+		}
+		else
+			inst = emit_x86_instruction(compiler, 2, dst_r, 0, SLJIT_MEM0(), (sljit_sw)&emit_clz_arg);
+
 		FAIL_IF(!inst);
 		*inst++ = GROUP_0F;
-		*inst = CMOVNE_r_rm;
-	} else {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
-		FAIL_IF(!inst);
-		INC_SIZE(4);
-
-		*inst++ = JE_i8;
-		*inst++ = 2;
-		*inst++ = MOV_r_rm;
-		*inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REG1];
-#else
-		inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
-		FAIL_IF(!inst);
-		INC_SIZE(5);
-
-		*inst++ = JE_i8;
-		*inst++ = 3;
-		*inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REG1] >= 8 ? REX_B : 0);
-		*inst++ = MOV_r_rm;
-		*inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REG1];
-#endif
+		*inst = CMOVE_r_rm;
 	}
+	else
+		FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, 32 + 31));
 
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 	inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
 #else
+	if (cpu_has_cmov) {
+		EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? (64 + 63) : (32 + 31));
+
+		inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
+		FAIL_IF(!inst);
+		*inst++ = GROUP_0F;
+		*inst = CMOVE_r_rm;
+	}
+	else
+		FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? (64 + 63) : (32 + 31)));
+
 	inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, dst_r, 0);
 #endif
+
 	FAIL_IF(!inst);
 	*(inst + 1) |= XOR;
 
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-	if (dst & SLJIT_MEM) {
-		inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
-		FAIL_IF(!inst);
-		*inst = XCHG_r_rm;
-	}
-#else
 	if (dst & SLJIT_MEM)
-		EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
-#endif
+		EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
 	return SLJIT_SUCCESS;
 }
 
@@ -1282,14 +1252,9 @@
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
-	sljit_u8* inst;
-	sljit_s32 update = 0;
 	sljit_s32 op_flags = GET_ALL_FLAGS(op);
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 	sljit_s32 dst_is_ereg = 0;
-	sljit_s32 src_is_ereg = 0;
-#else
-#	define src_is_ereg 0
 #endif
 
 	CHECK_ERROR();
@@ -1298,38 +1263,40 @@
 	ADJUST_LOCAL_OFFSET(src, srcw);
 
 	CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
-	CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
+	CHECK_EXTRA_REGS(src, srcw, (void)0);
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 	compiler->mode32 = op_flags & SLJIT_I32_OP;
 #endif
 
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
+		if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
+			return emit_prefetch(compiler, op, src, srcw);
+		return SLJIT_SUCCESS;
+	}
+
 	op = GET_OPCODE(op);
-	if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
+
+	if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 		compiler->mode32 = 0;
 #endif
 
-		if (op_flags & SLJIT_I32_OP) {
-			if (FAST_IS_REG(src) && src == dst) {
-				if (!TYPE_CAST_NEEDED(op))
-					return SLJIT_SUCCESS;
-			}
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-			if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM))
-				op = SLJIT_MOV_U32;
-			if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM))
-				op = SLJIT_MOVU_U32;
-			if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM))
-				op = SLJIT_MOV_S32;
-			if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM))
-				op = SLJIT_MOVU_S32;
-#endif
+		if (FAST_IS_REG(src) && src == dst) {
+			if (!TYPE_CAST_NEEDED(op))
+				return SLJIT_SUCCESS;
 		}
 
-		SLJIT_COMPILE_ASSERT(SLJIT_MOV + 8 == SLJIT_MOVU, movu_offset);
-		if (op >= SLJIT_MOVU) {
-			update = 1;
-			op -= 8;
+		if (op_flags & SLJIT_I32_OP) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+			if (src & SLJIT_MEM) {
+				if (op == SLJIT_MOV_S32)
+					op = SLJIT_MOV_U32;
+			}
+			else if (src & SLJIT_IMM) {
+				if (op == SLJIT_MOV_U32)
+					op = SLJIT_MOV_S32;
+			}
+#endif
 		}
 
 		if (src & SLJIT_IMM) {
@@ -1361,14 +1328,6 @@
 #endif
 		}
 
-		if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & REG_MASK) && (srcw != 0 || (src & OFFS_REG_MASK) != 0)) {
-			inst = emit_x86_instruction(compiler, 1, src & REG_MASK, 0, src, srcw);
-			FAIL_IF(!inst);
-			*inst = LEA_r_m;
-			src &= SLJIT_MEM | 0xf;
-			srcw = 0;
-		}
-
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 		if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) {
 			SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP));
@@ -1411,40 +1370,23 @@
 		if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1)
 			return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0);
 #endif
-
-		if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & REG_MASK) && (dstw != 0 || (dst & OFFS_REG_MASK) != 0)) {
-			inst = emit_x86_instruction(compiler, 1, dst & REG_MASK, 0, dst, dstw);
-			FAIL_IF(!inst);
-			*inst = LEA_r_m;
-		}
 		return SLJIT_SUCCESS;
 	}
 
-	if (SLJIT_UNLIKELY(GET_FLAGS(op_flags)))
-		compiler->flags_saved = 0;
-
 	switch (op) {
 	case SLJIT_NOT:
-		if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_E))
+		if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_Z))
 			return emit_not_with_flags(compiler, dst, dstw, src, srcw);
 		return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw);
 
 	case SLJIT_NEG:
-		if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
-			FAIL_IF(emit_save_flags(compiler));
 		return emit_unary(compiler, NEG_rm, dst, dstw, src, srcw);
 
 	case SLJIT_CLZ:
-		if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
-			FAIL_IF(emit_save_flags(compiler));
 		return emit_clz(compiler, op_flags, dst, dstw, src, srcw);
 	}
 
 	return SLJIT_SUCCESS;
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-#	undef src_is_ereg
-#endif
 }
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -1456,8 +1398,8 @@
 		*(inst + 1) |= (op_imm); \
 	} \
 	else { \
-		FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
-		inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
+		FAIL_IF(emit_load_imm64(compiler, (arg == TMP_REG1) ? TMP_REG2 : TMP_REG1, immw)); \
+		inst = emit_x86_instruction(compiler, 1, (arg == TMP_REG1) ? TMP_REG2 : TMP_REG1, 0, arg, argw); \
 		FAIL_IF(!inst); \
 		*inst = (op_mr); \
 	}
@@ -1478,12 +1420,16 @@
 #endif
 
 static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
-	sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+	sljit_u32 op_types,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
 	sljit_u8* inst;
+	sljit_u8 op_eax_imm = (op_types >> 24);
+	sljit_u8 op_rm = (op_types >> 16) & 0xff;
+	sljit_u8 op_mr = (op_types >> 8) & 0xff;
+	sljit_u8 op_imm = op_types & 0xff;
 
 	if (dst == SLJIT_UNUSED) {
 		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
@@ -1594,12 +1540,16 @@
 }
 
 static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
-	sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
+	sljit_u32 op_types,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
 	sljit_u8* inst;
+	sljit_u8 op_eax_imm = (op_types >> 24);
+	sljit_u8 op_rm = (op_types >> 16) & 0xff;
+	sljit_u8 op_mr = (op_types >> 8) & 0xff;
+	sljit_u8 op_imm = op_types & 0xff;
 
 	if (dst == SLJIT_UNUSED) {
 		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
@@ -1683,7 +1633,7 @@
 	sljit_u8* inst;
 	sljit_s32 dst_r;
 
-	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
 
 	/* Register destination. */
 	if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
@@ -1735,9 +1685,9 @@
 			sljit_unaligned_store_s32(inst, (sljit_s32)src1w);
 		}
 		else {
-			EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
 			if (dst_r != src2)
 				EMIT_MOV(compiler, dst_r, 0, src2, src2w);
+			FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
 			inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
 			FAIL_IF(!inst);
 			*inst++ = GROUP_0F;
@@ -1778,9 +1728,9 @@
 			sljit_unaligned_store_s32(inst, (sljit_s32)src2w);
 		}
 		else {
-			EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src2w);
 			if (dst_r != src1)
 				EMIT_MOV(compiler, dst_r, 0, src1, src1w);
+			FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
 			inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
 			FAIL_IF(!inst);
 			*inst++ = GROUP_0F;
@@ -1799,13 +1749,13 @@
 		*inst = IMUL_r_rm;
 	}
 
-	if (dst_r == TMP_REG1)
+	if (dst & SLJIT_MEM)
 		EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
 
 	return SLJIT_SUCCESS;
 }
 
-static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, sljit_s32 keep_flags,
+static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler,
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
@@ -1814,12 +1764,10 @@
 	sljit_s32 dst_r, done = 0;
 
 	/* These cases better be left to handled by normal way. */
-	if (!keep_flags) {
-		if (dst == src1 && dstw == src1w)
-			return SLJIT_ERR_UNSUPPORTED;
-		if (dst == src2 && dstw == src2w)
-			return SLJIT_ERR_UNSUPPORTED;
-	}
+	if (dst == src1 && dstw == src1w)
+		return SLJIT_ERR_UNSUPPORTED;
+	if (dst == src2 && dstw == src2w)
+		return SLJIT_ERR_UNSUPPORTED;
 
 	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
 
@@ -1931,7 +1879,7 @@
 	}
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-	if (src2 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+	if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
 #else
 	if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
 #endif
@@ -1948,8 +1896,8 @@
 				*inst = GROUP_F7;
 			}
 			else {
-				FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
-				inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, src1w);
+				FAIL_IF(emit_load_imm64(compiler, TMP_REG1, src2w));
+				inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src1, src1w);
 				FAIL_IF(!inst);
 				*inst = TEST_rm_r;
 			}
@@ -1977,8 +1925,8 @@
 				*inst = GROUP_F7;
 			}
 			else {
-				FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
-				inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, src2w);
+				FAIL_IF(emit_load_imm64(compiler, TMP_REG1, src1w));
+				inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
 				FAIL_IF(!inst);
 				*inst = TEST_rm_r;
 			}
@@ -2079,7 +2027,7 @@
 		*inst |= mode;
 		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
 	}
-	else if (FAST_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
+	else if (SLOW_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
 		if (src1 != dst)
 			EMIT_MOV(compiler, dst, 0, src1, src1w);
 		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);
@@ -2090,25 +2038,26 @@
 		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
 	}
 	else {
-		/* This case is really difficult, since ecx itself may used for
-		   addressing, and we must ensure to work even in that case. */
+		/* This case is complex since ecx itself may be used for
+		   addressing, and this case must be supported as well. */
 		EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-		EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
-#else
-		/* [esp+0] contains the flags. */
-		EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0);
-#endif
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+		EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_PREF_SHIFT_REG, 0);
 		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
 		inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
 		FAIL_IF(!inst);
 		*inst |= mode;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
+		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), 0);
 #else
-		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw));
+		EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
+		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+		inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
+		FAIL_IF(!inst);
+		*inst |= mode;
+		EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
 #endif
-		EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
+		if (dst != SLJIT_UNUSED)
+			return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
 	}
 
 	return SLJIT_SUCCESS;
@@ -2132,7 +2081,7 @@
 		if (!set_flags)
 			return emit_mov(compiler, dst, dstw, src1, src1w);
 		/* OR dst, src, 0 */
-		return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32,
+		return emit_cum_binary(compiler, BINARY_OPCODE(OR),
 			dst, dstw, src1, src1w, SLJIT_IMM, 0);
 	}
 
@@ -2142,10 +2091,10 @@
 	if (!FAST_IS_REG(dst))
 		FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
 
-	FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
+	FAIL_IF(emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w));
 
 	if (FAST_IS_REG(dst))
-		return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
+		return emit_cmp_binary(compiler, (dst == SLJIT_UNUSED) ? TMP_REG1 : dst, dstw, SLJIT_IMM, 0);
 	return SLJIT_SUCCESS;
 }
 
@@ -2167,77 +2116,54 @@
 	compiler->mode32 = op & SLJIT_I32_OP;
 #endif
 
-	if (GET_OPCODE(op) >= SLJIT_MUL) {
-		if (SLJIT_UNLIKELY(GET_FLAGS(op)))
-			compiler->flags_saved = 0;
-		else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
-			FAIL_IF(emit_save_flags(compiler));
-	}
+	if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+		return SLJIT_SUCCESS;
 
 	switch (GET_OPCODE(op)) {
 	case SLJIT_ADD:
-		if (!GET_FLAGS(op)) {
-			if (emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
+		if (!HAS_FLAGS(op)) {
+			if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
 				return compiler->error;
 		}
-		else
-			compiler->flags_saved = 0;
-		if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
-			FAIL_IF(emit_save_flags(compiler));
-		return emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
+		return emit_cum_binary(compiler, BINARY_OPCODE(ADD),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_ADDC:
-		if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
-			FAIL_IF(emit_restore_flags(compiler, 1));
-		else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
-			FAIL_IF(emit_save_flags(compiler));
-		if (SLJIT_UNLIKELY(GET_FLAGS(op)))
-			compiler->flags_saved = 0;
-		return emit_cum_binary(compiler, ADC_r_rm, ADC_rm_r, ADC, ADC_EAX_i32,
+		return emit_cum_binary(compiler, BINARY_OPCODE(ADC),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_SUB:
-		if (!GET_FLAGS(op)) {
-			if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
+		if (!HAS_FLAGS(op)) {
+			if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
 				return compiler->error;
 		}
-		else
-			compiler->flags_saved = 0;
-		if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
-			FAIL_IF(emit_save_flags(compiler));
+
 		if (dst == SLJIT_UNUSED)
 			return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
-		return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
+		return emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_SUBC:
-		if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
-			FAIL_IF(emit_restore_flags(compiler, 1));
-		else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
-			FAIL_IF(emit_save_flags(compiler));
-		if (SLJIT_UNLIKELY(GET_FLAGS(op)))
-			compiler->flags_saved = 0;
-		return emit_non_cum_binary(compiler, SBB_r_rm, SBB_rm_r, SBB, SBB_EAX_i32,
+		return emit_non_cum_binary(compiler, BINARY_OPCODE(SBB),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_MUL:
 		return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_AND:
 		if (dst == SLJIT_UNUSED)
 			return emit_test_binary(compiler, src1, src1w, src2, src2w);
-		return emit_cum_binary(compiler, AND_r_rm, AND_rm_r, AND, AND_EAX_i32,
+		return emit_cum_binary(compiler, BINARY_OPCODE(AND),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_OR:
-		return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32,
+		return emit_cum_binary(compiler, BINARY_OPCODE(OR),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_XOR:
-		return emit_cum_binary(compiler, XOR_r_rm, XOR_rm_r, XOR, XOR_EAX_i32,
+		return emit_cum_binary(compiler, BINARY_OPCODE(XOR),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_SHL:
-		return emit_shift_with_flags(compiler, SHL, GET_FLAGS(op),
+		return emit_shift_with_flags(compiler, SHL, HAS_FLAGS(op),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_LSHR:
-		return emit_shift_with_flags(compiler, SHR, GET_FLAGS(op),
+		return emit_shift_with_flags(compiler, SHR, HAS_FLAGS(op),
 			dst, dstw, src1, src1w, src2, src2w);
 	case SLJIT_ASHR:
-		return emit_shift_with_flags(compiler, SAR, GET_FLAGS(op),
+		return emit_shift_with_flags(compiler, SAR, HAS_FLAGS(op),
 			dst, dstw, src1, src1w, src2, src2w);
 	}
 
@@ -2248,7 +2174,7 @@
 {
 	CHECK_REG_INDEX(check_sljit_get_register_index(reg));
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-	if (reg >= SLJIT_R3 && reg <= SLJIT_R6)
+	if (reg >= SLJIT_R3 && reg <= SLJIT_R8)
 		return -1;
 #endif
 	return reg_map[reg];
@@ -2257,7 +2183,11 @@
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
 {
 	CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 	return reg;
+#else
+	return freg_map[reg];
+#endif
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
@@ -2279,36 +2209,25 @@
 /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */
 
-/* Alignment + 2 * 16 bytes. */
-static sljit_s32 sse2_data[3 + (4 + 4) * 2];
+/* Alignment(3) + 4 * 16 bytes. */
+static sljit_s32 sse2_data[3 + (4 * 4)];
 static sljit_s32 *sse2_buffer;
 
 static void init_compiler(void)
 {
+	/* Align to 16 bytes. */
 	sse2_buffer = (sljit_s32*)(((sljit_uw)sse2_data + 15) & ~0xf);
-	/* Single precision constants. */
+
+	/* Single precision constants (each constant is 16 byte long). */
 	sse2_buffer[0] = 0x80000000;
 	sse2_buffer[4] = 0x7fffffff;
-	/* Double precision constants. */
+	/* Double precision constants (each constant is 16 byte long). */
 	sse2_buffer[8] = 0;
 	sse2_buffer[9] = 0x80000000;
 	sse2_buffer[12] = 0xffffffff;
 	sse2_buffer[13] = 0x7fffffff;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
-{
-#ifdef SLJIT_IS_FPU_AVAILABLE
-	return SLJIT_IS_FPU_AVAILABLE;
-#elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
-	if (cpu_has_sse2 == -1)
-		get_cpu_features();
-	return cpu_has_sse2;
-#else /* SLJIT_DETECT_SSE2 */
-	return 1;
-#endif /* SLJIT_DETECT_SSE2 */
-}
-
 static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode,
 	sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w)
 {
@@ -2349,7 +2268,7 @@
 	sljit_s32 dst, sljit_sw dstw,
 	sljit_s32 src, sljit_sw srcw)
 {
-	sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+	sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
 	sljit_u8 *inst;
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -2362,7 +2281,7 @@
 	*inst++ = GROUP_0F;
 	*inst = CVTTSD2SI_r_xm;
 
-	if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
+	if (dst & SLJIT_MEM)
 		return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
 	return SLJIT_SUCCESS;
 }
@@ -2406,11 +2325,11 @@
 	sljit_s32 src1, sljit_sw src1w,
 	sljit_s32 src2, sljit_sw src2w)
 {
-	compiler->flags_saved = 0;
 	if (!FAST_IS_REG(src1)) {
 		FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
 		src1 = TMP_FREG;
 	}
+
 	return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_F32_OP), src1, src2, src2w);
 }
 
@@ -2455,7 +2374,7 @@
 		return SLJIT_SUCCESS;
 	}
 
-	if (SLOW_IS_REG(dst)) {
+	if (FAST_IS_REG(dst)) {
 		dst_r = dst;
 		if (dst != src)
 			FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw));
@@ -2553,11 +2472,6 @@
 	CHECK_ERROR_PTR();
 	CHECK_PTR(check_sljit_emit_label(compiler));
 
-	/* We should restore the flags before the label,
-	   since other taken jumps has their own flags as well. */
-	if (SLJIT_UNLIKELY(compiler->flags_saved))
-		PTR_FAIL_IF(emit_restore_flags(compiler, 0));
-
 	if (compiler->last_label && compiler->last_label->size == compiler->size)
 		return compiler->last_label;
 
@@ -2582,20 +2496,11 @@
 	CHECK_ERROR_PTR();
 	CHECK_PTR(check_sljit_emit_jump(compiler, type));
 
-	if (SLJIT_UNLIKELY(compiler->flags_saved)) {
-		if ((type & 0xff) <= SLJIT_JUMP)
-			PTR_FAIL_IF(emit_restore_flags(compiler, 0));
-		compiler->flags_saved = 0;
-	}
-
 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 	PTR_FAIL_IF_NULL(jump);
 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
 	type &= 0xff;
 
-	if (type >= SLJIT_CALL1)
-		PTR_FAIL_IF(call_with_args(compiler, type));
-
 	/* Worst case size. */
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 	compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
@@ -2607,7 +2512,7 @@
 	PTR_FAIL_IF_NULL(inst);
 
 	*inst++ = 0;
-	*inst++ = type + 4;
+	*inst++ = type + 2;
 	return jump;
 }
 
@@ -2622,32 +2527,6 @@
 
 	CHECK_EXTRA_REGS(src, srcw, (void)0);
 
-	if (SLJIT_UNLIKELY(compiler->flags_saved)) {
-		if (type <= SLJIT_JUMP)
-			FAIL_IF(emit_restore_flags(compiler, 0));
-		compiler->flags_saved = 0;
-	}
-
-	if (type >= SLJIT_CALL1) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
-		if (src == SLJIT_R2) {
-			EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
-			src = TMP_REG1;
-		}
-		if (src == SLJIT_MEM1(SLJIT_SP) && type >= SLJIT_CALL3)
-			srcw += sizeof(sljit_sw);
-#endif
-#endif
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
-		if (src == SLJIT_R2) {
-			EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
-			src = TMP_REG1;
-		}
-#endif
-		FAIL_IF(call_with_args(compiler, type));
-	}
-
 	if (src == SLJIT_IMM) {
 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 		FAIL_IF_NULL(jump);
@@ -2665,7 +2544,7 @@
 		FAIL_IF_NULL(inst);
 
 		*inst++ = 0;
-		*inst++ = type + 4;
+		*inst++ = type + 2;
 	}
 	else {
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -2682,37 +2561,29 @@
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 	sljit_s32 dst, sljit_sw dstw,
-	sljit_s32 src, sljit_sw srcw,
 	sljit_s32 type)
 {
 	sljit_u8 *inst;
 	sljit_u8 cond_set = 0;
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 	sljit_s32 reg;
-#else
-	/* CHECK_EXTRA_REGS migh overwrite these values. */
+#endif
+	/* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */
 	sljit_s32 dst_save = dst;
 	sljit_sw dstw_save = dstw;
-#endif
 
 	CHECK_ERROR();
-	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
-	SLJIT_UNUSED_ARG(srcw);
-
-	if (dst == SLJIT_UNUSED)
-		return SLJIT_SUCCESS;
+	CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 
 	ADJUST_LOCAL_OFFSET(dst, dstw);
 	CHECK_EXTRA_REGS(dst, dstw, (void)0);
-	if (SLJIT_UNLIKELY(compiler->flags_saved))
-		FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS));
 
 	type &= 0xff;
 	/* setcc = jcc + 0x10. */
 	cond_set = get_jump_code(type) + 0x10;
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-	if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src) {
+	if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst)) {
 		inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3);
 		FAIL_IF(!inst);
 		INC_SIZE(4 + 3);
@@ -2727,7 +2598,7 @@
 		return SLJIT_SUCCESS;
 	}
 
-	reg = (op == SLJIT_MOV && FAST_IS_REG(dst)) ? dst : TMP_REG1;
+	reg = (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG1;
 
 	inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4);
 	FAIL_IF(!inst);
@@ -2738,6 +2609,7 @@
 	*inst++ = cond_set;
 	*inst++ = MOD_REG | reg_lmap[reg];
 	*inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
+	/* The movzx instruction does not affect flags. */
 	*inst++ = GROUP_0F;
 	*inst++ = MOVZX_r_rm8;
 	*inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg];
@@ -2749,12 +2621,15 @@
 		compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV;
 		return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
 	}
+
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 	compiler->skip_checks = 1;
 #endif
-	return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG1, 0);
-#else /* SLJIT_CONFIG_X86_64 */
+	return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0);
+
+#else
+	/* The SLJIT_CONFIG_X86_32 code path starts here. */
 	if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) {
 		if (reg_map[dst] <= 4) {
 			/* Low byte is accessible. */
@@ -2808,8 +2683,9 @@
 		return SLJIT_SUCCESS;
 	}
 
-	if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) {
-		SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] == 0, scratch_reg1_must_be_eax);
+	if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && reg_map[dst] <= 4) {
+		SLJIT_ASSERT(reg_map[SLJIT_R0] == 0);
+
 		if (dst != SLJIT_R0) {
 			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1);
 			FAIL_IF(!inst);
@@ -2868,6 +2744,46 @@
 #endif /* SLJIT_CONFIG_X86_64 */
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+	sljit_s32 dst_reg,
+	sljit_s32 src, sljit_sw srcw)
+{
+	sljit_u8* inst;
+
+	CHECK_ERROR();
+	CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+	dst_reg &= ~SLJIT_I32_OP;
+
+	if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV) || (dst_reg >= SLJIT_R3 && dst_reg <= SLJIT_S3))
+		return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
+#else
+	if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV))
+		return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
+#endif
+
+	/* ADJUST_LOCAL_OFFSET is not needed. */
+	CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+	compiler->mode32 = dst_reg & SLJIT_I32_OP;
+	dst_reg &= ~SLJIT_I32_OP;
+#endif
+
+	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
+		src = TMP_REG1;
+		srcw = 0;
+	}
+
+	inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw);
+	FAIL_IF(!inst);
+	*inst++ = GROUP_0F;
+	*inst = get_jump_code(type & 0xff) - 0x40;
+	return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
 {
 	CHECK_ERROR();
@@ -2886,16 +2802,16 @@
 	if (NOT_HALFWORD(offset)) {
 		FAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset));
 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
-		SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);
+		SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0) != SLJIT_ERR_UNSUPPORTED);
 		return compiler->error;
 #else
-		return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0);
+		return emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, TMP_REG1, 0);
 #endif
 	}
 #endif
 
 	if (offset != 0)
-		return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
+		return emit_lea_binary(compiler, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
 	return emit_mov(compiler, dst, dstw, SLJIT_SP, 0);
 }
 
@@ -2919,14 +2835,11 @@
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 	compiler->mode32 = 0;
-	reg = SLOW_IS_REG(dst) ? dst : TMP_REG1;
+	reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
 
 	if (emit_load_imm64(compiler, reg, init_value))
 		return NULL;
 #else
-	if (dst == SLJIT_UNUSED)
-		dst = TMP_REG1;
-
 	if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
 		return NULL;
 #endif
@@ -2946,82 +2859,18 @@
 	return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
+	SLJIT_UNUSED_ARG(executable_offset);
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-	sljit_unaligned_store_sw((void*)addr, new_addr - (addr + 4));
+	sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);
 #else
-	sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_addr);
+	sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);
 #endif
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
+	SLJIT_UNUSED_ARG(executable_offset);
 	sljit_unaligned_store_sw((void*)addr, new_constant);
 }
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void)
-{
-#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
-	if (cpu_has_sse2 == -1)
-		get_cpu_features();
-	return cpu_has_sse2;
-#else
-	return 1;
-#endif
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void)
-{
-	if (cpu_has_cmov == -1)
-		get_cpu_features();
-	return cpu_has_cmov;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler,
-	sljit_s32 type,
-	sljit_s32 dst_reg,
-	sljit_s32 src, sljit_sw srcw)
-{
-	sljit_u8* inst;
-
-	CHECK_ERROR();
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
-	CHECK_ARGUMENT(sljit_x86_is_cmov_available());
-	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
-	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
-	CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_I32_OP));
-	FUNCTION_CHECK_SRC(src, srcw);
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-		fprintf(compiler->verbose, "  x86_cmov%s %s%s, ",
-			!(dst_reg & SLJIT_I32_OP) ? "" : ".i",
-			jump_names[type & 0xff], JUMP_POSTFIX(type));
-		sljit_verbose_reg(compiler, dst_reg & ~SLJIT_I32_OP);
-		fprintf(compiler->verbose, ", ");
-		sljit_verbose_param(compiler, src, srcw);
-		fprintf(compiler->verbose, "\n");
-	}
-#endif
-
-	ADJUST_LOCAL_OFFSET(src, srcw);
-	CHECK_EXTRA_REGS(src, srcw, (void)0);
-
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-	compiler->mode32 = dst_reg & SLJIT_I32_OP;
-#endif
-	dst_reg &= ~SLJIT_I32_OP;
-
-	if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
-		EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
-		src = TMP_REG1;
-		srcw = 0;
-	}
-
-	inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw);
-	FAIL_IF(!inst);
-	*inst++ = GROUP_0F;
-	*inst = get_jump_code(type & 0xff) - 0x40;
-	return SLJIT_SUCCESS;
-}
diff --git a/dist2/src/sljit/sljitProtExecAllocator.c b/dist2/src/sljit/sljitProtExecAllocator.c
new file mode 100644
index 0000000..8a5b2b3
--- /dev/null
+++ b/dist2/src/sljit/sljitProtExecAllocator.c
@@ -0,0 +1,421 @@
+/*
+ *    Stack-less Just-In-Time compiler
+ *
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright notice, this list of
+ *      conditions and the following disclaimer.
+ *
+ *   2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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.
+ */
+
+/*
+   This file contains a simple executable memory allocator
+
+   It is assumed, that executable code blocks are usually medium (or sometimes
+   large) memory blocks, and the allocator is not too frequently called (less
+   optimized than other allocators). Thus, using it as a generic allocator is
+   not suggested.
+
+   How does it work:
+     Memory is allocated in continuous memory areas called chunks by alloc_chunk()
+     Chunk format:
+     [ block ][ block ] ... [ block ][ block terminator ]
+
+   All blocks and the block terminator is started with block_header. The block
+   header contains the size of the previous and the next block. These sizes
+   can also contain special values.
+     Block size:
+       0 - The block is a free_block, with a different size member.
+       1 - The block is a block terminator.
+       n - The block is used at the moment, and the value contains its size.
+     Previous block size:
+       0 - This is the first block of the memory chunk.
+       n - The size of the previous block.
+
+   Using these size values we can go forward or backward on the block chain.
+   The unused blocks are stored in a chain list pointed by free_blocks. This
+   list is useful if we need to find a suitable memory area when the allocator
+   is called.
+
+   When a block is freed, the new free block is connected to its adjacent free
+   blocks if possible.
+
+     [ free block ][ used block ][ free block ]
+   and "used block" is freed, the three blocks are connected together:
+     [           one big free block           ]
+*/
+
+/* --------------------------------------------------------------------- */
+/*  System (OS) functions                                                */
+/* --------------------------------------------------------------------- */
+
+/* 64 KByte. */
+#define CHUNK_SIZE	0x10000
+
+struct chunk_header {
+	void *executable;
+	int fd;
+};
+
+/*
+   alloc_chunk / free_chunk :
+     * allocate executable system memory chunks
+     * the size is always divisible by CHUNK_SIZE
+   allocator_grab_lock / allocator_release_lock :
+     * make the allocator thread safe
+     * can be empty if the OS (or the application) does not support threading
+     * only the allocator requires this lock, sljit is fully thread safe
+       as it only uses local variables
+*/
+
+#include <fcntl.h>
+
+#ifndef O_NOATIME
+#define O_NOATIME 0
+#endif
+
+#ifdef __O_TMPFILE
+#ifndef O_TMPFILE
+#define O_TMPFILE	(__O_TMPFILE | O_DIRECTORY)
+#endif
+#endif
+
+int mkostemp(char *template, int flags);
+char *secure_getenv(const char *name);
+
+static SLJIT_INLINE int create_tempfile(void)
+{
+	int fd;
+
+	char tmp_name[256];
+	size_t tmp_name_len;
+	char *dir;
+	size_t len;
+
+#ifdef P_tmpdir
+	len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0;
+
+	if (len > 0 && len < sizeof(tmp_name)) {
+		strcpy(tmp_name, P_tmpdir);
+		tmp_name_len = len;
+	}
+	else {
+		strcpy(tmp_name, "/tmp");
+		tmp_name_len = 4;
+	}
+#else
+	strcpy(tmp_name, "/tmp");
+	tmp_name_len = 4;
+#endif
+
+	dir = secure_getenv("TMPDIR");
+	if (dir) {
+		len = strlen(dir);
+		if (len > 0 && len < sizeof(tmp_name)) {
+			strcpy(tmp_name, dir);
+			tmp_name_len = len;
+		}
+	}
+
+	SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));
+
+	while (tmp_name_len > 0 && tmp_name[tmp_name_len - 1] == '/') {
+		tmp_name_len--;
+		tmp_name[tmp_name_len] = '\0';
+	}
+
+#ifdef O_TMPFILE
+	fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, S_IRUSR | S_IWUSR);
+	if (fd != -1)
+		return fd;
+#endif
+
+	if (tmp_name_len + 7 >= sizeof(tmp_name))
+	{
+		return -1;
+	}
+
+	strcpy(tmp_name + tmp_name_len, "/XXXXXX");
+	fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);
+
+	if (fd == -1)
+		return fd;
+
+	if (unlink(tmp_name)) {
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}
+
+static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
+{
+	struct chunk_header *retval;
+	int fd;
+
+	fd = create_tempfile();
+	if (fd == -1)
+		return NULL;
+
+	if (ftruncate(fd, size)) {
+		close(fd);
+		return NULL;
+	}
+
+	retval = (struct chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+	if (retval == MAP_FAILED) {
+		close(fd);
+		return NULL;
+	}
+
+	retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
+
+	if (retval->executable == MAP_FAILED) {
+		munmap(retval, size);
+		close(fd);
+		return NULL;
+	}
+
+	retval->fd = fd;
+	return retval;
+}
+
+static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
+{
+	struct chunk_header *header = ((struct chunk_header *)chunk) - 1;
+
+	int fd = header->fd;
+	munmap(header->executable, size);
+	munmap(header, size);
+	close(fd);
+}
+
+/* --------------------------------------------------------------------- */
+/*  Common functions                                                     */
+/* --------------------------------------------------------------------- */
+
+#define CHUNK_MASK	(~(CHUNK_SIZE - 1))
+
+struct block_header {
+	sljit_uw size;
+	sljit_uw prev_size;
+	sljit_sw executable_offset;
+};
+
+struct free_block {
+	struct block_header header;
+	struct free_block *next;
+	struct free_block *prev;
+	sljit_uw size;
+};
+
+#define AS_BLOCK_HEADER(base, offset) \
+	((struct block_header*)(((sljit_u8*)base) + offset))
+#define AS_FREE_BLOCK(base, offset) \
+	((struct free_block*)(((sljit_u8*)base) + offset))
+#define MEM_START(base)		((void*)((base) + 1))
+#define ALIGN_SIZE(size)	(((size) + sizeof(struct block_header) + 7) & ~7)
+
+static struct free_block* free_blocks;
+static sljit_uw allocated_size;
+static sljit_uw total_size;
+
+static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
+{
+	free_block->header.size = 0;
+	free_block->size = size;
+
+	free_block->next = free_blocks;
+	free_block->prev = NULL;
+	if (free_blocks)
+		free_blocks->prev = free_block;
+	free_blocks = free_block;
+}
+
+static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
+{
+	if (free_block->next)
+		free_block->next->prev = free_block->prev;
+
+	if (free_block->prev)
+		free_block->prev->next = free_block->next;
+	else {
+		SLJIT_ASSERT(free_blocks == free_block);
+		free_blocks = free_block->next;
+	}
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+	struct chunk_header *chunk_header;
+	struct block_header *header;
+	struct block_header *next_header;
+	struct free_block *free_block;
+	sljit_uw chunk_size;
+	sljit_sw executable_offset;
+
+	allocator_grab_lock();
+	if (size < (64 - sizeof(struct block_header)))
+		size = (64 - sizeof(struct block_header));
+	size = ALIGN_SIZE(size);
+
+	free_block = free_blocks;
+	while (free_block) {
+		if (free_block->size >= size) {
+			chunk_size = free_block->size;
+			if (chunk_size > size + 64) {
+				/* We just cut a block from the end of the free block. */
+				chunk_size -= size;
+				free_block->size = chunk_size;
+				header = AS_BLOCK_HEADER(free_block, chunk_size);
+				header->prev_size = chunk_size;
+				header->executable_offset = free_block->header.executable_offset;
+				AS_BLOCK_HEADER(header, size)->prev_size = size;
+			}
+			else {
+				sljit_remove_free_block(free_block);
+				header = (struct block_header*)free_block;
+				size = chunk_size;
+			}
+			allocated_size += size;
+			header->size = size;
+			allocator_release_lock();
+			return MEM_START(header);
+		}
+		free_block = free_block->next;
+	}
+
+	chunk_size = sizeof(struct chunk_header) + sizeof(struct block_header);
+	chunk_size = (chunk_size + size + CHUNK_SIZE - 1) & CHUNK_MASK;
+
+	chunk_header = alloc_chunk(chunk_size);
+	if (!chunk_header) {
+		allocator_release_lock();
+		return NULL;
+	}
+
+	executable_offset = (sljit_sw)((sljit_u8*)chunk_header->executable - (sljit_u8*)chunk_header);
+
+	chunk_size -= sizeof(struct chunk_header) + sizeof(struct block_header);
+	total_size += chunk_size;
+
+	header = (struct block_header *)(chunk_header + 1);
+
+	header->prev_size = 0;
+	header->executable_offset = executable_offset;
+	if (chunk_size > size + 64) {
+		/* Cut the allocated space into a free and a used block. */
+		allocated_size += size;
+		header->size = size;
+		chunk_size -= size;
+
+		free_block = AS_FREE_BLOCK(header, size);
+		free_block->header.prev_size = size;
+		free_block->header.executable_offset = executable_offset;
+		sljit_insert_free_block(free_block, chunk_size);
+		next_header = AS_BLOCK_HEADER(free_block, chunk_size);
+	}
+	else {
+		/* All space belongs to this allocation. */
+		allocated_size += chunk_size;
+		header->size = chunk_size;
+		next_header = AS_BLOCK_HEADER(header, chunk_size);
+	}
+	next_header->size = 1;
+	next_header->prev_size = chunk_size;
+	next_header->executable_offset = executable_offset;
+	allocator_release_lock();
+	return MEM_START(header);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+	struct block_header *header;
+	struct free_block* free_block;
+
+	allocator_grab_lock();
+	header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
+	header = AS_BLOCK_HEADER(header, -header->executable_offset);
+	allocated_size -= header->size;
+
+	/* Connecting free blocks together if possible. */
+
+	/* If header->prev_size == 0, free_block will equal to header.
+	   In this case, free_block->header.size will be > 0. */
+	free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size);
+	if (SLJIT_UNLIKELY(!free_block->header.size)) {
+		free_block->size += header->size;
+		header = AS_BLOCK_HEADER(free_block, free_block->size);
+		header->prev_size = free_block->size;
+	}
+	else {
+		free_block = (struct free_block*)header;
+		sljit_insert_free_block(free_block, header->size);
+	}
+
+	header = AS_BLOCK_HEADER(free_block, free_block->size);
+	if (SLJIT_UNLIKELY(!header->size)) {
+		free_block->size += ((struct free_block*)header)->size;
+		sljit_remove_free_block((struct free_block*)header);
+		header = AS_BLOCK_HEADER(free_block, free_block->size);
+		header->prev_size = free_block->size;
+	}
+
+	/* The whole chunk is free. */
+	if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
+		/* If this block is freed, we still have (allocated_size / 2) free space. */
+		if (total_size - free_block->size > (allocated_size * 3 / 2)) {
+			total_size -= free_block->size;
+			sljit_remove_free_block(free_block);
+			free_chunk(free_block, free_block->size + sizeof(struct block_header));
+		}
+	}
+
+	allocator_release_lock();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
+{
+	struct free_block* free_block;
+	struct free_block* next_free_block;
+
+	allocator_grab_lock();
+
+	free_block = free_blocks;
+	while (free_block) {
+		next_free_block = free_block->next;
+		if (!free_block->header.prev_size && 
+				AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
+			total_size -= free_block->size;
+			sljit_remove_free_block(free_block);
+			free_chunk(free_block, free_block->size + sizeof(struct block_header));
+		}
+		free_block = next_free_block;
+	}
+
+	SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
+	allocator_release_lock();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr)
+{
+	return ((struct block_header *)(ptr))[-1].executable_offset;
+}
diff --git a/dist2/src/sljit/sljitUtils.c b/dist2/src/sljit/sljitUtils.c
index ec5c321..5c2a838 100644
--- a/dist2/src/sljit/sljitUtils.c
+++ b/dist2/src/sljit/sljitUtils.c
@@ -1,7 +1,7 @@
 /*
  *    Stack-less Just-In-Time compiler
  *
- *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:
@@ -48,12 +48,12 @@
 
 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
 
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
 {
 	/* Always successful. */
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
 {
 	/* Always successful. */
 }
@@ -88,7 +88,7 @@
 
 static HANDLE global_mutex = 0;
 
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
 {
 	/* No idea what to do if an error occures. Static mutexes should never fail... */
 	if (!global_mutex)
@@ -97,7 +97,7 @@
 		WaitForSingleObject(global_mutex, INFINITE);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
 {
 	ReleaseMutex(global_mutex);
 }
@@ -130,12 +130,12 @@
 
 static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
 {
 	pthread_mutex_lock(&global_mutex);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
 {
 	pthread_mutex_unlock(&global_mutex);
 }
@@ -203,19 +203,16 @@
 /* Planning to make it even more clever in the future. */
 static sljit_sw sljit_page_align = 0;
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
 {
 	struct sljit_stack *stack;
-	union {
-		void *ptr;
-		sljit_uw uw;
-	} base;
+	void *ptr;
 #ifdef _WIN32
 	SYSTEM_INFO si;
 #endif
 
 	SLJIT_UNUSED_ARG(allocator_data);
-	if (limit > max_limit || limit < 1)
+	if (start_size > max_size || start_size < 1)
 		return NULL;
 
 #ifdef _WIN32
@@ -233,29 +230,31 @@
 	}
 #endif
 
-	/* Align limit and max_limit. */
-	max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
-
 	stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
 	if (!stack)
 		return NULL;
 
+	/* Align max_size. */
+	max_size = (max_size + sljit_page_align) & ~sljit_page_align;
+
 #ifdef _WIN32
-	base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE);
-	if (!base.ptr) {
+	ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
+	if (!ptr) {
 		SLJIT_FREE(stack, allocator_data);
 		return NULL;
 	}
-	stack->base = base.uw;
-	stack->limit = stack->base;
-	stack->max_limit = stack->base + max_limit;
-	if (sljit_stack_resize(stack, stack->base + limit)) {
+
+	stack->min_start = (sljit_u8 *)ptr;
+	stack->end = stack->min_start + max_size;
+	stack->start = stack->end;
+
+	if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
 		sljit_free_stack(stack, allocator_data);
 		return NULL;
 	}
 #else
 #ifdef MAP_ANON
-	base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+	ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
 #else
 	if (dev_zero < 0) {
 		if (open_dev_zero()) {
@@ -263,73 +262,70 @@
 			return NULL;
 		}
 	}
-	base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
+	ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
 #endif
-	if (base.ptr == MAP_FAILED) {
+	if (ptr == MAP_FAILED) {
 		SLJIT_FREE(stack, allocator_data);
 		return NULL;
 	}
-	stack->base = base.uw;
-	stack->limit = stack->base + limit;
-	stack->max_limit = stack->base + max_limit;
+	stack->min_start = (sljit_u8 *)ptr;
+	stack->end = stack->min_start + max_size;
+	stack->start = stack->end - start_size;
 #endif
-	stack->top = stack->base;
+	stack->top = stack->end;
 	return stack;
 }
 
 #undef PAGE_ALIGN
 
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack, void *allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
 {
 	SLJIT_UNUSED_ARG(allocator_data);
 #ifdef _WIN32
-	VirtualFree((void*)stack->base, 0, MEM_RELEASE);
+	VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
 #else
-	munmap((void*)stack->base, stack->max_limit - stack->base);
+	munmap((void*)stack->min_start, stack->end - stack->min_start);
 #endif
 	SLJIT_FREE(stack, allocator_data);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
+SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
 {
-	sljit_uw aligned_old_limit;
-	sljit_uw aligned_new_limit;
+	sljit_uw aligned_old_start;
+	sljit_uw aligned_new_start;
 
-	if ((new_limit > stack->max_limit) || (new_limit < stack->base))
-		return -1;
+	if ((new_start < stack->min_start) || (new_start >= stack->end))
+		return NULL;
+
 #ifdef _WIN32
-	aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
-	aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
-	if (aligned_new_limit != aligned_old_limit) {
-		if (aligned_new_limit > aligned_old_limit) {
-			if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
-				return -1;
+	aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
+	aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
+	if (aligned_new_start != aligned_old_start) {
+		if (aligned_new_start < aligned_old_start) {
+			if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
+				return NULL;
 		}
 		else {
-			if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
-				return -1;
+			if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
+				return NULL;
 		}
 	}
-	stack->limit = new_limit;
-	return 0;
 #else
-	if (new_limit >= stack->limit) {
-		stack->limit = new_limit;
-		return 0;
-	}
-	aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
-	aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
-	/* If madvise is available, we release the unnecessary space. */
+	if (stack->start < new_start) {
+		aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
+		aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
+		/* If madvise is available, we release the unnecessary space. */
 #if defined(MADV_DONTNEED)
-	if (aligned_new_limit < aligned_old_limit)
-		madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
+		if (aligned_new_start > aligned_old_start)
+			madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
 #elif defined(POSIX_MADV_DONTNEED)
-	if (aligned_new_limit < aligned_old_limit)
-		posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED);
+		if (aligned_new_start > aligned_old_start)
+			posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
 #endif
-	stack->limit = new_limit;
-	return 0;
+	}
 #endif
+	stack->start = new_start;
+	return new_start;
 }
 
 #endif /* SLJIT_UTIL_STACK */
diff --git a/dist2/test-driver b/dist2/test-driver
index 8e575b0..0218a01 100755
--- a/dist2/test-driver
+++ b/dist2/test-driver
@@ -1,9 +1,9 @@
 #! /bin/sh
 # test-driver - basic testsuite driver script.
 
-scriptversion=2013-07-13.22; # UTC
+scriptversion=2016-01-11.22; # UTC
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2017 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -143,6 +143,6 @@
 # eval: (add-hook 'write-file-hooks 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/dist2/testdata/grepinputM b/dist2/testdata/grepinputM
new file mode 100644
index 0000000..9119e3d
--- /dev/null
+++ b/dist2/testdata/grepinputM
@@ -0,0 +1,17 @@
+Data file for multiline tests of multiple matches.
+
+start end in between start
+end and following
+Other stuff
+
+start end in between start
+end and following start
+end other stuff
+
+start end in between start
+
+end
+
+** These two lines must be last.
+start end in between start
+end
diff --git a/dist2/testdata/grepinputv b/dist2/testdata/grepinputv
index d33d326..366d4fb 100644
--- a/dist2/testdata/grepinputv
+++ b/dist2/testdata/grepinputv
@@ -2,3 +2,8 @@
 fox jumps
 over the lazy dog.
 This time it jumps and jumps and jumps.
+This line contains \E and (regex) *meta* [characters].
+The word is cat in this line
+The caterpillar sat on the mat
+The snowcat is not an animal
+A buried feline in the syndicate
diff --git a/dist2/testdata/grepoutput b/dist2/testdata/grepoutput
index 9d41817..e49c2b2 100644
--- a/dist2/testdata/grepoutput
+++ b/dist2/testdata/grepoutput
Binary files differ
diff --git a/dist2/testdata/grepoutputC b/dist2/testdata/grepoutputC
index 0116645..60f249f 100644
--- a/dist2/testdata/grepoutputC
+++ b/dist2/testdata/grepoutputC
@@ -1,8 +1,42 @@
 Arg1: [T] [he ] [ ] Arg2: |T| () () (0)
 Arg1: [T] [his] [s] Arg2: |T| () () (0)
+Arg1: [T] [his] [s] Arg2: |T| () () (0)
+Arg1: [T] [he ] [ ] Arg2: |T| () () (0)
+Arg1: [T] [he ] [ ] Arg2: |T| () () (0)
+Arg1: [T] [he ] [ ] Arg2: |T| () () (0)
 The quick brown
 This time it jumps and jumps and jumps.
+This line contains \E and (regex) *meta* [characters].
+The word is cat in this line
+The caterpillar sat on the mat
+The snowcat is not an animal
 Arg1: [qu] [qu]
 Arg1: [ t] [ t]
+Arg1: [ l] [ l]
+Arg1: [wo] [wo]
+Arg1: [ca] [ca]
+Arg1: [sn] [sn]
 The quick brown
 This time it jumps and jumps and jumps.
+This line contains \E and (regex) *meta* [characters].
+The word is cat in this line
+The caterpillar sat on the mat
+The snowcat is not an animal
+0:T
+The quick brown
+0:T
+This time it jumps and jumps and jumps.
+0:T
+This line contains \E and (regex) *meta* [characters].
+0:T
+The word is cat in this line
+0:T
+The caterpillar sat on the mat
+0:T
+The snowcat is not an animal
+T
+T
+T
+T
+T
+T
diff --git a/dist2/testdata/grepoutputN b/dist2/testdata/grepoutputN
index 1f9f880..ba97e90 100644
--- a/dist2/testdata/grepoutputN
+++ b/dist2/testdata/grepoutputN
Binary files differ
diff --git a/dist2/testdata/testinput1 b/dist2/testdata/testinput1
index 6d7bc80..9a9c5fd 100644
--- a/dist2/testdata/testinput1
+++ b/dist2/testdata/testinput1
@@ -95,17 +95,6 @@
     aaac
     abbbbbbbbbbbac
 
-/^(b+|a){1,2}?bc/
-    bbc
-
-/^(b*|ba){1,2}?bc/
-    babc
-    bbabc
-    bababc
-\= Expect no match
-    bababbc
-    babababc
-
 /^(ba|b*){1,2}?bc/
     babc
     bbabc
@@ -1434,11 +1423,6 @@
 \= Expect no match
     aaa
 
-/[\d-z]+/
-    12-34z
-\= Expect no match
-    aaa
-
 /\x5c/
     \\
 
@@ -3631,13 +3615,6 @@
 /a*/g
     abbab
 
-/^[\d-a]/
-    abcde
-    -things
-    0digit
-\= Expect no match
-    bcdef    
-    
 /[[:space:]]+/
     > \x09\x0a\x0c\x0d\x0b<
      
@@ -5792,4 +5769,424 @@
     aaaccccaaa
     bccccb 
 
+# /x does not apply to MARK labels 
+
+/x (*MARK:ab cd # comment
+ef) x/x,mark
+    axxz
+
+/(?<=a(B){0}c)X/
+    acX
+
+/(?<DEFINE>b)(?(DEFINE)(a+))(?&DEFINE)/          
+    bbbb 
+\= Expect no match     
+    baaab
+
+/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\s])/
+    \   Fred:099
+
+/(?=.*X)X$/ 
+    \  X
+
+/(?s)(?=.*?)b/
+    aabc
+
+/(Z)(a)\2{1,2}?(?-i)\1X/i
+    ZaAAZX
+
+/(?'c')XX(?'YYYYYYYYYYYYYYYYYYYYYYYCl')/
+
+/[s[:digit:]\E-H]+/
+    s09-H
+
+/[s[:digit:]\Q\E-H]+/
+    s09-H
+
+/a+(?:|b)a/
+    aaaa
+
+/X?(R||){3335}/
+
+/(?1)(A(*COMMIT)|B)D/
+    ABD
+    XABD
+    BAD
+    ABXABD  
+\= Expect no match 
+    ABX 
+
+/(?(DEFINE)(?<m> 1? (?=(?<cond>2)?) 1 2 (?('cond')|3)))
+    \A
+    ()
+    (?&m)
+    \Z/x
+    123
+
+/^(?: 
+(?: A| (1? (?=(?<cond>2)?) (1) 2 (?('cond')|3)) )
+(Z)
+)+$/x
+    AZ123Z
+\= Expect no match     
+    AZ12Z 
+    
+/^ (?(DEFINE) ( (?!(a)\2b)..) )   ()(?1)  /x
+    acb
+\= Expect no match     
+    aab
+    
+'(?>ab|abab){1,5}?M'
+    abababababababababababM
+
+'(?>ab|abab){2}?M'
+    abababM
+
+'((?(?=(a))a)+k)'
+    bbak
+
+'((?(?=(a))a|)+k)'
+    bbak
+
+'(?(?!(b))a|b)+k'
+    ababbalbbadabak
+
+/(?!(b))c|b/
+    Ab
+    Ac 
+
+/(?=(b))b|c/
+    Ab
+    Ac 
+
+/^(.|(.)(?1)\2)$/
+    a
+    aba
+    abcba
+    ababa
+    abcdcba
+
+/^((.)(?1)\2|.?)$/
+    a
+    aba
+    abba
+    abcba
+    ababa
+    abccba
+    abcdcba
+    abcddcba
+
+/^(.)(\1|a(?2))/
+    bab
+
+/^(.|(.)(?1)?\2)$/
+    abcba
+    
+/^(?(?=(a))abc|def)/
+    abc
+
+/^(?(?!(a))def|abc)/
+    abc
+
+/^(?(?=(a)(*ACCEPT))abc|def)/
+    abc
+
+/^(?(?!(a)(*ACCEPT))def|abc)/
+    abc
+
+/^(?1)\d{3}(a)/
+    a123a
+
+# This pattern uses a lot of named subpatterns in order to match email
+# addresses in various formats. It's a heavy test for named subpatterns. In the
+# <atext> group, slash is coded as \x{2f} so that this pattern can also be
+# processed by perltest.sh, which does not cater for an escaped delimiter
+# within the pattern. $ within the pattern must also be escaped. All $ and @
+# characters in subject strings are escaped so that Perl doesn't interpret them
+# as variable insertions and " characters must also be escaped for Perl.
+
+# This set of subpatterns is more or less a direct transliteration of the BNF
+# definitions in RFC2822, without any of the obsolete features. The addition of
+# a possessive + to the definition of <phrase> reduced the match limit in PCRE2
+# from over 5 million to just under 400, and eliminated a very noticeable delay
+# when this file was passed to perltest.sh.
+
+/(?ix)(?(DEFINE)
+(?<addr_spec>       (?&local_part) \@ (?&domain) )
+(?<angle_addr>      (?&CFWS)?+ < (?&addr_spec) > (?&CFWS)?+ )
+(?<atext>           [a-z\d!#\$%&'*+-\x{2f}=?^_`{|}~] )
+(?<atom>            (?&CFWS)?+ (?&atext)+ (?&CFWS)?+ )
+(?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment) )
+(?<ctext>           [^\x{9}\x{10}\x{13}\x{7f}-\x{ff}\ ()\\] )
+(?<comment>         \( (?: (?&FWS)?+ (?&ccontent) )*+ (?&FWS)?+ \) )
+(?<CFWS>            (?: (?&FWS)?+ (?&comment) )* (?# NOT possessive)
+                    (?: (?&FWS)?+ (?&comment) | (?&FWS) ) )
+(?<dcontent>        (?&dtext) | (?&quoted_pair) )
+(?<display_name>    (?&phrase) )
+(?<domain>          (?&dot_atom) | (?&domain_literal) )
+(?<domain_literal>  (?&CFWS)?+ \[ (?: (?&FWS)?+ (?&dcontent) )* (?&FWS)?+ \]
+                    (?&CFWS)?+ )
+(?<dot_atom>        (?&CFWS)?+ (?&dot_atom_text) (?&CFWS)?+ )
+(?<dot_atom_text>   (?&atext)++ (?: \. (?&atext)++)*+ )
+(?<dtext>           [^\x{9}\x{10}\x{13}\x{7f}-\x{ff}\ \[\]\\] )
+(?<FWS>             (?: [\t\ ]*+ \n)?+ [\t\ ]++ )
+(?<local_part>      (?&dot_atom) | (?&quoted_string)  )
+(?<mailbox>         (?&name_addr) | (?&addr_spec) )
+(?<name_addr>       (?&display_name)? (?&angle_addr) )
+(?<phrase>          (?&word)++ )
+(?<qcontent>        (?&qtext) | (?&quoted_pair) )
+(?<quoted_pair>     " (?&text) )
+(?<quoted_string>   (?&CFWS)?+ " (?: (?&FWS)?+ (?&qcontent))* (?&FWS)?+ "
+                    (?&CFWS)?+ )
+(?<qtext>           [^\x{9}\x{10}\x{13}\x{7f}-\x{ff}\ "\\] )
+(?<text>            [^\r\n] )
+(?<word>            (?&atom) | (?&quoted_string) )
+) # End DEFINE
+^(?&mailbox)$/
+    Alan Other <user\@dom.ain>
+    <user\@dom.ain>
+    user\@dom.ain
+    user\@[] 
+    user\@[domain literal] 
+    user\@[domain literal with \"[square brackets\"] inside] 
+    \"A. Other\" <user.1234\@dom.ain> (a comment)
+    A. Other <user.1234\@dom.ain> (a comment)
+    \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+\= Expect no match
+    A missing angle <user\@some.where
+    The quick brown fox
+    
+# -------------------------------------------------------------------------- 
+
+# This pattern uses named groups to match default PCRE2 patterns. It's another
+# heavy test for named subpatterns. Once again, code slash as \x{2f} and escape 
+# $ even in classes so that this works with pcre2test.
+
+/(?sx)(?(DEFINE)
+
+(?<assertion>         (?&simple_assertion) | (?&lookaround) )
+
+(?<atomic_group>      \( \? > (?&regex) \) )
+
+(?<back_reference>    \\ \d+ |
+                      \\g (?: [+-]?\d+ | \{ (?: [+-]?\d+ | (?&groupname) ) \} ) |
+                      \\k <(?&groupname)> |
+                      \\k '(?&groupname)' |
+                      \\k \{ (?&groupname) \} |
+                      \( \? P= (?&groupname) \) )
+
+(?<branch>            (?:(?&assertion) |
+                         (?&callout) |
+                         (?&comment) |
+                         (?&option_setting) |
+                         (?&qualified_item) |
+                         (?&quoted_string) |
+                         (?&quoted_string_empty) | 
+                         (?&special_escape) |
+                         (?&verb)
+                      )* )
+
+(?<callout>           \(\?C (?: \d+ | 
+                      (?: (?<D>["'`^%\#\$]) 
+                        (?: \k'D'\k'D' | (?!\k'D') . )* \k'D' |
+                      \{ (?: \}\} | [^}]*+ )* \} ) 
+                      )? \) )
+
+(?<capturing_group>   \( (?: \? P? < (?&groupname) > | \? ' (?&groupname) ' )?
+                      (?&regex) \) )
+
+(?<character_class>   \[ \^?+ (?: \] (?&class_item)* | (?&class_item)+ ) \] )
+
+(?<character_type>    (?! \\N\{\w+\} ) \\ [dDsSwWhHvVRN] )
+
+(?<class_item>        (?: \[ : (?:
+                      alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|
+                      punct|space|upper|word|xdigit
+                      ) : \] |
+                      (?&quoted_string) |  
+                      (?&quoted_string_empty) | 
+                      (?&escaped_character) | 
+                      (?&character_type) | 
+                      [^]] ) )
+
+(?<comment>           \(\?\# [^)]* \) | (?&quoted_string_empty) | \\E )
+
+(?<condition>         (?: \( [+-]? \d+ \) |
+                          \( < (?&groupname) > \) |
+                          \( ' (?&groupname) ' \) |
+                          \( R \d* \) |
+                          \( R & (?&groupname) \) |
+                          \( (?&groupname) \) | 
+                          \( DEFINE \) |
+                          \( VERSION >?=\d+(?:\.\d\d?)? \) |
+                          (?&callout)?+ (?&comment)* (?&lookaround) ) )
+
+(?<conditional_group> \(\? (?&condition) (?&branch) (?: \| (?&branch) )? \) )
+
+(?<delimited_regex>   (?<delimiter> [-\x{2f}!"'`=_:;,%&@~]) (?&regex) 
+                      \k'delimiter' .* )
+
+(?<escaped_character> \\ (?: 0[0-7]{1,2} | [0-7]{1,3} | o\{ [0-7]+ \} |
+                      x \{ (*COMMIT) [[:xdigit:]]* \} | x [[:xdigit:]]{0,2} | 
+                      [aefnrt] | c[[:print:]] |
+                      [^[:alnum:]] ) )
+
+(?<group>             (?&capturing_group) | (?&non_capturing_group) |
+                      (?&resetting_group) | (?&atomic_group) |
+                      (?&conditional_group) )
+
+(?<groupname>         [a-zA-Z_]\w* )
+
+(?<literal_character> (?! (?&range_qualifier) ) [^[()|*+?.\$\\] )
+
+(?<lookaround>        \(\? (?: = | ! | <= | <! ) (?&regex) \) )
+
+(?<non_capturing_group> \(\? [iJmnsUx-]* : (?&regex) \) )
+
+(?<option_setting>    \(\? [iJmnsUx-]* \) )
+
+(?<qualified_item>    (?:\. |
+                         (?&lookaround) |
+                         (?&back_reference) |
+                         (?&character_class) |
+                         (?&character_type) |
+                         (?&escaped_character) |
+                         (?&group) |
+                         (?&subroutine_call) |
+                         (?&literal_character) |
+                         (?&quoted_string) 
+                      ) (?&comment)? (?&qualifier)? )
+
+(?<qualifier>         (?: [?*+] | (?&range_qualifier) ) [+?]? )
+
+(?<quoted_string>     (?: \\Q (?: (?!\\E | \k'delimiter') . )++ (?: \\E | ) ) ) 
+                      
+(?<quoted_string_empty>  \\Q\\E ) 
+
+(?<range_qualifier>   \{ (?: \d+ (?: , \d* )? | , \d+ ) \} )
+
+(?<regex>             (?&start_item)* (?&branch) (?: \| (?&branch) )* )
+
+(?<resetting_group>   \( \? \| (?&regex) \) )
+
+(?<simple_assertion>  \^ | \$ | \\A | \\b | \\B | \\G | \\z | \\Z )
+
+(?<special_escape>    \\K )
+
+(?<start_item>        \( \* (?:
+                      ANY |
+                      ANYCRLF |
+                      BSR_ANYCRLF |
+                      BSR_UNICODE |
+                      CR |
+                      CRLF |
+                      LF |
+                      LIMIT_MATCH=\d+ |
+                      LIMIT_DEPTH=\d+ |
+                      LIMIT_HEAP=\d+ | 
+                      NOTEMPTY |
+                      NOTEMPTY_ATSTART |
+                      NO_AUTO_POSSESS |
+                      NO_DOTSTAR_ANCHOR |
+                      NO_JIT |
+                      NO_START_OPT |
+                      NUL |
+                      UTF |
+                      UCP ) \) )
+
+(?<subroutine_call>   (?: \(\?R\) | \(\?[+-]?\d+\) |
+                      \(\? (?: & | P> ) (?&groupname) \) |
+                      \\g < (?&groupname) > |
+                      \\g ' (?&groupname) ' |
+                      \\g < [+-]? \d+ > |
+                      \\g ' [+-]? \d+ ) )
+
+(?<verb>              \(\* (?: ACCEPT | FAIL | F | COMMIT |
+                      (?:MARK)?:(?&verbname) |
+                      (?:PRUNE|SKIP|THEN) (?: : (?&verbname)? )? ) \) )
+
+(?<verbname>          [^)]+ )
+
+) # End DEFINE
+# Kick it all off...
+^(?&delimited_regex)$/subject_literal,jitstack=256
+    /^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/
+    /(cat(a(ract|tonic)|erpillar)) \1()2(3)/
+    /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/
+    /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/
+    /<tr([\w\W\s\d][^<>]{0,})><TD([\w\W\s\d][^<>]{0,})>([\d]{0,}\.)(.*)((<BR>([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is
+    /^(?(DEFINE) (?<A> a) (?<B> b) )  (?&A) (?&B) /
+    /(?(DEFINE)(?<byte>2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/
+    /\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/
+    /^(\w++|\s++)*$/
+    /a+b?(*THEN)c+(*FAIL)/
+    /(A (A|B(*ACCEPT)|C) D)(E)/x
+    /^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$/i
+    /A(*PRUNE)B(*SKIP)C(*THEN)D(*COMMIT)E(*F)F(*FAIL)G(?!)H(*ACCEPT)I/B
+    /(?C`a``b`)(?C'a''b')(?C"a""b")(?C^a^^b^)(?C%a%%b%)(?C#a##b#)(?C$a$$b$)(?C{a}}b})/B,callout_info
+    /(?sx)(?(DEFINE)(?<assertion> (?&simple_assertion) | (?&lookaround) )(?<atomic_group> \( \? > (?&regex) \) )(?<back_reference> \\ \d+ | \\g (?: [+-]?\d+ | \{ (?: [+-]?\d+ | (?&groupname) ) \} ) | \\k <(?&groupname)> | \\k '(?&groupname)' | \\k \{ (?&groupname) \} | \( \? P= (?&groupname) \) )(?<branch> (?:(?&assertion) | (?&callout) | (?&comment) | (?&option_setting) | (?&qualified_item) | (?&quoted_string) | (?&quoted_string_empty) | (?&special_escape) | (?&verb) )* )(?<callout> \(\?C (?: \d+ | (?: (?<D>["'`^%\#\$]) (?: \k'D'\k'D' | (?!\k'D') . )* \k'D' | \{ (?: \}\} | [^}]*+ )* \} ) )? \) )(?<capturing_group> \( (?: \? P? < (?&groupname) > | \? ' (?&groupname) ' )? (?&regex) \) )(?<character_class> \[ \^?+ (?: \] (?&class_item)* | (?&class_item)+ ) \] )(?<character_type> (?! \\N\{\w+\} ) \\ [dDsSwWhHvVRN] )(?<class_item> (?: \[ : (?: alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print| punct|space|upper|word|xdigit ) : \] | (?&quoted_string) | (?&quoted_string_empty) | (?&escaped_character) | (?&character_type) | [^]] ) )(?<comment> \(\?\# [^)]* \) | (?&quoted_string_empty) | \\E )(?<condition> (?: \( [+-]? \d+ \) | \( < (?&groupname) > \) | \( ' (?&groupname) ' \) | \( R \d* \) | \( R & (?&groupname) \) | \( (?&groupname) \) | \( DEFINE \) | \( VERSION >?=\d+(?:\.\d\d?)? \) | (?&callout)?+ (?&comment)* (?&lookaround) ) )(?<conditional_group> \(\? (?&condition) (?&branch) (?: \| (?&branch) )? \) )(?<delimited_regex> (?<delimiter> [-\x{2f}!"'`=_:;,%&@~]) (?&regex) \k'delimiter' .* )(?<escaped_character> \\ (?: 0[0-7]{1,2} | [0-7]{1,3} | o\{ [0-7]+ \} | x \{ (*COMMIT) [[:xdigit:]]* \} | x [[:xdigit:]]{0,2} | [aefnrt] | c[[:print:]] | [^[:alnum:]] ) )(?<group> (?&capturing_group) | (?&non_capturing_group) | (?&resetting_group) | (?&atomic_group) | (?&conditional_group) )(?<groupname> [a-zA-Z_]\w* )(?<literal_character> (?! (?&range_qualifier) ) [^[()|*+?.\$\\] )(?<lookaround> \(\? (?: = | ! | <= | <! ) (?&regex) \) )(?<non_capturing_group> \(\? [iJmnsUx-]* : (?&regex) \) )(?<option_setting> \(\? [iJmnsUx-]* \) )(?<qualified_item> (?:\. | (?&lookaround) | (?&back_reference) | (?&character_class) | (?&character_type) | (?&escaped_character) | (?&group) | (?&subroutine_call) | (?&literal_character) | (?&quoted_string) ) (?&comment)? (?&qualifier)? )(?<qualifier> (?: [?*+] | (?&range_qualifier) ) [+?]? )(?<quoted_string> (?: \\Q (?: (?!\\E | \k'delimiter') . )++ (?: \\E | ) ) ) (?<quoted_string_empty> \\Q\\E ) (?<range_qualifier> \{ (?: \d+ (?: , \d* )? | , \d+ ) \} )(?<regex> (?&start_item)* (?&branch) (?: \| (?&branch) )* )(?<resetting_group> \( \? \| (?&regex) \) )(?<simple_assertion> \^ | \$ | \\A | \\b | \\B | \\G | \\z | \\Z )(?<special_escape> \\K )(?<start_item> \( \* (?: ANY | ANYCRLF | BSR_ANYCRLF | BSR_UNICODE | CR | CRLF | LF | LIMIT_MATCH=\d+ | LIMIT_DEPTH=\d+ | LIMIT_HEAP=\d+ | NOTEMPTY | NOTEMPTY_ATSTART | NO_AUTO_POSSESS | NO_DOTSTAR_ANCHOR | NO_JIT | NO_START_OPT | NUL | UTF | UCP ) \) )(?<subroutine_call> (?: \(\?R\) | \(\?[+-]?\d+\) | \(\? (?: & | P> ) (?&groupname) \) | \\g < (?&groupname) > | \\g ' (?&groupname) ' | \\g < [+-]? \d+ > | \\g ' [+-]? \d+ ) )(?<verb> \(\* (?: ACCEPT | FAIL | F | COMMIT | (?:MARK)?:(?&verbname) | (?:PRUNE|SKIP|THEN) (?: : (?&verbname)? )? ) \) )(?<verbname> [^)]+ ))^(?&delimited_regex)$/
+\= Expect no match
+    /((?(?C'')\QX\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
+    /(?:(?(2y)a|b)(X))+/
+    /a(*MARK)b/
+    /a(*CR)b/
+    /(?P<abn>(?P=abn)(?<badstufxxx)/
+
+# -------------------------------------------------------------------------- 
+
+/<(?x:[a b])>/xx
+    < >
+
+/<(?:[a b])>/xx
+    < >
+
+/<(?xxx:[a b])>/
+    < >
+    
+/<(?-x:[a b])>/xx
+    < >
+
+/[[:digit:]-]+/
+    12-24
+
+/((?<=((*ACCEPT)) )\1?\b) /
+\= Expect no match     
+    ((?<=((*ACCEPT)) )\\1?\\b)\x20
+
+/((?<=((*ACCEPT))X)\1?Y)\1/
+    XYYZ
+
+/((?<=((*ACCEPT))X)\1?Y(*ACCEPT))\1/
+    XYYZ
+
+/(?(DEFINE)(?<optional_a>a?)X)^(?&optional_a)a$/
+    aa
+    a
+
+/^(a?)b(?1)a/
+    abaa
+    aba 
+    baa
+    ba  
+
+/^(a?)+b(?1)a/
+    abaa
+    aba 
+    baa
+    ba  
+
+/^(a?)++b(?1)a/
+    abaa
+    aba 
+    baa
+    ba  
+
+/^(a?)+b/
+    b
+    ab
+    aaab 
+
+/(?=a+)a(a+)++b/
+    aab
+
 # End of testinput1 
diff --git a/dist2/testdata/testinput10 b/dist2/testdata/testinput10
index 550e1c9..93d2560 100644
--- a/dist2/testdata/testinput10
+++ b/dist2/testdata/testinput10
@@ -445,4 +445,35 @@
 /(?<=(a)(?-1))x/I,utf
     a\x80zx\=offset=3
 
+/[\W\p{Any}]/B
+    abc
+    123 
+
+/[\W\pL]/B
+    abc
+\= Expect no match
+    123     
+
+/(*:*++++++++++++''''''''''''''''''''+''+++'+++x+++++++++++++++++++++++++++++++++++(++++++++++++++++++++:++++++%++:''''''''''''''''''''''''+++++++++++++++++++++++++++++++++++++++++++++++++++++-++++++++k+++++++''''+++'+++++++++++++++++++++++''''++++++++++++':ƿ)/utf
+
+/[\s[:^ascii:]]/B,ucp
+
+# A special extra option allows excaped surrogate code points in 8-bit mode,
+# but subjects containing them must not be UTF-checked.
+
+/\x{d800}/I,utf,allow_surrogate_escapes
+    \x{d800}\=no_utf_check
+
+/\udfff\o{157401}/utf,alt_bsux,allow_surrogate_escapes
+    \x{dfff}\x{df01}\=no_utf_check
+    
+# This has different starting code units in 8-bit mode. 
+
+/^[^ab]/IB,utf
+    c
+    \x{ff}
+    \x{100}
+\= Expect no match
+    aaa
+
 # End of testinput10
diff --git a/dist2/testdata/testinput11 b/dist2/testdata/testinput11
index 2bdef9b..2d267d6 100644
--- a/dist2/testdata/testinput11
+++ b/dist2/testdata/testinput11
@@ -353,4 +353,19 @@
 
 /(*THEN:\[A]{65501})/expand
 
+# We can use pcre2test's utf8_input modifier to create wide pattern characters,
+# even though this test is run when UTF is not supported.
+
+/abý¿¿¿¿¿z/utf8_input
+    abý¿¿¿¿¿z
+    ab\x{7fffffff}z
+
+/abÿý¿¿¿¿¿z/utf8_input
+    abÿý¿¿¿¿¿z
+    ab\x{ffffffff}z 
+
+/abÿAz/utf8_input
+    abÿAz
+    ab\x{80000041}z 
+
 # End of testinput11
diff --git a/dist2/testdata/testinput12 b/dist2/testdata/testinput12
index 14a7715..b0ab909 100644
--- a/dist2/testdata/testinput12
+++ b/dist2/testdata/testinput12
@@ -343,4 +343,43 @@
 /./utf
     \x{110000}
 
+/(*UTF)abý¿¿¿¿¿z/B
+
+/abý¿¿¿¿¿z/utf
+
+/[\W\p{Any}]/B
+    abc
+    123 
+
+/[\W\pL]/B
+    abc
+    \x{100}
+    \x{308}  
+\= Expect no match
+    123     
+
+/[\s[:^ascii:]]/B,ucp
+
+/\pP/ucp
+    \x{7fffffff}
+
+# A special extra option allows excaped surrogate code points in 32-bit mode,
+# but subjects containing them must not be UTF-checked. These patterns give
+# errors in 16-bit mode.
+
+/\x{d800}/I,utf,allow_surrogate_escapes
+    \x{d800}\=no_utf_check
+
+/\udfff\o{157401}/utf,alt_bsux,allow_surrogate_escapes
+    \x{dfff}\x{df01}\=no_utf_check
+
+# This has different starting code units in 8-bit mode. 
+
+/^[^ab]/IB,utf
+    c
+    \x{ff}
+    \x{100}
+\= Expect no match
+    aaa
+
 # End of testinput12
diff --git a/dist2/testdata/testinput15 b/dist2/testdata/testinput15
index 4ea9ffd..cd12ad1 100644
--- a/dist2/testdata/testinput15
+++ b/dist2/testdata/testinput15
@@ -43,14 +43,14 @@
 
 /(*LIMIT_MATCH=4294967290)abc/
 
-/(*LIMIT_RECURSION=4294967280)abc/I
+/(*LIMIT_DEPTH=4294967280)abc/I
 
 /(a+)*zz/
     aaaaaaaaaaaaaz
     aaaaaaaaaaaaaz\=match_limit=3000
 
 /(a+)*zz/
-    aaaaaaaaaaaaaz\=recursion_limit=10
+    aaaaaaaaaaaaaz\=depth_limit=10
 
 /(*LIMIT_MATCH=3000)(a+)*zz/I
     aaaaaaaaaaaaaz
@@ -63,23 +63,23 @@
     aaaaaaaaaaaaaz
     aaaaaaaaaaaaaz\=match_limit=3000
 
-/(*LIMIT_RECURSION=10)(a+)*zz/I
+/(*LIMIT_DEPTH=10)(a+)*zz/I
     aaaaaaaaaaaaaz
-    aaaaaaaaaaaaaz\=recursion_limit=1000
+    aaaaaaaaaaaaaz\=depth_limit=1000
 
-/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/I
+/(*LIMIT_DEPTH=10)(*LIMIT_DEPTH=1000)(a+)*zz/I
     aaaaaaaaaaaaaz
 
-/(*LIMIT_RECURSION=1000)(a+)*zz/I
+/(*LIMIT_DEPTH=1000)(a+)*zz/I
     aaaaaaaaaaaaaz
-    aaaaaaaaaaaaaz\=recursion_limit=10
+    aaaaaaaaaaaaaz\=depth_limit=10
     
 # These three have infinitely nested recursions. 
     
 /((?2))((?1))/
     abc
 
-/((?(R2)a+|(?1)b))/
+/((?(R2)a+|(?1)b))()/
     aaaabcde
 
 /(?(R)a*(?1)|((?R))b)/
@@ -160,4 +160,12 @@
 /(*NO_AUTO_POSSESS)\w+(?C1)/BI
     abc\=callout_fail=1
 
+# This test breaks the JIT stack limit 
+
+/(|]+){2,2452}/
+    (|]+){2,2452}
+
+/(*LIMIT_HEAP=21)\[(a)]{60}/expand
+    \[a]{60}
+
 # End of testinput15
diff --git a/dist2/testdata/testinput17 b/dist2/testdata/testinput17
index 76925fe..9a73ef1 100644
--- a/dist2/testdata/testinput17
+++ b/dist2/testdata/testinput17
@@ -177,7 +177,7 @@
 /((?2))((?1))/
     abc
 
-/((?(R2)a+|(?1)b))/
+/((?(R2)a+|(?1)b))()/
     aaaabcde
 
 /(?(R)a*(?1)|((?R))b)/
diff --git a/dist2/testdata/testinput18 b/dist2/testdata/testinput18
index e31b96e..755a0c9 100644
--- a/dist2/testdata/testinput18
+++ b/dist2/testdata/testinput18
@@ -5,7 +5,7 @@
 #forbid_utf
 #pattern posix
 
-# Test invalid options
+# Test some invalid options
 
 /abc/auto_callout
 
@@ -14,6 +14,10 @@
 
 /abc/
   abc\=partial_hard
+  
+/a(())bc/parens_nest_limit=1
+
+/abc/allow_surrogate_escapes,max_pattern_length=2
 
 # Real tests
 
@@ -103,4 +107,31 @@
 
 /\[A]{1000000}**/expand,regerror_buffsize=32
 
+//posix_nosub
+    \=offset=70000
+
+/(?=(a\K))/
+    a
+     
+/^d(e)$/posix
+    acdef\=posix_startend=2:4
+    acde\=posix_startend=2 
+\= Expect no match     
+    acdef
+    acdef\=posix_startend=2 
+
+/^a\x{00}b$/posix
+    a\x{00}b\=posix_startend=0:3
+
+/"A" 00 "B"/hex
+    A\x{00}B\=posix_startend=0:3
+    
+/ABC/use_length 
+    ABC
+
+/a\b(c/literal,posix
+    a\\b(c
+
+/a\b(c/literal,posix,dotall
+
 # End of testdata/testinput18
diff --git a/dist2/testdata/testinput19 b/dist2/testdata/testinput19
index 7a90f1a..3bf1720 100644
--- a/dist2/testdata/testinput19
+++ b/dist2/testdata/testinput19
@@ -15,4 +15,7 @@
 /\w/ucp
     +++\x{c2}
     
+/"^AB" 00 "\x{1234}$"/hex,utf
+    AB\x{00}\x{1234}\=posix_startend=0:6 
+    
 # End of testdata/testinput19
diff --git a/dist2/testdata/testinput2 b/dist2/testdata/testinput2
index 9d0759f..5d3a80e 100644
--- a/dist2/testdata/testinput2
+++ b/dist2/testdata/testinput2
@@ -1,12 +1,12 @@
 # This set of tests is not Perl-compatible. It checks on special features
 # of PCRE2's API, error diagnostics, and the compiled code of some patterns.
-# It also checks the non-Perl syntax that PCRE2 supports (Python, .NET, 
-# Oniguruma). There are also some tests where PCRE2 and Perl differ, 
-# either because PCRE2 can't be compatible, or there is a possible Perl 
+# It also checks the non-Perl syntax that PCRE2 supports (Python, .NET,
+# Oniguruma). There are also some tests where PCRE2 and Perl differ,
+# either because PCRE2 can't be compatible, or there is a possible Perl
 # bug.
 
 # NOTE: This is a non-UTF set of tests. When UTF support is needed, use
-# test 5. 
+# test 5.
 
 #forbid_utf
 #newline_default lf any anycrlf
@@ -189,9 +189,9 @@
     the barfoo
     and cattlefoo
 
-/(?<=a+)b/
+/abc(?<=a+)b/
 
-/(?<=aaa|b{0,3})b/
+/12345(?<=aaa|b{0,3})b/
 
 /(?<!(foo)a\1)bar/
 
@@ -330,7 +330,7 @@
 \= Expect no match
     aaaa
     aaaaaa
-    
+
 # Perl does not fail these two for the final subjects. Neither did PCRE until
 # release 8.01. The problem is in backtracking into a subpattern that contains
 # a recursive reference to itself. PCRE has now made these into atomic patterns.
@@ -1062,8 +1062,8 @@
 
 /(?C0)(abc(?C1))*/I
     abcabcabc
-    abcabc\=callout_fail=1:3
-    abcabcabc\=callout_fail=1:3
+    abcabc\=callout_fail=1:4
+    abcabcabc\=callout_fail=1:4
 
 /(\d{3}(?C))*/I
     123\=callout_capture
@@ -1099,6 +1099,9 @@
 
 /(?C)a|b/I
 
+/a|(b)(?C)/I
+    b
+
 /x(ab|(bc|(de|(?R))))/I
     xab
     xbc
@@ -1219,7 +1222,7 @@
    aaabbb
    aaabbb\=callout_data=0
    aaabbb\=callout_data=1
-\= Expect no match    
+\= Expect no match
    aaabbb\=callout_data=-1
 
 /ab(?P<one>cd)ef(?P<two>gh)/I
@@ -1291,19 +1294,19 @@
 /a+b/IB,auto_callout
   ab
   aaaab
-\= Expect no match 
+\= Expect no match
   aaaacb
 
 /(abc|def)x/IB,auto_callout
   abcx
   defx
-\= Expect no match 
+\= Expect no match
   abcdefzx
 
 /(abc|def)x/IB,auto_callout
   abcx
   defx
-\= Expect no match 
+\= Expect no match
   abcdefzx
 
 /(ab|cd){3,4}/I,auto_callout
@@ -1312,11 +1315,11 @@
   abcdcdcdcdcd
 
 /([ab]{,4}c|xy)/IB,auto_callout
-\= Expect no match 
+\= Expect no match
     Note: that { does NOT introduce a quantifier
 
 /([ab]{,4}c|xy)/IB,auto_callout
-\= Expect no match 
+\= Expect no match
     Note: that { does NOT introduce a quantifier
 
 /([ab]{1,4}c|xy){4,5}?123/IB,auto_callout
@@ -1465,7 +1468,7 @@
     a1b\=copy=A
     a2b\=copy=A
     a1b\=copy=Z,copy=A
-    
+
 /(?|(?<a>)(?<b>)(?<a>)|(?<a>)(?<b>)(?<a>))/I,dupnames
 
 /^(?P<A>a)(?P<A>b)/I,dupnames
@@ -1553,7 +1556,7 @@
 \= Expect no match
     xyz\nabclf
     xyz\rabclf
-    
+
 /^abc/Im,newline=cr
     xyz\rabc
 \= Expect no match
@@ -2029,11 +2032,11 @@
     afoo
     \r\nfoo
     \nfoo
-    
+
 /^$/gm,newline=any
     abc\r\rxyz
-    abc\n\rxyz  
-\= Expect no match 
+    abc\n\rxyz
+\= Expect no match
     abc\r\nxyz
 
 /(?m)^$/g,newline=any,aftertext
@@ -2041,7 +2044,7 @@
 
 /(?m)^$|^\r\n/g,newline=any,aftertext
     abc\r\n\r\n
-    
+
 /(?m)$/g,newline=any,aftertext
     abc\r\n\r\n
 
@@ -2050,7 +2053,7 @@
 
 /^X/m
     XABC
-\= Expect no match 
+\= Expect no match
     XABC\=notbol
 
 /(ab|c)(?-1)/B
@@ -2059,8 +2062,8 @@
 /xy(?+1)(abc)/B
     xyabcabc
 \= Expect no match
-    xyabc  
-    
+    xyabc
+
 /x(?-0)y/
 
 /x(?-1)y/
@@ -2073,13 +2076,13 @@
     abcX
     Y
 \= Expect no match
-    abcY   
-    
+    abcY
+
 /^((?(+1)X|Y)(abc))+/B
     YabcXabc
     YabcXabcXabc
 \= Expect no match
-    XabcXabc  
+    XabcXabc
 
 /(?(-1)a)/B
 
@@ -2092,30 +2095,30 @@
 
 /(?<A>tom|bon)-\k{A}/
     tom-tom
-    bon-bon 
+    bon-bon
 \= Expect no match
-    tom-bon  
+    tom-bon
 
 /\g{A/
 
 /(?|(abc)|(xyz))/B
    >abc<
-   >xyz< 
+   >xyz<
 
 /(x)(?|(abc)|(xyz))(x)/B
     xabcx
-    xxyzx 
+    xxyzx
 
 /(x)(?|(abc)(pqr)|(xyz))(x)/B
     xabcpqrx
-    xxyzx 
+    xxyzx
 
 /\H++X/B
 \= Expect no match
     XXXX
-    
+
 /\H+\hY/B
-    XXXX Y 
+    XXXX Y
 
 /\H+ Y/B
 
@@ -2169,7 +2172,7 @@
 /^a+(*FAIL)/auto_callout
 \= Expect no match
     aaaaaa
-    
+
 /a+b?c+(*FAIL)/auto_callout
 \= Expect no match
     aaabccc
@@ -2181,7 +2184,7 @@
 /a+b?(*COMMIT)c+(*FAIL)/auto_callout
 \= Expect no match
     aaabccc
-    
+
 /a+b?(*SKIP)c+(*FAIL)/auto_callout
 \= Expect no match
     aaabcccaaabccc
@@ -2189,7 +2192,7 @@
 /a+b?(*THEN)c+(*FAIL)/auto_callout
 \= Expect no match
     aaabccc
-    
+
 /a(*MARK)b/
 
 /(?i:A{1,}\6666666666)/
@@ -2203,52 +2206,52 @@
 /.+A/newline=crlf
 \= Expect no match
     \r\nA
-    
+
 /\nA/newline=crlf
-    \r\nA 
+    \r\nA
 
 /[\r\n]A/newline=crlf
-    \r\nA 
+    \r\nA
 
 /(\r|\n)A/newline=crlf
-    \r\nA 
+    \r\nA
 
 /a(*CR)b/
 
 /(*CR)a.b/
     a\nb
 \= Expect no match
-    a\rb  
+    a\rb
 
 /(*CR)a.b/newline=lf
     a\nb
 \= Expect no match
-    a\rb  
+    a\rb
 
 /(*LF)a.b/newline=CRLF
     a\rb
 \= Expect no match
-    a\nb  
+    a\nb
 
 /(*CRLF)a.b/
     a\rb
-    a\nb  
+    a\nb
 \= Expect no match
-    a\r\nb  
+    a\r\nb
 
 /(*ANYCRLF)a.b/newline=CR
 \= Expect no match
     a\rb
-    a\nb  
-    a\r\nb  
+    a\nb
+    a\r\nb
 
 /(*ANY)a.b/newline=cr
 \= Expect no match
     a\rb
-    a\nb  
-    a\r\nb  
-    a\x85b 
-    
+    a\nb
+    a\r\nb
+    a\x85b
+
 /(*ANY).*/g
     abc\r\ndef
 
@@ -2258,63 +2261,81 @@
 /(*CRLF).*/g
     abc\r\ndef
 
+/(*NUL)^.*/
+    a\nb\x00ccc
+
+/(*NUL)^.*/s
+    a\nb\x00ccc
+
+/^x/m,newline=NUL
+    ab\x00xy
+
+/'#comment' 0d 0a 00 '^x\' 0a 'y'/x,newline=nul,hex
+    x\nyz
+
+/(*NUL)^X\NY/
+    X\nY
+    X\rY
+\= Expect no match
+    X\x00Y
+
 /a\Rb/I,bsr=anycrlf
     a\rb
     a\nb
     a\r\nb
 \= Expect no match
     a\x85b
-    a\x0bb     
+    a\x0bb
 
 /a\Rb/I,bsr=unicode
     a\rb
     a\nb
     a\r\nb
     a\x85b
-    a\x0bb     
-    
+    a\x0bb
+
 /a\R?b/I,bsr=anycrlf
     a\rb
     a\nb
     a\r\nb
 \= Expect no match
     a\x85b
-    a\x0bb     
+    a\x0bb
 
 /a\R?b/I,bsr=unicode
     a\rb
     a\nb
     a\r\nb
     a\x85b
-    a\x0bb     
-    
+    a\x0bb
+
 /a\R{2,4}b/I,bsr=anycrlf
     a\r\n\nb
     a\n\r\rb
     a\r\n\r\n\r\n\r\nb
 \= Expect no match
     a\x85\x85b
-    a\x0b\x0bb     
+    a\x0b\x0bb
 
 /a\R{2,4}b/I,bsr=unicode
     a\r\rb
     a\n\n\nb
     a\r\n\n\r\rb
     a\x85\x85b
-    a\x0b\x0bb     
-\= Expect no match 
-    a\r\r\r\r\rb 
- 
+    a\x0b\x0bb
+\= Expect no match
+    a\r\r\r\r\rb
+
 /(*BSR_ANYCRLF)a\Rb/I
     a\nb
-    a\rb 
+    a\rb
 
 /(*BSR_UNICODE)a\Rb/I
     a\x85b
 
 /(*BSR_ANYCRLF)(*CRLF)a\Rb/I
     a\nb
-    a\rb 
+    a\rb
 
 /(*CRLF)(*BSR_UNICODE)a\Rb/I
     a\x85b
@@ -2377,9 +2398,9 @@
 
 /^(?+1)(?<a>x|y){0}z/
     xzxx
-    yzyy 
+    yzyy
 \= Expect no match
-    xxz  
+    xxz
 
 /(\3)(\1)(a)/
 \= Expect no match
@@ -2387,12 +2408,12 @@
 
 /(\3)(\1)(a)/alt_bsux,allow_empty_class,match_unset_backref,dupnames
     cat
-    
+
 /TA]/
-    The ACTA] comes 
+    The ACTA] comes
 
 /TA]/alt_bsux,allow_empty_class,match_unset_backref,dupnames
-    The ACTA] comes 
+    The ACTA] comes
 
 /(?2)[]a()b](abc)/
     abcbabc
@@ -2402,12 +2423,12 @@
 
 /(?1)[]a()b](abc)/
     abcbabc
-\= Expect no match 
+\= Expect no match
     abcXabc
 
 /(?1)[^]a()b](abc)/
     abcXabc
-\= Expect no match 
+\= Expect no match
     abcbabc
 
 /(?2)[]a()b](abc)(xyz)/
@@ -2429,23 +2450,23 @@
 
 /a[]+b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
 \= Expect no match
-    ab 
+    ab
 
 /a[]*+b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
 \= Expect no match
-    ab 
+    ab
 
 /a[^]b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
     aXb
-    a\nb 
+    a\nb
 \= Expect no match
-    ab  
-    
+    ab
+
 /a[^]+b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
     aXb
-    a\nX\nXb 
+    a\nX\nXb
 \= Expect no match
-    ab  
+    ab
 
 /a(?!)b/B
 
@@ -2458,32 +2479,32 @@
 
 /(?(?=.*b)b|^)/I,auto_callout
    adc
-   abc 
-   
+   abc
+
 /(?(?=b).*b|^d)/I
 
 /(?(?=.*b).*b|^d)/I
 
 /xyz/auto_callout
-  xyz 
-  abcxyz 
-\= Expect no match 
+  xyz
+  abcxyz
+\= Expect no match
   abc
-  abcxypqr  
-  
+  abcxypqr
+
 /xyz/auto_callout,no_start_optimize
-  abcxyz 
-\= Expect no match 
+  abcxyz
+\= Expect no match
   abc
-  abcxypqr  
-  
+  abcxypqr
+
 /(*NO_START_OPT)xyz/auto_callout
   abcxyz
-  
+
 /(*NO_AUTO_POSSESS)a+b/B
 
 /xyz/auto_callout,no_start_optimize
-  abcxyz 
+  abcxyz
 
 /^"((?(?=[a])[^"])|b)*"$/auto_callout
     "ab"
@@ -2496,133 +2517,133 @@
 
 /^X(?&N)(a)(?|(b)|(q))(c)(d)(?<N>Y)/
     XYabcdY
- 
+
 /Xa{2,4}b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /Xa{2,4}?b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /Xa{2,4}+b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /X\d{2,4}b/
     X\=ps
     X3\=ps
     X33\=ps
     X333\=ps
     X3333\=ps
-    
+
 /X\d{2,4}?b/
     X\=ps
     X3\=ps
     X33\=ps
     X333\=ps
     X3333\=ps
-    
+
 /X\d{2,4}+b/
     X\=ps
     X3\=ps
     X33\=ps
     X333\=ps
     X3333\=ps
-    
+
 /X\D{2,4}b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /X\D{2,4}?b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /X\D{2,4}+b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /X[abc]{2,4}b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /X[abc]{2,4}?b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /X[abc]{2,4}+b/
     X\=ps
     Xa\=ps
     Xaa\=ps
     Xaaa\=ps
     Xaaaa\=ps
-    
+
 /X[^a]{2,4}b/
     X\=ps
     Xz\=ps
     Xzz\=ps
     Xzzz\=ps
     Xzzzz\=ps
-    
+
 /X[^a]{2,4}?b/
     X\=ps
     Xz\=ps
     Xzz\=ps
     Xzzz\=ps
     Xzzzz\=ps
-    
+
 /X[^a]{2,4}+b/
     X\=ps
     Xz\=ps
     Xzz\=ps
     Xzzz\=ps
     Xzzzz\=ps
-    
+
 /(Y)X\1{2,4}b/
     YX\=ps
     YXY\=ps
     YXYY\=ps
     YXYYY\=ps
     YXYYYY\=ps
-    
+
 /(Y)X\1{2,4}?b/
     YX\=ps
     YXY\=ps
     YXYY\=ps
     YXYYY\=ps
     YXYYYY\=ps
-    
+
 /(Y)X\1{2,4}+b/
     YX\=ps
     YXY\=ps
     YXYY\=ps
     YXYYY\=ps
     YXYYYY\=ps
-    
+
 /\++\KZ|\d+X|9+Y/startchar
     ++++123999\=ps
     ++++123999Y\=ps
@@ -2632,7 +2653,7 @@
 \= Expect no match
     Z\=ps
     ZA\=ps
-    
+
 /Z(?!)/
 \= Expect no match
     Z\=ps
@@ -2641,7 +2662,7 @@
 /dog(sbody)?/
     dogs\=ps
     dogs\=ph
-    
+
 /dog(sbody)??/
     dogs\=ps
     dogs\=ph
@@ -2649,7 +2670,7 @@
 /dog|dogsbody/
     dogs\=ps
     dogs\=ph
- 
+
 /dogsbody|dog/
     dogs\=ps
     dogs\=ph
@@ -2661,14 +2682,14 @@
 /abc/
    abc\=ps
    abc\=ph
-   
+
 /abc\K123/startchar
     xyzabc123pqr
     xyzabc12\=ps
     xyzabc12\=ph
-    
+
 /(?<=abc)123/
-    xyzabc123pqr 
+    xyzabc123pqr
     xyzabc12\=ps
     xyzabc12\=ph
 
@@ -2690,11 +2711,11 @@
 \= Expect no match
     abcdef\=notempty
     xyzabcdef\=notempty
-    
+
 /^(?:(?=abc)|abc\K)/aftertext,startchar
     abcdef
     abcdef\=notempty_atstart
-\= Expect no match 
+\= Expect no match
     abcdef\=notempty
 
 /a?b?/aftertext
@@ -2703,79 +2724,79 @@
     xyzabc\=notempty
     xyzabc\=notempty_atstart
     xyz\=notempty_atstart
-\= Expect no match 
+\= Expect no match
     xyz\=notempty
 
 /^a?b?/aftertext
     xyz
     xyzabc
-\= Expect no match 
+\= Expect no match
     xyzabc\=notempty
     xyzabc\=notempty_atstart
     xyz\=notempty_atstart
     xyz\=notempty
-    
+
 /^(?<name>a|b\g<name>c)/
     aaaa
     bacxxx
-    bbaccxxx 
+    bbaccxxx
     bbbacccxx
 
 /^(?<name>a|b\g'name'c)/
     aaaa
     bacxxx
-    bbaccxxx 
+    bbaccxxx
     bbbacccxx
 
 /^(a|b\g<1>c)/
     aaaa
     bacxxx
-    bbaccxxx 
+    bbaccxxx
     bbbacccxx
 
 /^(a|b\g'1'c)/
     aaaa
     bacxxx
-    bbaccxxx 
+    bbaccxxx
     bbbacccxx
 
 /^(a|b\g'-1'c)/
     aaaa
     bacxxx
-    bbaccxxx 
+    bbaccxxx
     bbbacccxx
 
 /(^(a|b\g<-1>c))/
     aaaa
     bacxxx
-    bbaccxxx 
+    bbaccxxx
     bbbacccxx
 
 /(?-i:\g<name>)(?i:(?<name>a))/
     XaaX
-    XAAX 
+    XAAX
 
 /(?i:\g<name>)(?-i:(?<name>a))/
     XaaX
-\= Expect no match 
-    XAAX 
+\= Expect no match
+    XAAX
 
 /(?-i:\g<+1>)(?i:(a))/
     XaaX
-    XAAX 
+    XAAX
 
 /(?=(?<regex>(?#simplesyntax)\$(?<name>[a-zA-Z_\x{7f}-\x{ff}][a-zA-Z0-9_\x{7f}-\x{ff}]*)(?:\[(?<index>[a-zA-Z0-9_\x{7f}-\x{ff}]+|\$\g<name>)\]|->\g<name>(\(.*?\))?)?|(?#simple syntax withbraces)\$\{(?:\g<name>(?<indices>\[(?:\g<index>|'(?:\\.|[^'\\])*'|"(?:\g<regex>|\\.|[^"\\])*")\])?|\g<complex>|\$\{\g<complex>\})\}|(?#complexsyntax)\{(?<complex>\$(?<segment>\g<name>(\g<indices>*|\(.*?\))?)(?:->\g<segment>)*|\$\g<complex>|\$\{\g<complex>\})\}))\{/
 
 /(?<n>a|b|c)\g<n>*/
    abc
-   accccbbb 
+   accccbbb
 
 /^X(?7)(a)(?|(b)|(q)(r)(s))(c)(d)(Y)/
     XYabcdY
 
 /(?<=b(?1)|zzz)(a)/
     xbaax
-    xzzzax 
+    xzzzax
 
 /(a)(?<=b\1)/
 
@@ -2826,7 +2847,7 @@
     (?: [0-9a-f]{1,4} |       # 1-4 hex digits or
     (?(1)0 | () ) )           # if null previously matched, fail; else null
     :                         # followed by colon
-  ){1,7}                      # end item; 1-7 of them required               
+  ){1,7}                      # end item; 1-7 of them required
   [0-9a-f]{1,4} $             # final hex number at end of string
   (?(1)|.)                    # check that there was an empty component
   /Iix
@@ -2838,25 +2859,25 @@
 /(?|(?<a>A)|(?<b>B))/
 
 /(?:a(?<quote> (?<apostrophe>')|(?<realquote>")) |
-    b(?<quote> (?<apostrophe>')|(?<realquote>")) ) 
+    b(?<quote> (?<apostrophe>')|(?<realquote>")) )
     (?('quote')[a-z]+|[0-9]+)/Ix,dupnames
     a"aaaaa
-    b"aaaaa 
-\= Expect no match 
+    b"aaaaa
+\= Expect no match
     b"11111
-    a"11111 
-    
+    a"11111
+
 /^(?|(a)(b)(c)(?<D>d)|(?<D>e)) (?('D')X|Y)/IBx,dupnames
     abcdX
     eX
 \= Expect no match
     abcdY
-    ey     
-    
+    ey
+
 /(?<A>a) (b)(c)  (?<A>d  (?(R&A)$ | (?4)) )/IBx,dupnames
     abcdd
 \= Expect no match
-    abcdde  
+    abcdde
 
 /abcd*/
     xxxxabcd\=ps
@@ -2880,19 +2901,6 @@
     xxxxabcde\=ps
     xxxxabcde\=ph
 
-# This is not in the Perl-compatible test because Perl seems currently to be
-# broken and not behaving as specified in that it *does* bumpalong after
-# hitting (*COMMIT). 
-
-/(?1)(A(*COMMIT)|B)D/
-    ABD
-    XABD
-    BAD
-    ABXABD  
-\= Expect no match 
-    ABX 
-    BAXBAD  
-
 /(\3)(\1)(a)/alt_bsux,allow_empty_class,match_unset_backref,dupnames
     cat
 
@@ -2905,16 +2913,16 @@
 
 /i(?(DEFINE)(?<s>a))/I
     i
-    
+
 /()i(?(1)a)/I
     ia
 
 /(?i)a(?-i)b|c/B
     XabX
     XAbX
-    CcC 
+    CcC
 \= Expect no match
-    XABX   
+    XABX
 
 /(?i)a(?s)b|c/B
 
@@ -2922,20 +2930,20 @@
 
 /^(ab(c\1)d|x){2}$/B
     xabcxd
-    
+
 /^(?&t)*+(?(DEFINE)(?<t>.))$/B
 
 /^(?&t)*(?(DEFINE)(?<t>.))$/B
 
 # This one is here because Perl gives the match as "b" rather than "ab". I
 # believe this to be a Perl bug.
-      
+
 /(?>a\Kb)z|(ab)/
-    ab\=startchar 
+    ab\=startchar
 
 /(?P<L1>(?P<L2>0|)|(?P>L2)(?P>L1))/
     abcd
-    0abc 
+    0abc
 
 /abc(*MARK:)pqr/
 
@@ -2943,7 +2951,7 @@
 
 /abc(*FAIL:123)xyz/
 
-# This should, and does, fail. In Perl, it does not, which I think is a 
+# This should, and does, fail. In Perl, it does not, which I think is a
 # bug because replacing the B in the pattern by (B|D) does make it fail.
 
 /A(*COMMIT)B/aftertext,mark
@@ -2959,37 +2967,37 @@
 /A(*PRUNE)B|A(*PRUNE)C/mark
 \= Expect no match
     AC
-    
+
 # Mark names can be duplicated. Perl doesn't give a mark for this one,
 # though PCRE2 does.
 
 /^A(*:A)B|^X(*:A)Y/mark
 \= Expect no match
     XAQQ
-    
-# COMMIT at the start of a pattern should be the same as an anchor. Perl 
+
+# COMMIT at the start of a pattern should be the same as an anchor. Perl
 # optimizations defeat this. So does the PCRE2 optimization unless we disable
 # it.
 
 /(*COMMIT)ABC/
     ABCDEFG
-    
+
 /(*COMMIT)ABC/no_start_optimize
 \= Expect no match
     DEFGABC
-    
+
 /^(ab (c+(*THEN)cd) | xyz)/x
 \= Expect no match
-    abcccd  
+    abcccd
 
 /^(ab (c+(*PRUNE)cd) | xyz)/x
 \= Expect no match
-    abcccd  
+    abcccd
 
 /^(ab (c+(*FAIL)cd) | xyz)/x
 \= Expect no match
-    abcccd  
-    
+    abcccd
+
 # Perl gets some of these wrong
 
 /(?>.(*ACCEPT))*?5/
@@ -3008,19 +3016,19 @@
     ACBD
 \= Expect no match
     A\nB
-    ACB\n   
+    ACB\n
 
 /A\NB./Bs
     ACBD
-    ACB\n 
+    ACB\n
 \= Expect no match
-    A\nB  
-  
+    A\nB
+
 /A\NB/newline=crlf
     A\nB
     A\rB
 \= Expect no match
-    A\r\nB    
+    A\r\nB
 
 /\R+b/B
 
@@ -3091,7 +3099,7 @@
 /.+/
 \= Bad offsets
     abc\=offset=4
-    abc\=offset=-4 
+    abc\=offset=-4
 \= Valid data
     abc\=offset=0
     abc\=offset=1
@@ -3111,24 +3119,24 @@
 
 /(?P<abn>(?P=axn)xxx)(?<axn>yy)/B
 
-# These tests are here because Perl gets the first one wrong. 
+# These tests are here because Perl gets the first one wrong.
 
 /(\R*)(.)/s
     \r\n
-    \r\r\n\n\r 
-    \r\r\n\n\r\n 
+    \r\r\n\n\r
+    \r\r\n\n\r\n
 
 /(\R)*(.)/s
     \r\n
-    \r\r\n\n\r 
-    \r\r\n\n\r\n 
+    \r\r\n\n\r
+    \r\r\n\n\r\n
 
 /((?>\r\n|\n|\x0b|\f|\r|\x85)*)(.)/s
     \r\n
-    \r\r\n\n\r 
-    \r\r\n\n\r\n 
+    \r\r\n\n\r
+    \r\r\n\n\r\n
 
-# ------------- 
+# -------------
 
 /^abc$/B
 
@@ -3136,12 +3144,12 @@
 
 /^(a)*+(\w)/
     aaaaX
-\= Expect no match 
+\= Expect no match
     aaaa
 
 /^(?:a)*+(\w)/
     aaaaX
-\= Expect no match 
+\= Expect no match
     aaaa
 
 /(a)++1234/IB
@@ -3200,39 +3208,39 @@
 
 /(abc)\1+/
 
-# Perl doesn't get these right IMO (the 3rd is PCRE2-specific) 
+# Perl doesn't get these right IMO (the 3rd is PCRE2-specific)
 
 /(?1)(?:(b(*ACCEPT))){0}/
     b
 
 /(?1)(?:(b(*ACCEPT))){0}c/
     bc
-\= Expect no match 
-    b 
+\= Expect no match
+    b
 
 /(?1)(?:((*ACCEPT))){0}c/
     c
     c\=notempty
 
 /^.*?(?(?=a)a|b(*THEN)c)/
-\= Expect no match 
+\= Expect no match
     ba
 
 /^.*?(?(?=a)a|bc)/
     ba
 
 /^.*?(?(?=a)a(*THEN)b|c)/
-\= Expect no match 
+\= Expect no match
     ac
 
 /^.*?(?(?=a)a(*THEN)b)c/
-\= Expect no match 
+\= Expect no match
     ac
 
 /^.*?(a(*THEN)b)c/
-\= Expect no match 
+\= Expect no match
     aabc
-    
+
 /^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x
     aabc
 
@@ -3247,11 +3255,11 @@
 
 /(*MARK:A)(*SKIP:B)(C|X)/mark
     C
-\= Expect no match 
+\= Expect no match
     D
-     
+
 /(*:A)A+(*SKIP:A)(B|Z)/mark
-\= Expect no match 
+\= Expect no match
     AAAC
 
 # ----------------------------
@@ -3259,14 +3267,14 @@
 "(?=a*(*ACCEPT)b)c"
     c
     c\=notempty
-    
+
 /(?1)c(?(DEFINE)((*ACCEPT)b))/
     c
     c\=notempty
-    
+
 /(?>(*ACCEPT)b)c/
     c
-\= Expect no match 
+\= Expect no match
     c\=notempty
 
 /(?:(?>(a)))+a%/allaftertext
@@ -3274,7 +3282,7 @@
 
 /(a)b|ac/allaftertext
     ac\=ovector=1
-    
+
 /(a)(b)x|abc/allaftertext
      abc\=ovector=2
 
@@ -3299,7 +3307,7 @@
     foobazbarX
     barfooX
     bazX
-    foobarbazX    
+    foobarbazX
     bazfooX\=ovector=0
     bazfooX\=ovector=1
     bazfooX\=ovector=2
@@ -3363,17 +3371,17 @@
 /^(?>a+)(?>(z+))\w/B
     aaaazzzzb
 \= Expect no match
-    aazz  
+    aazz
 
 /(.)(\1|a(?2))/
     bab
-    
+
 /\1|(.)(?R)\1/
     cbbbc
-    
+
 /(.)((?(1)c|a)|a(?2))/
 \= Expect no match
-    baa  
+    baa
 
 /(?P<abn>(?P=abn)xxx)/B
 
@@ -3414,7 +3422,7 @@
 
 /a[\NB]c/
     aNc
-    
+
 /a[B-\Nc]/
 
 /a[B\Nc]/
@@ -3426,34 +3434,34 @@
 # This test, with something more complicated than individual letters, causes
 # different behaviour in Perl. Perhaps it disables some optimization; no tag is
 # passed back for the failures, whereas in PCRE2 there is a tag.
-    
+
 /(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/x,mark
     AABC
-    XXYZ 
+    XXYZ
 \= Expect no match
-    XAQQ  
-    XAQQXZZ  
-    AXQQQ 
-    AXXQQQ 
+    XAQQ
+    XAQQXZZ
+    AXQQQ
+    AXXQQQ
 
 # Perl doesn't give marks for these, though it does if the alternatives are
-# replaced by single letters. 
-    
+# replaced by single letters.
+
 /(b|q)(*:m)f|a(*:n)w/mark
-    aw 
-\= Expect no match 
+    aw
+\= Expect no match
     abc
 
 /(q|b)(*:m)f|a(*:n)w/mark
-    aw 
-\= Expect no match 
+    aw
+\= Expect no match
     abc
 
-# After a partial match, the behaviour is as for a failure. 
+# After a partial match, the behaviour is as for a failure.
 
 /^a(*:X)bcde/mark
    abc\=ps
-   
+
 # These are here because Perl doesn't return a mark, except for the first.
 
 /(?=(*:x))(q|)/aftertext,mark
@@ -3521,22 +3529,22 @@
     ababa\=ps
     ababa\=ph
     abababx
-    ababababx  
+    ababababx
 
 /^(..)\1{2,3}?x/
     aba\=ps
     ababa\=ps
     ababa\=ph
     abababx
-    ababababx  
-    
+    ababababx
+
 /^(..)(\1{2,3})ab/
     abababab
 
 /^\R/
     \r\=ps
     \r\=ph
-    
+
 /^\R{2,3}x/
     \r\=ps
     \r\=ph
@@ -3545,7 +3553,7 @@
     \r\r\r\=ps
     \r\r\r\=ph
     \r\rx
-    \r\r\rx    
+    \r\r\rx
 
 /^\R{2,3}?x/
     \r\=ps
@@ -3555,20 +3563,20 @@
     \r\r\r\=ps
     \r\r\r\=ph
     \r\rx
-    \r\r\rx    
-    
+    \r\r\rx
+
 /^\R?x/
     \r\=ps
     \r\=ph
     x
-    \rx  
+    \rx
 
 /^\R+x/
     \r\=ps
     \r\=ph
     \r\n\=ps
     \r\n\=ph
-    \rx  
+    \rx
 
 /^a$/newline=crlf
     a\r\=ps
@@ -3589,7 +3597,7 @@
 /./newline=crlf
     \r\=ps
     \r\=ph
-  
+
 /.{2,3}/newline=crlf
     \r\=ps
     \r\=ph
@@ -3608,9 +3616,9 @@
 
 "AB(C(D))(E(F))?(?(?=\2)(?=\4))"
     ABCDGHI\=ovector=01
-    
+
 # These are all run as real matches in test 1; here we are just checking the
-# settings of the anchored and startline bits.  
+# settings of the anchored and startline bits.
 
 /(?>.*?a)(?<=ba)/I
 
@@ -3646,10 +3654,10 @@
 
 /(?:(a)+(?C1)bb|aa(?C2)b)/
     aab\=callout_capture
-   
+
 /(?:(a)++(?C1)bb|aa(?C2)b)/
     aab\=callout_capture
-    
+
 /(?:(?>(a))(?C1)bb|aa(?C2)b)/
     aab\=callout_capture
 
@@ -3666,11 +3674,11 @@
 /(ab)x|ab/
     ab\=ovector=0
     ab\=ovector=1
-  
+
 /(?<=123)(*MARK:xx)abc/mark
     xxxx123a\=ph
     xxxx123a\=ps
-    
+
 /123\Kabc/startchar
     xxxx123a\=ph
     xxxx123a\=ps
@@ -3685,22 +3693,22 @@
 
 /aaaaa(*COMMIT)(*PRUNE)b|a+c/
     aaaaaac
-    
+
 # Here are some that Perl treats differently because of the way it handles
-# backtracking verbs. 
+# backtracking verbs.
 
 /(?!a(*COMMIT)b)ac|ad/
      ac
-     ad 
+     ad
 
 /^(?!a(*THEN)b|ac)../
-     ad 
+     ad
 \= Expect no match
      ac
 
 /^(?=a(*THEN)b|ac)/
     ac
-    
+
 /\A.*?(?:a|b(*THEN)c)/
     ba
 
@@ -3711,25 +3719,24 @@
     ba
 
 /(?:(a(*MARK:X)a+(*SKIP:X)b)){0}(?:(?1)|aac)/
-    aac 
+    aac
 
 /\A.*?(a|b(*THEN)c)/
     ba
 
 /^(A(*THEN)B|A(*THEN)D)/
-    AD           
-    
+    AD
+
 /(?!b(*THEN)a)bn|bnn/
     bnn
 
 /(?(?=b(*SKIP)a)bn|bnn)/
-\= Expect no match
     bnn
 
 /(?=b(*THEN)a|)bn|bnn/
     bnn
 
-# This test causes a segfault with Perl 5.18.0 
+# This test causes a segfault with Perl 5.18.0
 
 /^(?=(a)){0}b(?1)/
     backgammon
@@ -3837,13 +3844,13 @@
 
 /[a-c]{0,6}d/IB
 
-# End of special auto-possessive tests 
+# End of special auto-possessive tests
 
 /^A\o{1239}B/
     A\123B
 
 /^A\oB/
-    
+
 /^A\x{zz}B/
 
 /^A\x{12Z/
@@ -3915,13 +3922,13 @@
 
 /[[:<:]]red[[:>:]]/B
     little red riding hood
-    a /red/ thing 
+    a /red/ thing
     red is a colour
-    put it all on red  
+    put it all on red
 \= Expect no match
     no reduction
     Alfred Winifred
-    
+
 /[a[:<:]] should give error/
 
 /(?=ab\K)/aftertext
@@ -3930,7 +3937,7 @@
 /abcd/newline=lf,firstline
 \= Expect no match
     xx\nxabcd
-    
+
 # Test stack guard external calls.
 
 /(((a)))/stackguard=1
@@ -3961,25 +3968,25 @@
 
 /A\9B/
 
-# This one is here because Perl fails to match "12" for this pattern when the $ 
+# This one is here because Perl fails to match "12" for this pattern when the $
 # is present.
-    
+
 /^(?(?=abc)\w{3}:|\d\d)$/
     abc:
     12
 \= Expect no match
     123
-    xyz    
+    xyz
 
-# Perl gets this one wrong, giving "a" as the after text for ca and failing to 
+# Perl gets this one wrong, giving "a" as the after text for ca and failing to
 # match for cd.
 
 /(?(?=ab)ab)/aftertext
     abxxx
     ca
-    cd 
-    
-# This should test both paths for processing OP_RECURSE. 
+    cd
+
+# This should test both paths for processing OP_RECURSE.
 
 /(?(R)a+|(?R)b)/
     aaaabcde
@@ -3991,29 +3998,29 @@
 /(*NOTEMPTY)a*?b*?/
     ab
     ba
-    cb  
+    cb
 
 /(*NOTEMPTY_ATSTART)a*?b*?/aftertext
     ab
-    cdab 
+    cdab
 
 /(?(VERSION>=10.0)yes|no)/I
     yesno
-    
+
 /(?(VERSION=8)yes){3}/BI,aftertext
     yesno
 
 /(?(VERSION=8)yes|no){3}/I
     yesnononoyes
 \= Expect no match
-    yesno   
+    yesno
 
 /(?:(?<VERSION>abc)|xyz)(?(VERSION)yes|no)/I
     abcyes
     xyzno
 \= Expect no match
     abcno
-    xyzyes    
+    xyzyes
 
 /(?(VERSION<10)yes|no)/
 
@@ -4029,11 +4036,11 @@
 
 /(|ab)*?d/I
    abd
-   xyd 
+   xyd
 
 /(|ab)*?d/I,no_start_optimize
    abd
-   xyd 
+   xyd
 
 /\k<A>*(?<A>aa)(?<A>bb)/match_unset_backref,dupnames
     aabb
@@ -4093,7 +4100,7 @@
 
 /abc/replace=[9]XYZ
     123abc123
-    
+
 /abc/replace=xyz
     1abc2\=partial_hard
 
@@ -4105,23 +4112,23 @@
 
 /(?<=abc)(|def)/g,replace=<$0>
     123abcxyzabcdef789abcpqr
-    
+
 /./replace=$0
     a
-    
+
 /(.)(.)/replace=$2+$1
     abc
-    
+
 /(?<A>.)(?<B>.)/replace=$B+$A
     abc
-    
+
 /(.)(.)/g,replace=$2$1
-    abcdefgh  
-    
+    abcdefgh
+
 /(*:pear)apple|(*:orange)lemon|(*:strawberry)blackberry/g,replace=${*MARK}
     apple lemon blackberry
     apple strudel
-    fruitless  
+    fruitless
 
 /(*:pear)apple|(*:orange)lemon|(*:strawberry)blackberry/replace=${*MARK} sauce,
     apple lemon blackberry
@@ -4129,15 +4136,15 @@
 /(*:pear)apple|(*:orange)lemon|(*:strawberry)blackberry/g,replace=<$*MARK>
     apple lemon blackberry
     apple strudel
-    fruitless  
-    
-/(*:pear)apple/g,replace=${*MARKING} 
+    fruitless
+
+/(*:pear)apple/g,replace=${*MARKING}
     apple lemon blackberry
 
 /(*:pear)apple/g,replace=${*MARK-time
     apple lemon blackberry
 
-/(*:pear)apple/g,replace=${*mark} 
+/(*:pear)apple/g,replace=${*mark}
     apple lemon blackberry
 
 /(*:pear)apple|(*:orange)lemon|(*:strawberry)blackberry/g,replace=<$*MARKET>
@@ -4173,10 +4180,10 @@
 
 /(a)(b)|(c)/
     XcX\=ovector=2,get=1,get=2,get=3,get=4,getall
-    
+
 /x(?=ab\K)/
-    xab\=get=0 
-    xab\=copy=0 
+    xab\=get=0
+    xab\=copy=0
     xab\=getall
 
 /(?<A>a)|(?<A>b)/dupnames
@@ -4239,16 +4246,16 @@
      00765
      456
 \= Expect no match
-     356   
+     356
 
 '^(a)*+(\w)'
     g
-    g\=ovector=1 
+    g\=ovector=1
 
 '^(?:a)*+(\w)'
     g
-    g\=ovector=1 
-    
+    g\=ovector=1
+
 # These two pattern showeds up compile-time bugs
 
 "((?2){0,1999}())?"
@@ -4289,11 +4296,11 @@
 
 /^(?(?C25)(?=abc)abcd|xyz)/B,callout_info
     abcdefg
-    xyz123 
+    xyz123
 
 /^(?(?C$abc$)(?=abc)abcd|xyz)/B
     abcdefg
-    xyz123 
+    xyz123
 
 /^ab(?C'first')cd(?C"second")ef/
     abcdefg
@@ -4310,8 +4317,8 @@
 
 /(?(?!)a|b)/
     bbb
-\= Expect no match 
-    aaa 
+\= Expect no match
+    aaa
 
 # JIT gives a different error message for the infinite recursion
 
@@ -4345,9 +4352,9 @@
 /abc/
 \= Expect no match
     \[9x!xxx(]{9999}
-    
+
 /(abc)*/
-    \[abc]{5} 
+    \[abc]{5}
 
 /^/gm
     \n\n\n
@@ -4365,17 +4372,17 @@
 
 /A\8B\9C/
     A8B9C
-    
+
 /(?x:((?'a')) # comment (with parentheses) and | vertical
 (?-x:#not a comment (?'b')) # this is a comment ()
 (?'c')) # not a comment (?'d')/info
 
 /(?|(?'a')(2)(?'b')|(?'a')(?'a')(3))/I,dupnames
     A23B
-    B32A 
+    B32A
 
 # These are some patterns that used to cause buffer overflows or other errors
-# while compiling. 
+# while compiling.
 
 /.((?2)(?R)|\1|$)()/B
 
@@ -4459,7 +4466,7 @@
     {4,5a}bc
 
 /\x0{ab}/
-    \0{ab} 
+    \0{ab}
 
 /^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/
     ababababbbabZXXXX
@@ -4501,8 +4508,8 @@
 \= Expect no match
     aacb
 
-/(*MARK:a\zb)z/alt_verbnames 
-    
+/(*MARK:a\zb)z/alt_verbnames
+
 /(*:ab\t(d\)c)xxx/
 
 /(*:ab\t(d\)c)xxx/alt_verbnames,mark
@@ -4510,16 +4517,28 @@
 
 /(*:A\Qxx)x\EB)x/alt_verbnames,mark
     x
-    
+
 /(*:A\ExxxB)x/alt_verbnames,mark
-    x 
-    
+    x
+
 /(*: A \ and #comment
      \ B)x/x,alt_verbnames,mark
-    x  
-    
+    x
+
+/(*: A \ and #comment
+     \ B)x/alt_verbnames,mark
+    x
+
+/(*: A \ and #comment
+     \ B)x/x,mark
+    x
+
+/(*: A \ and #comment
+     \ B)x/mark
+    x
+
 /(*:A
-B)x/alt_verbnames,mark 
+B)x/alt_verbnames,mark
     x
 
 /(*:abc\Qpqr)/alt_verbnames
@@ -4537,7 +4556,7 @@
     1234abc\=offset_limit=7
 \= Expect no match
     1234abc\=offset_limit=6
-    
+
 /A/g,replace=-,use_offset_limit
     XAXAXAXAXA\=offset_limit=4
 
@@ -4551,16 +4570,16 @@
 
 /abcd/null_context
     abcd\=null_context
-\= Expect error     
+\= Expect error
     abcd\=null_context,find_limits
-    abcd\=allusedtext,startchar 
+    abcd\=allusedtext,startchar
 
 /abcd/replace=w\rx\x82y\o{333}z(\Q12\$34$$\x34\E5$$),substitute_extended
     abcd
-    
+
 /a(bc)(DE)/replace=a\u$1\U$1\E$1\l$2\L$2\Eab\Uab\LYZ\EDone,substitute_extended
     abcDE
- 
+
 /abcd/replace=xy\kz,substitute_extended
     abcd
 
@@ -4598,8 +4617,8 @@
 
 /(?J)(?:(?<A>a)|(?<A>b))/replace=<$A>
     [a]
-    [b] 
-\= Expect error     
+    [b]
+\= Expect error
     (a)\=ovector=1
 
 /(a)|(b)/replace=<$1>
@@ -4624,10 +4643,10 @@
 
 /(?=a\K)/replace=z
     BaCaD
-    
+
 /(?'abcdefghijklmnopqrstuvwxyzABCDEFG'toolong)/
- 
-/(?'abcdefghijklmnopqrstuvwxyzABCDEF'justright)/ 
+
+/(?'abcdefghijklmnopqrstuvwxyzABCDEF'justright)/
 
 # These two use zero-termination
 /abcd/max_pattern_length=3
@@ -4639,7 +4658,7 @@
 
 /abcdef/hex,max_pattern_length=3
 
-# These two patterns used to take a long time to compile
+# These patterns used to take a long time to compile
 
 "(.*)
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
@@ -4652,9 +4671,6 @@
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
 a)"xI
 
-# When (?| is used and groups of the same number may be different,
-# we have to rely on a count to catch overly complicated patterns.
-
 "(?|()|())(.*)
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
@@ -4753,7 +4769,7 @@
 
 /a|(b)c/replace=>$1<,substitute_unset_empty
     cat
-    xbcom 
+    xbcom
 
 /a|(b)c/
     cat\=replace=>$1<
@@ -4767,26 +4783,26 @@
 
 /a|(?'X'b)c/replace=>$X<,substitute_unset_empty
     cat
-    xbcom 
+    xbcom
 
 /a|(?'X'b)c/replace=>$Y<,substitute_unset_empty
     cat
-    cat\=substitute_unknown_unset 
-    cat\=substitute_unknown_unset,-substitute_unset_empty 
+    cat\=substitute_unknown_unset
+    cat\=substitute_unknown_unset,-substitute_unset_empty
 
 /a|(b)c/replace=>$2<,substitute_unset_empty
     cat
-    cat\=substitute_unknown_unset 
-    cat\=substitute_unknown_unset,-substitute_unset_empty 
+    cat\=substitute_unknown_unset
+    cat\=substitute_unknown_unset,-substitute_unset_empty
 
 /()()()/use_offset_limit
     \=ovector=11000000000
     \=callout_fail=11000000000
     \=callout_fail=1:11000000000
-    \=callout_data=11000000000 
-    \=callout_data=-11000000000 
-    \=offset_limit=1100000000000000000000 
-    \=copy=11000000000 
+    \=callout_data=11000000000
+    \=callout_data=-11000000000
+    \=offset_limit=1100000000000000000000
+    \=copy=11000000000
 
 /(*MARK:A\x00b)/mark
     abc
@@ -4819,4 +4835,598 @@
 
 /\[AB]{6000000000000000000000}/expand
 
-# End of testinput2 
+# Hex uses pattern length, not zero-terminated. This tests for overrunning
+# the given length of a pattern.
+
+/'(*U'/hex
+
+/'(*'/hex
+
+/'('/hex
+
+//hex
+
+# These tests are here because Perl never allows a back reference in a
+# lookbehind. PCRE2 supports some limited cases.
+
+/([ab])...(?<=\1)z/
+    a11az
+    b11bz
+\= Expect no match
+    b11az
+
+/(?|([ab]))...(?<=\1)z/
+
+/([ab])(\1)...(?<=\2)z/
+    aa11az
+
+/(a\2)(b\1)(?<=\2)/
+
+/(?<A>[ab])...(?<=\k'A')z/
+    a11az
+    b11bz
+\= Expect no match
+    b11az
+
+/(?<A>[ab])...(?<=\k'A')(?<A>)z/dupnames
+
+# Perl does not support \g+n
+
+/((\g+1X)?([ab]))+/
+    aaXbbXa
+
+/ab(?C1)c/auto_callout
+    abc
+
+/'ab(?C1)c'/hex,auto_callout
+    abc
+
+# Perl accepts these, but gives a warning. We can't warn, so give an error.
+
+/[a-[:digit:]]+/
+    a-a9-a
+
+/[A-[:digit:]]+/
+    A-A9-A
+
+/[a-\d]+/
+    a-a9-a
+
+/(?<RA>abc)(?(R)xyz)/B
+
+/(?<R>abc)(?(R)xyz)/B
+
+/(?=.*[A-Z])/I
+
+/()(?<=(?0))/
+
+/(?<!|!(?<!))/
+
+/(?<!|!|!||||||(?<!)||(?<!)!|!||(?<!)!|!(?<!)!|!|!|!||||!!|<!)!|!||||!|/
+
+/{2,2{2,2/use_length
+
+/.>*?\g'0/use_length
+
+/.>*?\g'0/
+
+/{„Í„Í̈́Í{'{22{2{{2{'{22{{22{2{'{22{2{{2{{222{{2{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{222{2Ą̈́Í̈́Í{'{22{2{{2{'{22{{11{2{'{22{2{{2{{'{22{2{{2{'{22{{22{1{'{22{2{{2{{222{{2{'{22{2{22{2{'{/auto_callout
+
+//
+\=get=i00000000000000000000000000000000
+\=get=i2345678901234567890123456789012,get=i1245678901234567890123456789012
+
+"(?(?C))"
+
+/(?(?(?(?(?(?))))))/
+
+/(?<=(?1))((?s))/anchored
+
+/(*:ab)*/
+
+%(*:(:(svvvvvvvvvv:]*[   Z!*;[]*[^[]*!^[+.+{{2,7}'      _\\\\\\\\\\\\\)?.:..    *w////\\\Q\\\\\\\\\\\\\\\T\\\\\+/?/////'+\\\EEE?/////'+/*+/[^K]?]//(w)%never_backslash_c,alt_verbnames,auto_callout
+
+/./newline=crlf
+    \=ph
+
+/(\x0e00\000000\xc)/replace=\P,substitute_extended
+    \x0e00\000000\xc
+
+//replace=0
+    \=offset=7
+
+".+\QX\E+"B,no_auto_possess
+
+".+\QX\E+"B,auto_callout,no_auto_possess
+
+# This one is here because Perl gives an 'unmatched )' error which goes away
+# if one of the \) sequences is removed - which is weird. PCRE finds it too
+# complicated to find a minimum matching length.
+
+"()X|((((((((()))))))((((())))))\2())((((((\2\2)))\2)(\22((((\2\2)2))\2)))(2\ZZZ)+:)Z^|91ZiZZnter(ZZ |91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z+:)Z|91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z((Z*(\2(Z\':))\0)i|||||||||||||||loZ\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \)\0nte!rnal errpr\2\\21r(2\ZZZ)+:)Z!|91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \)\0(2\ZZZ)+:)Z^|91ZiZZnter(ZZ |91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \)\0(2\ZZZ)+:)Z^)))int \)\0(2\ZZZ)+:)Z^|91ZiZZnter(ZZernZal ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \))\ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)))\2))))((((((\2\2))))))"I
+
+# This checks that new code for handling groups that may match an empty string
+# works on a very large number of alternatives. This pattern used to provoke a
+# complaint that it was too complicated.
+
+/(?:\[A|B|C|D|E|F|G|H|I|J|]{200}Z)/expand
+
+# This one used to compile rubbish instead of a compile error, and then
+# behave unpredictably at match time.
+
+/.+(?(?C'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'))?!XXXX.=X/
+    .+(?(?C'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'))?!XXXX.=X
+
+/[:[:alnum:]-[[a:lnum:]+/
+
+/((?(?C'')\QX\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
+
+/((?(?C'')\Q\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
+
+/abcd/auto_callout
+    abcd\=callout_error=255:2
+
+/()(\g+65534)/
+
+/()(\g+65533)/
+
+/Á\x00\x00\x00š(\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\x00k\d+\x00‎\x00\x00\x00\x00\x00\2*\x00\x00\1*.){36}int^\x00\x00ÿÿ\x00š(\1{50779}?)J\w2/I
+
+/(a)(b)\2\1\1\1\1/I
+
+/(?<a>a)(?<b>b)\g{b}\g{a}\g{a}\g{a}\g{a}(?<a>xx)(?<b>zz)/I,dupnames
+
+//
+    \=ovector=7777777777
+
+# This is here because Perl matches, even though a COMMIT is encountered
+# outside of the recursion.
+
+/(?1)(A(*COMMIT)|B)D/
+    BAXBAD
+
+"(?1){2}(a)"B
+
+"(?1){2,4}(a)"B
+
+# This test differs from Perl for the first subject. Perl ends up with
+# $1 set to 'B'; PCRE2 has it unset (which I think is right).
+
+/^(?:
+(?:A| (?:B|B(*ACCEPT)) (?<=(.)) D)
+(Z)
+)+$/x
+    AZB
+    AZBDZ
+
+# The first of these, when run by Perl, gives the mark 'aa', which is wrong.
+
+'(?>a(*:aa))b|ac' mark
+    ac
+
+'(?:a(*:aa))b|ac' mark
+    ac
+
+/(R?){65}/
+    (R?){65}
+
+/\[(a)]{60}/expand
+    aaaa
+
+/(?<!\1((?U)1((?U))))(*F)/never_backslash_c,alt_bsux,anchored,extended
+
+/\g{3/
+
+/(a(?C1)(b)(c)d)+/
+  abcdabcd\=callout_capture
+
+# Perl matches this one, but PCRE does not because (*ACCEPT) clears out any
+# pending backtracks in the recursion.
+
+/^ (?(DEFINE) (..(*ACCEPT)|...) ) (?1)$/x
+\= Expect no match
+    abc
+
+# Perl gives no match for this one
+
+/(a(*MARK:m)(*ACCEPT)){0}(?1)/mark
+    abc
+
+/abc/endanchored
+    xyzabc
+\= Expect no match
+    xyzabcdef
+\= Expect error
+    xyzabc\=ph
+
+/abc/
+    xyzabc\=endanchored
+\= Expect no match
+    xyzabcdef\=endanchored
+\= Expect error
+    xyzabc\=ps,endanchored
+
+/abc(*ACCEPT)d/endanchored
+    xyzabc
+\= Expect no match
+    xyzabcdef
+
+/abc|bcd/endanchored
+    xyzabcd
+\= Expect no match
+    xyzabcdef
+
+/a(*ACCEPT)x|aa/endanchored
+    aaa
+
+# Check auto-anchoring when there is a group that is never obeyed at
+# the start of a branch.
+
+/(?(DEFINE)(a))^bc/I
+
+/(a){0}.*bc/sI
+
+# This should be anchored, as the condition is always false and there is
+# no alternative branch.
+
+/(?(VERSION>=999)yes)^bc/I
+
+# This should not be anchored.
+
+/(?(VERSION>=999)yes|no)^bc/I
+
+/(*LIMIT_HEAP=0)xxx/I
+
+/\d{0,3}(*:abc)(?C1)xxx/callout_info
+
+# ----------------------------------------------------------------------
+
+# These are a whole pile of tests that touch lines of code that are not
+# used by any other tests (at least when these were created).
+
+/^a+?x/i,no_start_optimize,no_auto_possess
+\= Expect no match
+    aaa
+
+/^[^a]{3,}?x/i,no_start_optimize,no_auto_possess
+\= Expect no match
+    bbb
+    cc
+
+/^X\S/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\W/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\H/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\h/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\V/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\v/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\h/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY
+
+/^X\V/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\n
+
+/^X\v/no_start_optimize,no_auto_possess
+\= Expect no match
+    XX
+
+/^X.+?/s,no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\R+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    XX
+
+/^X\H+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\h+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+
+/^X\V+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+    X\n
+
+/^X\D+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+    X9
+
+/^X\S+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+    X\n
+
+/^X\W+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+    XX
+
+/^X.+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+
+/(*CRLF)^X.+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\r\=ps
+
+/^X\R+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\nX
+    X\n\r\n
+    X\n\rY
+    X\n\nY
+    X\n\x{0c}Y
+
+/(*BSR_ANYCRLF)^X\R+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\nX
+    X\n\r\n
+    X\n\rY
+    X\n\nY
+    X\n\x{0c}Y
+
+/^X\H+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\t
+    XYY
+
+/^X\h+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\t\t
+    X\tY
+
+/^X\V+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+    XYY
+
+/^X\v+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\n\n
+    X\nY
+
+/^X\D+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY9
+    XYY
+
+/^X\d+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X99
+    X9Y
+
+/^X\S+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+    XYY
+
+/^X\s+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\n\n
+    X\nY
+
+/^X\W+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X.A
+    X++
+
+/^X\w+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    Xa.
+    Xaa
+
+/^X.{1,3}Z/s,no_start_optimize,no_auto_possess
+\= Expect no match
+    Xa.bd
+
+/^X\h+Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\t\t
+    X\tY
+
+/^X\V+Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+    XYY
+
+/^(X(*THEN)Y|AB){0}(?1)/
+    ABX
+\= Expect no match
+    XAB
+
+/^(?!A(?C1)B)C/
+    ABC\=callout_error=1,no_jit
+
+/^(?!A(?C1)B)C/no_start_optimize
+    ABC\=callout_error=1
+
+/^(?(?!A(?C1)B)C)/
+    ABC\=callout_error=1
+
+# ----------------------------------------------------------------------
+
+/[a b c]/BxxI
+
+/[a b c]/BxxxI
+
+/[a b c]/B,extended_more
+
+/[ a b c ]/B,extended_more
+
+/[a b](?xx: [ 12 ] (?-xx:[ 34 ]) )y z/B
+
+# Unsetting /x also unsets /xx
+
+/[a b](?xx: [ 12 ] (?-x:[ 34 ]) )y z/B
+
+/(a)(?-n:(b))(c)/nB
+
+# ----------------------------------------------------------------------
+# These test the dangerous PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL option.
+
+/\j\x{z}\o{82}\L\uabcd\u\U\g{\g/B,\bad_escape_is_literal
+
+/\N{\c/IB,bad_escape_is_literal
+
+/[\j\x{z}\o\gA-\Nb-\g]/B,bad_escape_is_literal
+
+/[Q-\N]/B,bad_escape_is_literal
+
+# ----------------------------------------------------------------------
+
+/a\b(c/literal
+    a\\b(c
+
+/a\b(c/literal,caseless
+    a\\b(c
+    a\\B(c
+
+/a\b(c/literal,firstline
+    XYYa\\b(c
+\= Expect no match
+    X\na\\b(c
+
+/a\b?c/literal,use_offset_limit
+    XXXXa\\b?c\=offset_limit=4
+\= Expect no match
+    XXXXa\\b?c\=offset_limit=3
+
+/a\b(c/literal,anchored,endanchored
+    a\\b(c
+\= Expect no match
+    Xa\\b(c
+    a\\b(cX
+    Xa\\b(cX
+
+//literal,extended
+
+/a\b(c/literal,auto_callout,no_start_optimize
+    XXXXa\\b(c
+
+/a\b(c/literal,auto_callout
+    XXXXa\\b(c
+
+/(*CR)abc/literal
+    (*CR)abc
+
+/cat|dog/I,match_word
+    the cat sat
+\= Expect no match
+    caterpillar
+    snowcat
+    syndicate
+
+/(cat)|dog/I,match_line,literal
+    (cat)|dog
+\= Expect no match
+    the cat sat
+    caterpillar
+    snowcat
+    syndicate
+
+/a whole line/match_line,multiline
+    Rhubarb \na whole line\n custard
+\= Expect no match
+    Not a whole line
+
+# Perl gets this wrong, failing to capture 'b' in group 1.
+
+/^(b+|a){1,2}?bc/
+    bbc
+    
+# And again here, for the "babc" subject string. 
+
+/^(b*|ba){1,2}?bc/
+    babc
+    bbabc
+    bababc
+\= Expect no match
+    bababbc
+    babababc
+
+/[[:digit:]-a]/
+
+/[[:digit:]-[:print:]]/
+
+/[\d-a]/
+
+/[\H-z]/
+
+/[\d-[:print:]]/
+
+# Perl gets the second of these wrong, giving no match.
+
+"(?<=(a))\1?b"I
+    ab
+    aaab 
+
+"(?=(a))\1?b"I
+    ab
+    aaab
+    
+# JIT does not support callout_extra  
+    
+/(*NO_JIT)(a+)b/auto_callout,no_start_optimize,no_auto_possess
+\= Expect no match
+    aac\=callout_extra 
+    
+/(*NO_JIT)a+(?C'XXX')b/no_start_optimize,no_auto_possess
+\= Expect no match
+    aac\=callout_extra 
+
+/\n/firstline
+    xyz\nabc
+
+/\nabc/firstline
+    xyz\nabc
+
+/\x{0a}abc/firstline,newline=crlf
+\= Expect no match
+    xyz\r\nabc
+
+/[abc]/firstline
+\= Expect no match
+    \na
+    
+# These tests are matched in test 1 as they are Perl compatible. Here we are
+# looking at what does and does not get auto-possessified. 
+
+/(?(DEFINE)(?<optional_a>a?))^(?&optional_a)a$/B
+
+/(?(DEFINE)(?<optional_a>a?)X)^(?&optional_a)a$/B
+    
+/^(a?)b(?1)a/B
+
+/^(a?)+b(?1)a/B
+
+/^(a?)++b(?1)a/B
+
+/^(a?)+b/B
+
+/(?=a+)a(a+)++b/B
+
+# End of testinput2
diff --git a/dist2/testdata/testinput20 b/dist2/testdata/testinput20
index c920e2a..71f39ae 100644
--- a/dist2/testdata/testinput20
+++ b/dist2/testdata/testinput20
@@ -31,20 +31,20 @@
 #load testsaved2
 
 #pop info
-    foofoo             
+    foofoo
     barbar
-    
+
 #pop mark
     C
-\= Expect no match     
-    D 
-    
+\= Expect no match
+    D
+
 #pop
-    AmanaplanacanalPanama   
+    AmanaplanacanalPanama
 
 #pop info
     metcalfe 33
-    
+
 # Check for an error when different tables are used.
 
 /abc/push,tables=1
@@ -59,33 +59,50 @@
 
 #pop should give an error
     pqr
-    
+
 /abcd/pushcopy
     abcd
-    
+
 #pop
-    abcd 
+    abcd
 
 #pop should give an error
 
 /abcd/push
 #popcopy
     abcd
-    
+
 #pop
-    abcd 
-    
+    abcd
+
 /abcd/push
 #save testsaved1
 #pop should give an error
 
 #load testsaved1
-#popcopy 
+#popcopy
     abcd
-    
+
 #pop
     abcd
 
 #pop should give an error
 
+/abcd/pushtablescopy
+    abcd
+
+#popcopy
+    abcd
+
+#pop
+    abcd
+
+# Must only specify one of these
+
+//push,pushcopy
+
+//push,pushtablescopy
+
+//pushcopy,pushtablescopy
+
 # End of testinput20
diff --git a/dist2/testdata/testinput22 b/dist2/testdata/testinput22
index 7ada9aa..e6d4053 100644
--- a/dist2/testdata/testinput22
+++ b/dist2/testdata/testinput22
Binary files differ
diff --git a/dist2/testdata/testinput24 b/dist2/testdata/testinput24
new file mode 100644
index 0000000..380e23c
--- /dev/null
+++ b/dist2/testdata/testinput24
@@ -0,0 +1,396 @@
+# This file tests the auxiliary pattern conversion features of the PCRE2
+# library, in non-UTF mode.
+
+#forbid_utf
+#newline_default lf any anycrlf
+
+# -------- Tests of glob conversion --------
+
+# Set the glob separator explicitly so that different OS defaults are not a
+# problem. Then test various errors.
+
+#pattern convert=glob,convert_glob_escape=\,convert_glob_separator=/
+
+/abc/posix
+
+# Separator must be / \ or .
+
+/a*b/convert_glob_separator=%
+
+# Can't have separator in a class
+
+"[ab/cd]"
+
+"[,-/]"
+
+/[ab/
+
+# Length check
+
+/abc/convert_length=11
+
+/abc/convert_length=12
+
+# Now some actual tests
+
+/a?b[]xy]*c/
+    azb]1234c
+
+# Tests from the gitwildmatch list, with some additions
+
+/foo/
+    foo
+/= Expect no match
+    bar
+
+//
+    \
+
+/???/
+    foo
+\= Expect no match
+    foobar
+
+/*/
+    foo
+    \
+
+/f*/
+    foo
+    f
+
+/*f/
+    oof
+\= Expect no match
+    foo
+
+/*foo*/
+    foo
+    food
+    aprilfool
+
+/*ob*a*r*/
+    foobar
+
+/*ab/
+    aaaaaaabababab
+
+/foo\*/
+    foo*
+
+/foo\*bar/
+\= Expect no match
+    foobar
+
+/f\\oo/
+    f\\oo
+
+/*[al]?/
+    ball
+
+/[ten]/
+\= Expect no match
+    ten
+
+/t[a-g]n/
+    ten
+
+/a[]]b/
+    a]b
+
+/a[]a-]b/
+
+/a[]-]b/
+    a-b
+    a]b
+\= Expect no match
+    aab
+
+/a[]a-z]b/
+    aab
+
+/]/
+    ]
+
+/t[!a-g]n/
+    ton
+\= Expect no match
+    ten
+
+'[[:alpha:]][[:digit:]][[:upper:]]'
+    a1B
+
+'[[:digit:][:upper:][:space:]]'
+    A
+    1
+    \ \=
+\= Expect no match
+    a
+    .
+
+'[a-c[:digit:]x-z]'
+    5
+    b
+    y
+\= Expect no match
+    q
+
+# End of gitwildmatch tests
+
+/*.j?g/
+    pic01.jpg
+    .jpg
+    pic02.jxg
+\= Expect no match
+    pic03.j/g
+
+/A[+-0]B/
+    A+B
+    A.B
+    A0B
+\= Expect no match
+    A/B
+
+/*x?z/
+    abc.xyz
+\= Expect no match
+    .xyz
+
+/?x?z/
+    axyz
+\= Expect no match
+    .xyz
+
+"[,-0]x?z"
+    ,xyz
+\= Expect no match
+    /xyz
+    .xyz
+
+".x*"
+    .xabc
+
+/a[--0]z/
+    a-z
+    a.z
+    a0z
+\= Expect no match
+    a/z
+    a1z
+
+/<[a-c-d]>/
+    <a>
+    <b>
+    <c>
+    <d>
+    <->
+
+/a[[:digit:].]z/
+    a1z
+    a.z
+\= Expect no match
+    a:z
+
+/a[[:digit].]z/
+    a[.]z
+    a:.]z
+    ad.]z
+
+/<[[:a[:digit:]b]>/
+    <[>
+    <:>
+    <a>
+    <9>
+    <b>
+\= Expect no match
+    <d>
+
+/a*b/convert_glob_separator=\
+
+/a*b/convert_glob_separator=.
+
+/a*b/convert_glob_separator=/
+
+# Non control character checking
+
+/A\B\\C\D/
+
+/\\{}\?\*+\[\]()|.^$/
+
+/*a*\/*b*/
+
+/?a?\/?b?/
+
+/[a\\b\c][]][-][\]\-]/
+
+/[^a\\b\c][!]][!-][^\]\-]/
+
+/[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:word:][:xdigit:]]/
+
+"[/-/]"
+
+/[-----]/
+
+/[------]/
+
+/[!------]/
+
+/[[:alpha:]-a]/
+
+/[[:alpha:]][[:punct:]][[:ascii:]]/
+
+/[a-[:alpha:]]/
+
+/[[:alpha:/
+
+/[[:alpha:]/
+
+/[[:alphaa:]]/
+
+/[[:xdigi:]]/
+
+/[[:xdigit::]]/
+
+/****/
+
+/**\/abc/
+  abc
+  x/abc
+  xabc
+
+/abc\/**/
+
+/abc\/**\/abc/
+
+/**\/*a*b*g*n*t/
+  abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt
+
+/**\/*a*\/**/
+  xx/xx/xx/xax/xx/xb
+
+/**\/*a*/
+  xx/xx/xx/xax
+  xx/xx/xx/xax/xx
+
+/**\/*a*\/**\/*b*/
+  xx/xx/xx/xax/xx/xb
+  xx/xx/xx/xax/xx/x
+
+"**a"convert=glob
+  a
+  c/b/a
+  c/b/aaa
+
+"a**/b"convert=glob
+  a/b
+  ab
+
+"a/**b"convert=glob
+  a/b
+  ab
+
+#pattern convert=glob:glob_no_starstar
+
+/***/
+
+/**a**/
+
+#pattern convert=unset
+#pattern convert=glob:glob_no_wild_separator
+
+/*/
+
+/*a*/
+
+/**a**/
+
+/a*b/
+
+/*a*b*/
+
+/??a??/
+
+#pattern convert=unset
+#pattern convert=glob,convert_glob_escape=0
+
+/a\b\cd/
+
+/**\/a/
+
+/a`*b/convert_glob_escape=`
+
+/a`*b/convert_glob_escape=0
+
+/a`*b/convert_glob_escape=x
+
+# -------- Tests of extended POSIX conversion --------
+
+#pattern convert=unset:posix_extended
+
+/<[[:a[:digit:]b]>/
+    <[>
+    <:>
+    <a>
+    <9>
+    <b>
+\= Expect no match
+    <d>
+
+/a+\1b\\c|d[ab\c]/
+
+/<[]bc]>/
+    <]>
+    <b>
+    <c>
+
+/<[^]bc]>/
+    <.>
+\= Expect no match
+    <]>
+    <b>
+
+/(a)\1b/
+    a1b
+\= Expect no match
+    aab
+
+/(ab)c)d]/
+    Xabc)d]Y
+
+/a***b/
+
+# -------- Tests of basic POSIX conversion --------
+
+#pattern convert=unset:posix_basic
+
+/a*b+c\+[def](ab)\(cd\)/
+
+/\(a\)\1b/
+    aab
+\= Expect no match
+    a1b
+
+/how.to how\.to/
+    how\nto how.to
+\= Expect no match     
+    how\x{0}to how.to
+
+/^how to \^how to/
+
+/^*abc/
+
+/*abc/
+    X*abcY
+
+/**abc/
+    XabcY
+    X*abcY
+    X**abcY
+    
+/*ab\(*cd\)/ 
+
+/^b\(c^d\)\(^e^f\)/
+
+/a***b/
+
+# End of testinput24
diff --git a/dist2/testdata/testinput25 b/dist2/testdata/testinput25
new file mode 100644
index 0000000..f21d9ad
--- /dev/null
+++ b/dist2/testdata/testinput25
@@ -0,0 +1,18 @@
+# This file tests the auxiliary pattern conversion features of the PCRE2 
+# library, in UTF mode.
+
+#newline_default lf any anycrlf
+
+# -------- Tests of glob conversion --------
+
+# Set the glob separator explicitly so that different OS defaults are not a
+# problem. Then test various errors.
+
+#pattern convert=glob,convert_glob_escape=\,convert_glob_separator=/
+
+# The fact that this one works in 13 bytes in the 8-bit library shows that the
+# output is in UTF-8, though pcre2test shows the character as an escape.
+
+/'>' c4 a3 '<'/hex,utf,convert_length=13
+
+# End of testinput25
diff --git a/dist2/testdata/testinput4 b/dist2/testdata/testinput4
index ce9145d..0ef7b8e 100644
--- a/dist2/testdata/testinput4
+++ b/dist2/testdata/testinput4
@@ -567,7 +567,7 @@
 /[[:^xdigit:]]/g,utf
     M\x{442}
 
-/[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽƁƂƄƆƇƉƊƋƎƏƐƑƓƔƖƗƘƜƝƟƠƢƤƦƧƩƬƮƯƱƲƳƵƷƸƼDŽLJNJǍǏǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎȐȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾɁΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎҐҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀӁӃӅӇӉӋӍӐӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌἍἎἏἘἙἚἛἜἝἨἩἪἫἬἭἮἯἸἹἺἻἼἽἾἿὈὉὊὋὌὍὙὛὝὟὨὩὪὫὬὭὮὯᾸᾹᾺΆῈΈῊΉῘῙῚΊῨῩῪΎῬῸΌῺΏabcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżžſƀƃƅƈƌƍƒƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎǐǒǔǖǘǚǜǝǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿȁȃȅȇȉȋȍȏȑȓȕȗșțȝȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϐϑϕϖϗϙϛϝϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿҁҋҍҏґғҕҗҙқҝҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛӝӟӡӣӥӧөӫӭӯӱӳӵӷӹԁԃԅԇԉԋԍԏաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹἀἁἂἃἄἅἆἇἐἑἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀὁὂὃὄὅὐὑὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇῐῑῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣⳤⴀⴁⴂⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌⴍⴎⴏⴐⴑⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜⴝⴞⴟⴠⴡⴢⴣⴤⴥfffiflffifflſtstﬓﬔﬕﬖﬗ\d-_^]/utf
+/[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽƁƂƄƆƇƉƊƋƎƏƐƑƓƔƖƗƘƜƝƟƠƢƤƦƧƩƬƮƯƱƲƳƵƷƸƼDŽLJNJǍǏǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎȐȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾɁΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎҐҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀӁӃӅӇӉӋӍӐӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌἍἎἏἘἙἚἛἜἝἨἩἪἫἬἭἮἯἸἹἺἻἼἽἾἿὈὉὊὋὌὍὙὛὝὟὨὩὪὫὬὭὮὯᾸᾹᾺΆῈΈῊΉῘῙῚΊῨῩῪΎῬῸΌῺΏabcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżžſƀƃƅƈƌƍƒƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎǐǒǔǖǘǚǜǝǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿȁȃȅȇȉȋȍȏȑȓȕȗșțȝȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϐϑϕϖϗϙϛϝϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿҁҋҍҏґғҕҗҙқҝҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛӝӟӡӣӥӧөӫӭӯӱӳӵӷӹԁԃԅԇԉԋԍԏաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹἀἁἂἃἄἅἆἇἐἑἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀὁὂὃὄὅὐὑὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇῐῑῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣⳤⴀⴁⴂⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌⴍⴎⴏⴐⴑⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜⴝⴞⴟⴠⴡⴢⴣⴤⴥfffiflffifflſtstﬓﬔﬕﬖﬗ\d_^]/utf
 
 /^[^d]*?$/
     abc
@@ -1627,6 +1627,11 @@
 /[z\x{1f88}]+/i,utf
     \x{1f88}\x{1f80} 
     
+# Check a reference with more than one other case
+
+/^(\x{00b5})\1{2}$/i,utf        
+    \x{00b5}\x{039c}\x{03bc} 
+    
 # Characters with more than one other case; test in classes 
 
 /[z\x{00b5}]+/i,utf
@@ -2282,4 +2287,18 @@
     \x{389}
     \x{20ac}
 
+/(?=.*b)\pL/
+    11bb
+    
+/(?(?=.*b)(?=.*b)\pL|.*c)/
+    11bb
+
+/^\x{123}+?$/utf,no_auto_possess
+    \x{123}\x{123}\x{123}
+
+/^\x{123}+?$/i,utf,no_auto_possess
+    \x{123}\x{122}\x{123}
+\= Expect no match     
+    \x{123}\x{124}\x{123}
+
 # End of testinput4
diff --git a/dist2/testdata/testinput5 b/dist2/testdata/testinput5
index 2e13a7c..0366136 100644
--- a/dist2/testdata/testinput5
+++ b/dist2/testdata/testinput5
Binary files differ
diff --git a/dist2/testdata/testinput6 b/dist2/testdata/testinput6
index de9227e..e2f00c0 100644
--- a/dist2/testdata/testinput6
+++ b/dist2/testdata/testinput6
@@ -1861,11 +1861,6 @@
 \= Expect no match
     aaa
 
-/[\d-z]+/
-    12-34z
-\= Expect no match
-    aaa
-
 /\x5c/
     \\
 
@@ -3813,13 +3808,6 @@
 /a*/g
     abbab
 
-/^[\d-a]/
-    abcde
-    -things
-    0digit
-\= Expect no match
-    bcdef    
-    
 /[[:space:]]+/
     > \x09\x0a\x0c\x0d\x0b<
      
@@ -4635,7 +4623,7 @@
 /((?(R)a+|(?1)b))/
     aaaabcde
 
-/((?(R2)a+|(?1)b))/
+/((?(R2)a+|(?1)b))()/
     aaaabcde
 
 /(?(R)a*(?1)|((?R))b)/
@@ -4879,7 +4867,83 @@
     abcd\=null_context
 
 /()()a+/no_auto_possess
-    aaa\=dfa,allcaptures
-    a\=dfa,allcaptures
+    aaa\=allcaptures
+    a\=allcaptures
 
+/(*LIMIT_DEPTH=100)^((.)(?1)|.)$/
+\= Expect depth limit exceeded
+    a[00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]
+
+/(02-)?[0-9]{3}-[0-9]{3}/
+    02-123-123
+
+/^(a(?2))(b)(?1)/
+    abbab\=find_limits 
+
+/abc/endanchored
+    xyzabc
+\= Expect no match
+    xyzabcdef
+\= Expect error
+    xyzabc\=ph
+
+/abc/
+    xyzabc\=endanchored
+\= Expect no match
+    xyzabcdef\=endanchored
+\= Expect error
+    xyzabc\=ps,endanchored
+
+/abc|bcd/endanchored
+    xyzabcd
+\= Expect no match
+    xyzabcdef
+
+/(*NUL)^.*/
+    a\nb\x00ccc
+    
+/(*NUL)^.*/s
+    a\nb\x00ccc
+    
+/^x/m,newline=nul
+    ab\x00xy
+    
+/'#comment' 0d 0a 00 '^x\' 0a 'y'/x,newline=nul,hex
+    x\nyz 
+ 
+/(*NUL)^X\NY/
+    X\nY
+    X\rY
+\= Expect no match
+    X\x00Y      
+
+/(?<=abc|)/
+    abcde\=aftertext
+    
+/(?<=|abc)/ 
+    abcde\=aftertext
+
+/(?<=abc|)/endanchored
+    abcde\=aftertext
+    
+/(?<=|abc)/endanchored
+    abcde\=aftertext
+
+/(*LIMIT_MATCH=100).*(?![|H]?.*(?![|H]?););.*(?![|H]?.*(?![|H]?););\x00\x00\x00\x00\x00\x00\x00(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?![|);)?.*(![|H]?);)?.*(?![|H]?);)?.*(?![|H]?);)?.*(?![|H]););![|H]?););[|H]?);|H]?);)\x00\x00\x00\x00\x00\x00H]?););?![|H]?);)?.*(?![|H]?););[||H]?);)?.*(?![|H]?););[|H]?);(?![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););;[\x00\x00\x00\x00\x00\x00\x00![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););/no_dotstar_anchor
+.*(?![|H]?.*(?![|H]?););.*(?![|H]?.*(?![|H]?););\x00\x00\x00\x00\x00\x00\x00(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?![|);)?.*(![|H]?);)?.*(?![|H]?);)?.*(?![|H]?);)?.*(?![|H]););![|H]?););[|H]?);|H]?);)\x00\x00\x00\x00\x00\x00H]?););?![|H]?);)?.*(?![|H]?););[||H]?);)?.*(?![|H]?););[|H]?);(?![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););;[\x00\x00\x00\x00\x00\x00\x00![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););
+
+/\n/firstline
+    xyz\nabc
+
+/\nabc/firstline
+    xyz\nabc
+
+/\x{0a}abc/firstline,newline=crlf
+\= Expect no match
+    xyz\r\nabc
+
+/[abc]/firstline
+\= Expect no match
+    \na
+    
 # End of testinput6
diff --git a/dist2/testdata/testinput8 b/dist2/testdata/testinput8
index f4bb709..2627454 100644
--- a/dist2/testdata/testinput8
+++ b/dist2/testdata/testinput8
@@ -161,18 +161,14 @@
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
 
 /(?(1)(?1)){8,}+()/debug
     abcd
diff --git a/dist2/testdata/testinput9 b/dist2/testdata/testinput9
index 9a26f5f..7be4b15 100644
--- a/dist2/testdata/testinput9
+++ b/dist2/testdata/testinput9
@@ -258,4 +258,6 @@
 
 /(*MARK:a\x{100}b)z/alt_verbnames 
 
+/(*:*++++++++++++''''''''''''''''''''+''+++'+++x+++++++++++++++++++++++++++++++++++(++++++++++++++++++++:++++++%++:''''''''''''''''''''''''+++++++++++++++++++++++++++++++++++++++++++++++++++++-++++++++k+++++++''''+++'+++++++++++++++++++++++''''++++++++++++':ƿ)/
+
 # End of testinput9
diff --git a/dist2/testdata/testoutput1 b/dist2/testdata/testoutput1
index d28bf91..9c55be9 100644
--- a/dist2/testdata/testoutput1
+++ b/dist2/testdata/testoutput1
@@ -183,27 +183,6 @@
     abbbbbbbbbbbac
 No match
 
-/^(b+|a){1,2}?bc/
-    bbc
- 0: bbc
- 1: b
-
-/^(b*|ba){1,2}?bc/
-    babc
- 0: babc
- 1: ba
-    bbabc
- 0: bbabc
- 1: ba
-    bababc
- 0: bababc
- 1: ba
-\= Expect no match
-    bababbc
-No match
-    babababc
-No match
-
 /^(ba|b*){1,2}?bc/
     babc
  0: babc
@@ -2006,13 +1985,6 @@
     aaa
 No match
 
-/[\d-z]+/
-    12-34z
- 0: 12-34z
-\= Expect no match
-    aaa
-No match
-
 /\x5c/
     \\
  0: \
@@ -5764,17 +5736,6 @@
  0: 
  0: 
 
-/^[\d-a]/
-    abcde
- 0: a
-    -things
- 0: -
-    0digit
- 0: 0
-\= Expect no match
-    bcdef    
-No match
-    
 /[[:space:]]+/
     > \x09\x0a\x0c\x0d\x0b<
  0:  \x09\x0a\x0c\x0d\x0b
@@ -9257,4 +9218,608 @@
  1: b
  2: cccc
 
+# /x does not apply to MARK labels 
+
+/x (*MARK:ab cd # comment
+ef) x/x,mark
+    axxz
+ 0: xx
+MK: ab cd # comment\x0aef
+
+/(?<=a(B){0}c)X/
+    acX
+ 0: X
+
+/(?<DEFINE>b)(?(DEFINE)(a+))(?&DEFINE)/          
+    bbbb 
+ 0: bb
+ 1: b
+\= Expect no match     
+    baaab
+No match
+
+/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[,;:])(?=.{8,16})(?!.*[\s])/
+    \   Fred:099
+ 0: 
+
+/(?=.*X)X$/ 
+    \  X
+ 0: X
+
+/(?s)(?=.*?)b/
+    aabc
+ 0: b
+
+/(Z)(a)\2{1,2}?(?-i)\1X/i
+    ZaAAZX
+ 0: ZaAAZX
+ 1: Z
+ 2: a
+
+/(?'c')XX(?'YYYYYYYYYYYYYYYYYYYYYYYCl')/
+
+/[s[:digit:]\E-H]+/
+    s09-H
+ 0: s09-H
+
+/[s[:digit:]\Q\E-H]+/
+    s09-H
+ 0: s09-H
+
+/a+(?:|b)a/
+    aaaa
+ 0: aaaa
+
+/X?(R||){3335}/
+
+/(?1)(A(*COMMIT)|B)D/
+    ABD
+ 0: ABD
+ 1: B
+    XABD
+ 0: ABD
+ 1: B
+    BAD
+ 0: BAD
+ 1: A
+    ABXABD  
+ 0: ABD
+ 1: B
+\= Expect no match 
+    ABX 
+No match
+
+/(?(DEFINE)(?<m> 1? (?=(?<cond>2)?) 1 2 (?('cond')|3)))
+    \A
+    ()
+    (?&m)
+    \Z/x
+    123
+ 0: 123
+ 1: <unset>
+ 2: <unset>
+ 3: 
+
+/^(?: 
+(?: A| (1? (?=(?<cond>2)?) (1) 2 (?('cond')|3)) )
+(Z)
+)+$/x
+    AZ123Z
+ 0: AZ123Z
+ 1: 123
+ 2: <unset>
+ 3: 1
+ 4: Z
+\= Expect no match     
+    AZ12Z 
+No match
+    
+/^ (?(DEFINE) ( (?!(a)\2b)..) )   ()(?1)  /x
+    acb
+ 0: ac
+ 1: <unset>
+ 2: <unset>
+ 3: 
+\= Expect no match     
+    aab
+No match
+    
+'(?>ab|abab){1,5}?M'
+    abababababababababababM
+ 0: abababababM
+
+'(?>ab|abab){2}?M'
+    abababM
+ 0: ababM
+
+'((?(?=(a))a)+k)'
+    bbak
+ 0: ak
+ 1: ak
+ 2: a
+
+'((?(?=(a))a|)+k)'
+    bbak
+ 0: ak
+ 1: ak
+ 2: a
+
+'(?(?!(b))a|b)+k'
+    ababbalbbadabak
+ 0: abak
+ 1: b
+
+/(?!(b))c|b/
+    Ab
+ 0: b
+    Ac 
+ 0: c
+
+/(?=(b))b|c/
+    Ab
+ 0: b
+ 1: b
+    Ac 
+ 0: c
+
+/^(.|(.)(?1)\2)$/
+    a
+ 0: a
+ 1: a
+    aba
+ 0: aba
+ 1: aba
+ 2: a
+    abcba
+ 0: abcba
+ 1: abcba
+ 2: a
+    ababa
+ 0: ababa
+ 1: ababa
+ 2: a
+    abcdcba
+ 0: abcdcba
+ 1: abcdcba
+ 2: a
+
+/^((.)(?1)\2|.?)$/
+    a
+ 0: a
+ 1: a
+    aba
+ 0: aba
+ 1: aba
+ 2: a
+    abba
+ 0: abba
+ 1: abba
+ 2: a
+    abcba
+ 0: abcba
+ 1: abcba
+ 2: a
+    ababa
+ 0: ababa
+ 1: ababa
+ 2: a
+    abccba
+ 0: abccba
+ 1: abccba
+ 2: a
+    abcdcba
+ 0: abcdcba
+ 1: abcdcba
+ 2: a
+    abcddcba
+ 0: abcddcba
+ 1: abcddcba
+ 2: a
+
+/^(.)(\1|a(?2))/
+    bab
+ 0: bab
+ 1: b
+ 2: ab
+
+/^(.|(.)(?1)?\2)$/
+    abcba
+ 0: abcba
+ 1: abcba
+ 2: a
+    
+/^(?(?=(a))abc|def)/
+    abc
+ 0: abc
+ 1: a
+
+/^(?(?!(a))def|abc)/
+    abc
+ 0: abc
+ 1: a
+
+/^(?(?=(a)(*ACCEPT))abc|def)/
+    abc
+ 0: abc
+ 1: a
+
+/^(?(?!(a)(*ACCEPT))def|abc)/
+    abc
+ 0: abc
+ 1: a
+
+/^(?1)\d{3}(a)/
+    a123a
+ 0: a123a
+ 1: a
+
+# This pattern uses a lot of named subpatterns in order to match email
+# addresses in various formats. It's a heavy test for named subpatterns. In the
+# <atext> group, slash is coded as \x{2f} so that this pattern can also be
+# processed by perltest.sh, which does not cater for an escaped delimiter
+# within the pattern. $ within the pattern must also be escaped. All $ and @
+# characters in subject strings are escaped so that Perl doesn't interpret them
+# as variable insertions and " characters must also be escaped for Perl.
+
+# This set of subpatterns is more or less a direct transliteration of the BNF
+# definitions in RFC2822, without any of the obsolete features. The addition of
+# a possessive + to the definition of <phrase> reduced the match limit in PCRE2
+# from over 5 million to just under 400, and eliminated a very noticeable delay
+# when this file was passed to perltest.sh.
+
+/(?ix)(?(DEFINE)
+(?<addr_spec>       (?&local_part) \@ (?&domain) )
+(?<angle_addr>      (?&CFWS)?+ < (?&addr_spec) > (?&CFWS)?+ )
+(?<atext>           [a-z\d!#\$%&'*+-\x{2f}=?^_`{|}~] )
+(?<atom>            (?&CFWS)?+ (?&atext)+ (?&CFWS)?+ )
+(?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment) )
+(?<ctext>           [^\x{9}\x{10}\x{13}\x{7f}-\x{ff}\ ()\\] )
+(?<comment>         \( (?: (?&FWS)?+ (?&ccontent) )*+ (?&FWS)?+ \) )
+(?<CFWS>            (?: (?&FWS)?+ (?&comment) )* (?# NOT possessive)
+                    (?: (?&FWS)?+ (?&comment) | (?&FWS) ) )
+(?<dcontent>        (?&dtext) | (?&quoted_pair) )
+(?<display_name>    (?&phrase) )
+(?<domain>          (?&dot_atom) | (?&domain_literal) )
+(?<domain_literal>  (?&CFWS)?+ \[ (?: (?&FWS)?+ (?&dcontent) )* (?&FWS)?+ \]
+                    (?&CFWS)?+ )
+(?<dot_atom>        (?&CFWS)?+ (?&dot_atom_text) (?&CFWS)?+ )
+(?<dot_atom_text>   (?&atext)++ (?: \. (?&atext)++)*+ )
+(?<dtext>           [^\x{9}\x{10}\x{13}\x{7f}-\x{ff}\ \[\]\\] )
+(?<FWS>             (?: [\t\ ]*+ \n)?+ [\t\ ]++ )
+(?<local_part>      (?&dot_atom) | (?&quoted_string)  )
+(?<mailbox>         (?&name_addr) | (?&addr_spec) )
+(?<name_addr>       (?&display_name)? (?&angle_addr) )
+(?<phrase>          (?&word)++ )
+(?<qcontent>        (?&qtext) | (?&quoted_pair) )
+(?<quoted_pair>     " (?&text) )
+(?<quoted_string>   (?&CFWS)?+ " (?: (?&FWS)?+ (?&qcontent))* (?&FWS)?+ "
+                    (?&CFWS)?+ )
+(?<qtext>           [^\x{9}\x{10}\x{13}\x{7f}-\x{ff}\ "\\] )
+(?<text>            [^\r\n] )
+(?<word>            (?&atom) | (?&quoted_string) )
+) # End DEFINE
+^(?&mailbox)$/
+    Alan Other <user\@dom.ain>
+ 0: Alan Other <user@dom.ain>
+    <user\@dom.ain>
+ 0: <user@dom.ain>
+    user\@dom.ain
+ 0: user@dom.ain
+    user\@[] 
+ 0: user@[]
+    user\@[domain literal] 
+ 0: user@[domain literal]
+    user\@[domain literal with \"[square brackets\"] inside] 
+ 0: user@[domain literal with "[square brackets"] inside]
+    \"A. Other\" <user.1234\@dom.ain> (a comment)
+ 0: "A. Other" <user.1234@dom.ain> (a comment)
+    A. Other <user.1234\@dom.ain> (a comment)
+ 0: A. Other <user.1234@dom.ain> (a comment)
+    \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+ 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay
+\= Expect no match
+    A missing angle <user\@some.where
+No match
+    The quick brown fox
+No match
+    
+# -------------------------------------------------------------------------- 
+
+# This pattern uses named groups to match default PCRE2 patterns. It's another
+# heavy test for named subpatterns. Once again, code slash as \x{2f} and escape 
+# $ even in classes so that this works with pcre2test.
+
+/(?sx)(?(DEFINE)
+
+(?<assertion>         (?&simple_assertion) | (?&lookaround) )
+
+(?<atomic_group>      \( \? > (?&regex) \) )
+
+(?<back_reference>    \\ \d+ |
+                      \\g (?: [+-]?\d+ | \{ (?: [+-]?\d+ | (?&groupname) ) \} ) |
+                      \\k <(?&groupname)> |
+                      \\k '(?&groupname)' |
+                      \\k \{ (?&groupname) \} |
+                      \( \? P= (?&groupname) \) )
+
+(?<branch>            (?:(?&assertion) |
+                         (?&callout) |
+                         (?&comment) |
+                         (?&option_setting) |
+                         (?&qualified_item) |
+                         (?&quoted_string) |
+                         (?&quoted_string_empty) | 
+                         (?&special_escape) |
+                         (?&verb)
+                      )* )
+
+(?<callout>           \(\?C (?: \d+ | 
+                      (?: (?<D>["'`^%\#\$]) 
+                        (?: \k'D'\k'D' | (?!\k'D') . )* \k'D' |
+                      \{ (?: \}\} | [^}]*+ )* \} ) 
+                      )? \) )
+
+(?<capturing_group>   \( (?: \? P? < (?&groupname) > | \? ' (?&groupname) ' )?
+                      (?&regex) \) )
+
+(?<character_class>   \[ \^?+ (?: \] (?&class_item)* | (?&class_item)+ ) \] )
+
+(?<character_type>    (?! \\N\{\w+\} ) \\ [dDsSwWhHvVRN] )
+
+(?<class_item>        (?: \[ : (?:
+                      alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|
+                      punct|space|upper|word|xdigit
+                      ) : \] |
+                      (?&quoted_string) |  
+                      (?&quoted_string_empty) | 
+                      (?&escaped_character) | 
+                      (?&character_type) | 
+                      [^]] ) )
+
+(?<comment>           \(\?\# [^)]* \) | (?&quoted_string_empty) | \\E )
+
+(?<condition>         (?: \( [+-]? \d+ \) |
+                          \( < (?&groupname) > \) |
+                          \( ' (?&groupname) ' \) |
+                          \( R \d* \) |
+                          \( R & (?&groupname) \) |
+                          \( (?&groupname) \) | 
+                          \( DEFINE \) |
+                          \( VERSION >?=\d+(?:\.\d\d?)? \) |
+                          (?&callout)?+ (?&comment)* (?&lookaround) ) )
+
+(?<conditional_group> \(\? (?&condition) (?&branch) (?: \| (?&branch) )? \) )
+
+(?<delimited_regex>   (?<delimiter> [-\x{2f}!"'`=_:;,%&@~]) (?&regex) 
+                      \k'delimiter' .* )
+
+(?<escaped_character> \\ (?: 0[0-7]{1,2} | [0-7]{1,3} | o\{ [0-7]+ \} |
+                      x \{ (*COMMIT) [[:xdigit:]]* \} | x [[:xdigit:]]{0,2} | 
+                      [aefnrt] | c[[:print:]] |
+                      [^[:alnum:]] ) )
+
+(?<group>             (?&capturing_group) | (?&non_capturing_group) |
+                      (?&resetting_group) | (?&atomic_group) |
+                      (?&conditional_group) )
+
+(?<groupname>         [a-zA-Z_]\w* )
+
+(?<literal_character> (?! (?&range_qualifier) ) [^[()|*+?.\$\\] )
+
+(?<lookaround>        \(\? (?: = | ! | <= | <! ) (?&regex) \) )
+
+(?<non_capturing_group> \(\? [iJmnsUx-]* : (?&regex) \) )
+
+(?<option_setting>    \(\? [iJmnsUx-]* \) )
+
+(?<qualified_item>    (?:\. |
+                         (?&lookaround) |
+                         (?&back_reference) |
+                         (?&character_class) |
+                         (?&character_type) |
+                         (?&escaped_character) |
+                         (?&group) |
+                         (?&subroutine_call) |
+                         (?&literal_character) |
+                         (?&quoted_string) 
+                      ) (?&comment)? (?&qualifier)? )
+
+(?<qualifier>         (?: [?*+] | (?&range_qualifier) ) [+?]? )
+
+(?<quoted_string>     (?: \\Q (?: (?!\\E | \k'delimiter') . )++ (?: \\E | ) ) ) 
+                      
+(?<quoted_string_empty>  \\Q\\E ) 
+
+(?<range_qualifier>   \{ (?: \d+ (?: , \d* )? | , \d+ ) \} )
+
+(?<regex>             (?&start_item)* (?&branch) (?: \| (?&branch) )* )
+
+(?<resetting_group>   \( \? \| (?&regex) \) )
+
+(?<simple_assertion>  \^ | \$ | \\A | \\b | \\B | \\G | \\z | \\Z )
+
+(?<special_escape>    \\K )
+
+(?<start_item>        \( \* (?:
+                      ANY |
+                      ANYCRLF |
+                      BSR_ANYCRLF |
+                      BSR_UNICODE |
+                      CR |
+                      CRLF |
+                      LF |
+                      LIMIT_MATCH=\d+ |
+                      LIMIT_DEPTH=\d+ |
+                      LIMIT_HEAP=\d+ | 
+                      NOTEMPTY |
+                      NOTEMPTY_ATSTART |
+                      NO_AUTO_POSSESS |
+                      NO_DOTSTAR_ANCHOR |
+                      NO_JIT |
+                      NO_START_OPT |
+                      NUL |
+                      UTF |
+                      UCP ) \) )
+
+(?<subroutine_call>   (?: \(\?R\) | \(\?[+-]?\d+\) |
+                      \(\? (?: & | P> ) (?&groupname) \) |
+                      \\g < (?&groupname) > |
+                      \\g ' (?&groupname) ' |
+                      \\g < [+-]? \d+ > |
+                      \\g ' [+-]? \d+ ) )
+
+(?<verb>              \(\* (?: ACCEPT | FAIL | F | COMMIT |
+                      (?:MARK)?:(?&verbname) |
+                      (?:PRUNE|SKIP|THEN) (?: : (?&verbname)? )? ) \) )
+
+(?<verbname>          [^)]+ )
+
+) # End DEFINE
+# Kick it all off...
+^(?&delimited_regex)$/subject_literal,jitstack=256
+    /^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/
+ 0: /^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/
+    /(cat(a(ract|tonic)|erpillar)) \1()2(3)/
+ 0: /(cat(a(ract|tonic)|erpillar)) \1()2(3)/
+    /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/
+ 0: /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/
+    /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/
+ 0: /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/
+    /<tr([\w\W\s\d][^<>]{0,})><TD([\w\W\s\d][^<>]{0,})>([\d]{0,}\.)(.*)((<BR>([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is
+ 0: /<tr([\w\W\s\d][^<>]{0,})><TD([\w\W\s\d][^<>]{0,})>([\d]{0,}\.)(.*)((<BR>([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is
+    /^(?(DEFINE) (?<A> a) (?<B> b) )  (?&A) (?&B) /
+ 0: /^(?(DEFINE) (?<A> a) (?<B> b) )  (?&A) (?&B) /
+    /(?(DEFINE)(?<byte>2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/
+ 0: /(?(DEFINE)(?<byte>2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/
+    /\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/
+ 0: /\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/
+    /^(\w++|\s++)*$/
+ 0: /^(\w++|\s++)*$/
+    /a+b?(*THEN)c+(*FAIL)/
+ 0: /a+b?(*THEN)c+(*FAIL)/
+    /(A (A|B(*ACCEPT)|C) D)(E)/x
+ 0: /(A (A|B(*ACCEPT)|C) D)(E)/x
+    /^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$/i
+ 0: /^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$/i
+    /A(*PRUNE)B(*SKIP)C(*THEN)D(*COMMIT)E(*F)F(*FAIL)G(?!)H(*ACCEPT)I/B
+ 0: /A(*PRUNE)B(*SKIP)C(*THEN)D(*COMMIT)E(*F)F(*FAIL)G(?!)H(*ACCEPT)I/B
+    /(?C`a``b`)(?C'a''b')(?C"a""b")(?C^a^^b^)(?C%a%%b%)(?C#a##b#)(?C$a$$b$)(?C{a}}b})/B,callout_info
+ 0: /(?C`a``b`)(?C'a''b')(?C"a""b")(?C^a^^b^)(?C%a%%b%)(?C#a##b#)(?C$a$$b$)(?C{a}}b})/B,callout_info
+    /(?sx)(?(DEFINE)(?<assertion> (?&simple_assertion) | (?&lookaround) )(?<atomic_group> \( \? > (?&regex) \) )(?<back_reference> \\ \d+ | \\g (?: [+-]?\d+ | \{ (?: [+-]?\d+ | (?&groupname) ) \} ) | \\k <(?&groupname)> | \\k '(?&groupname)' | \\k \{ (?&groupname) \} | \( \? P= (?&groupname) \) )(?<branch> (?:(?&assertion) | (?&callout) | (?&comment) | (?&option_setting) | (?&qualified_item) | (?&quoted_string) | (?&quoted_string_empty) | (?&special_escape) | (?&verb) )* )(?<callout> \(\?C (?: \d+ | (?: (?<D>["'`^%\#\$]) (?: \k'D'\k'D' | (?!\k'D') . )* \k'D' | \{ (?: \}\} | [^}]*+ )* \} ) )? \) )(?<capturing_group> \( (?: \? P? < (?&groupname) > | \? ' (?&groupname) ' )? (?&regex) \) )(?<character_class> \[ \^?+ (?: \] (?&class_item)* | (?&class_item)+ ) \] )(?<character_type> (?! \\N\{\w+\} ) \\ [dDsSwWhHvVRN] )(?<class_item> (?: \[ : (?: alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print| punct|space|upper|word|xdigit ) : \] | (?&quoted_string) | (?&quoted_string_empty) | (?&escaped_character) | (?&character_type) | [^]] ) )(?<comment> \(\?\# [^)]* \) | (?&quoted_string_empty) | \\E )(?<condition> (?: \( [+-]? \d+ \) | \( < (?&groupname) > \) | \( ' (?&groupname) ' \) | \( R \d* \) | \( R & (?&groupname) \) | \( (?&groupname) \) | \( DEFINE \) | \( VERSION >?=\d+(?:\.\d\d?)? \) | (?&callout)?+ (?&comment)* (?&lookaround) ) )(?<conditional_group> \(\? (?&condition) (?&branch) (?: \| (?&branch) )? \) )(?<delimited_regex> (?<delimiter> [-\x{2f}!"'`=_:;,%&@~]) (?&regex) \k'delimiter' .* )(?<escaped_character> \\ (?: 0[0-7]{1,2} | [0-7]{1,3} | o\{ [0-7]+ \} | x \{ (*COMMIT) [[:xdigit:]]* \} | x [[:xdigit:]]{0,2} | [aefnrt] | c[[:print:]] | [^[:alnum:]] ) )(?<group> (?&capturing_group) | (?&non_capturing_group) | (?&resetting_group) | (?&atomic_group) | (?&conditional_group) )(?<groupname> [a-zA-Z_]\w* )(?<literal_character> (?! (?&range_qualifier) ) [^[()|*+?.\$\\] )(?<lookaround> \(\? (?: = | ! | <= | <! ) (?&regex) \) )(?<non_capturing_group> \(\? [iJmnsUx-]* : (?&regex) \) )(?<option_setting> \(\? [iJmnsUx-]* \) )(?<qualified_item> (?:\. | (?&lookaround) | (?&back_reference) | (?&character_class) | (?&character_type) | (?&escaped_character) | (?&group) | (?&subroutine_call) | (?&literal_character) | (?&quoted_string) ) (?&comment)? (?&qualifier)? )(?<qualifier> (?: [?*+] | (?&range_qualifier) ) [+?]? )(?<quoted_string> (?: \\Q (?: (?!\\E | \k'delimiter') . )++ (?: \\E | ) ) ) (?<quoted_string_empty> \\Q\\E ) (?<range_qualifier> \{ (?: \d+ (?: , \d* )? | , \d+ ) \} )(?<regex> (?&start_item)* (?&branch) (?: \| (?&branch) )* )(?<resetting_group> \( \? \| (?&regex) \) )(?<simple_assertion> \^ | \$ | \\A | \\b | \\B | \\G | \\z | \\Z )(?<special_escape> \\K )(?<start_item> \( \* (?: ANY | ANYCRLF | BSR_ANYCRLF | BSR_UNICODE | CR | CRLF | LF | LIMIT_MATCH=\d+ | LIMIT_DEPTH=\d+ | LIMIT_HEAP=\d+ | NOTEMPTY | NOTEMPTY_ATSTART | NO_AUTO_POSSESS | NO_DOTSTAR_ANCHOR | NO_JIT | NO_START_OPT | NUL | UTF | UCP ) \) )(?<subroutine_call> (?: \(\?R\) | \(\?[+-]?\d+\) | \(\? (?: & | P> ) (?&groupname) \) | \\g < (?&groupname) > | \\g ' (?&groupname) ' | \\g < [+-]? \d+ > | \\g ' [+-]? \d+ ) )(?<verb> \(\* (?: ACCEPT | FAIL | F | COMMIT | (?:MARK)?:(?&verbname) | (?:PRUNE|SKIP|THEN) (?: : (?&verbname)? )? ) \) )(?<verbname> [^)]+ ))^(?&delimited_regex)$/
+ 0: /(?sx)(?(DEFINE)(?<assertion> (?&simple_assertion) | (?&lookaround) )(?<atomic_group> \( \? > (?&regex) \) )(?<back_reference> \\ \d+ | \\g (?: [+-]?\d+ | \{ (?: [+-]?\d+ | (?&groupname) ) \} ) | \\k <(?&groupname)> | \\k '(?&groupname)' | \\k \{ (?&groupname) \} | \( \? P= (?&groupname) \) )(?<branch> (?:(?&assertion) | (?&callout) | (?&comment) | (?&option_setting) | (?&qualified_item) | (?&quoted_string) | (?&quoted_string_empty) | (?&special_escape) | (?&verb) )* )(?<callout> \(\?C (?: \d+ | (?: (?<D>["'`^%\#\$]) (?: \k'D'\k'D' | (?!\k'D') . )* \k'D' | \{ (?: \}\} | [^}]*+ )* \} ) )? \) )(?<capturing_group> \( (?: \? P? < (?&groupname) > | \? ' (?&groupname) ' )? (?&regex) \) )(?<character_class> \[ \^?+ (?: \] (?&class_item)* | (?&class_item)+ ) \] )(?<character_type> (?! \\N\{\w+\} ) \\ [dDsSwWhHvVRN] )(?<class_item> (?: \[ : (?: alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print| punct|space|upper|word|xdigit ) : \] | (?&quoted_string) | (?&quoted_string_empty) | (?&escaped_character) | (?&character_type) | [^]] ) )(?<comment> \(\?\# [^)]* \) | (?&quoted_string_empty) | \\E )(?<condition> (?: \( [+-]? \d+ \) | \( < (?&groupname) > \) | \( ' (?&groupname) ' \) | \( R \d* \) | \( R & (?&groupname) \) | \( (?&groupname) \) | \( DEFINE \) | \( VERSION >?=\d+(?:\.\d\d?)? \) | (?&callout)?+ (?&comment)* (?&lookaround) ) )(?<conditional_group> \(\? (?&condition) (?&branch) (?: \| (?&branch) )? \) )(?<delimited_regex> (?<delimiter> [-\x{2f}!"'`=_:;,%&@~]) (?&regex) \k'delimiter' .* )(?<escaped_character> \\ (?: 0[0-7]{1,2} | [0-7]{1,3} | o\{ [0-7]+ \} | x \{ (*COMMIT) [[:xdigit:]]* \} | x [[:xdigit:]]{0,2} | [aefnrt] | c[[:print:]] | [^[:alnum:]] ) )(?<group> (?&capturing_group) | (?&non_capturing_group) | (?&resetting_group) | (?&atomic_group) | (?&conditional_group) )(?<groupname> [a-zA-Z_]\w* )(?<literal_character> (?! (?&range_qualifier) ) [^[()|*+?.\$\\] )(?<lookaround> \(\? (?: = | ! | <= | <! ) (?&regex) \) )(?<non_capturing_group> \(\? [iJmnsUx-]* : (?&regex) \) )(?<option_setting> \(\? [iJmnsUx-]* \) )(?<qualified_item> (?:\. | (?&lookaround) | (?&back_reference) | (?&character_class) | (?&character_type) | (?&escaped_character) | (?&group) | (?&subroutine_call) | (?&literal_character) | (?&quoted_string) ) (?&comment)? (?&qualifier)? )(?<qualifier> (?: [?*+] | (?&range_qualifier) ) [+?]? )(?<quoted_string> (?: \\Q (?: (?!\\E | \k'delimiter') . )++ (?: \\E | ) ) ) (?<quoted_string_empty> \\Q\\E ) (?<range_qualifier> \{ (?: \d+ (?: , \d* )? | , \d+ ) \} )(?<regex> (?&start_item)* (?&branch) (?: \| (?&branch) )* )(?<resetting_group> \( \? \| (?&regex) \) )(?<simple_assertion> \^ | \$ | \\A | \\b | \\B | \\G | \\z | \\Z )(?<special_escape> \\K )(?<start_item> \( \* (?: ANY | ANYCRLF | BSR_ANYCRLF | BSR_UNICODE | CR | CRLF | LF | LIMIT_MATCH=\d+ | LIMIT_DEPTH=\d+ | LIMIT_HEAP=\d+ | NOTEMPTY | NOTEMPTY_ATSTART | NO_AUTO_POSSESS | NO_DOTSTAR_ANCHOR | NO_JIT | NO_START_OPT | NUL | UTF | UCP ) \) )(?<subroutine_call> (?: \(\?R\) | \(\?[+-]?\d+\) | \(\? (?: & | P> ) (?&groupname) \) | \\g < (?&groupname) > | \\g ' (?&groupname) ' | \\g < [+-]? \d+ > | \\g ' [+-]? \d+ ) )(?<verb> \(\* (?: ACCEPT | FAIL | F | COMMIT | (?:MARK)?:(?&verbname) | (?:PRUNE|SKIP|THEN) (?: : (?&verbname)? )? ) \) )(?<verbname> [^)]+ ))^(?&delimited_regex)$/
+\= Expect no match
+    /((?(?C'')\QX\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
+No match
+    /(?:(?(2y)a|b)(X))+/
+No match
+    /a(*MARK)b/
+No match
+    /a(*CR)b/
+No match
+    /(?P<abn>(?P=abn)(?<badstufxxx)/
+No match
+
+# -------------------------------------------------------------------------- 
+
+/<(?x:[a b])>/xx
+    < >
+ 0: < >
+
+/<(?:[a b])>/xx
+    < >
+No match
+
+/<(?xxx:[a b])>/
+    < >
+No match
+    
+/<(?-x:[a b])>/xx
+    < >
+ 0: < >
+
+/[[:digit:]-]+/
+    12-24
+ 0: 12-24
+
+/((?<=((*ACCEPT)) )\1?\b) /
+\= Expect no match     
+    ((?<=((*ACCEPT)) )\\1?\\b)\x20
+No match
+
+/((?<=((*ACCEPT))X)\1?Y)\1/
+    XYYZ
+ 0: YY
+ 1: Y
+ 2: 
+
+/((?<=((*ACCEPT))X)\1?Y(*ACCEPT))\1/
+    XYYZ
+ 0: Y
+ 1: Y
+ 2: 
+
+/(?(DEFINE)(?<optional_a>a?)X)^(?&optional_a)a$/
+    aa
+ 0: aa
+    a
+ 0: a
+
+/^(a?)b(?1)a/
+    abaa
+ 0: abaa
+ 1: a
+    aba 
+ 0: aba
+ 1: a
+    baa
+ 0: baa
+ 1: 
+    ba  
+ 0: ba
+ 1: 
+
+/^(a?)+b(?1)a/
+    abaa
+ 0: abaa
+ 1: 
+    aba 
+ 0: aba
+ 1: 
+    baa
+ 0: baa
+ 1: 
+    ba  
+ 0: ba
+ 1: 
+
+/^(a?)++b(?1)a/
+    abaa
+ 0: abaa
+ 1: 
+    aba 
+ 0: aba
+ 1: 
+    baa
+ 0: baa
+ 1: 
+    ba  
+ 0: ba
+ 1: 
+
+/^(a?)+b/
+    b
+ 0: b
+ 1: 
+    ab
+ 0: ab
+ 1: 
+    aaab 
+ 0: aaab
+ 1: 
+
+/(?=a+)a(a+)++b/
+    aab
+ 0: aab
+ 1: a
+
 # End of testinput1 
diff --git a/dist2/testdata/testoutput10 b/dist2/testdata/testoutput10
index 9761f0f..9660fc5 100644
--- a/dist2/testdata/testoutput10
+++ b/dist2/testdata/testoutput10
@@ -1539,4 +1539,91 @@
     a\x80zx\=offset=3
 Failed: error -22: UTF-8 error: isolated byte with 0x80 bit set at offset 1
 
+/[\W\p{Any}]/B
+------------------------------------------------------------------
+        Bra
+        [\x00-/:-@[-^`{-\xff\p{Any}]
+        Ket
+        End
+------------------------------------------------------------------
+    abc
+ 0: a
+    123 
+ 0: 1
+
+/[\W\pL]/B
+------------------------------------------------------------------
+        Bra
+        [\x00-/:-@[-^`{-\xff\p{L}]
+        Ket
+        End
+------------------------------------------------------------------
+    abc
+ 0: a
+\= Expect no match
+    123     
+No match
+
+/(*:*++++++++++++''''''''''''''''''''+''+++'+++x+++++++++++++++++++++++++++++++++++(++++++++++++++++++++:++++++%++:''''''''''''''''''''''''+++++++++++++++++++++++++++++++++++++++++++++++++++++-++++++++k+++++++''''+++'+++++++++++++++++++++++''''++++++++++++':ƿ)/utf
+Failed: error 176 at offset 259: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
+
+/[\s[:^ascii:]]/B,ucp
+------------------------------------------------------------------
+        Bra
+        [\x80-\xff\p{Xsp}]
+        Ket
+        End
+------------------------------------------------------------------
+
+# A special extra option allows excaped surrogate code points in 8-bit mode,
+# but subjects containing them must not be UTF-checked.
+
+/\x{d800}/I,utf,allow_surrogate_escapes
+Capturing subpattern count = 0
+Options: utf
+Extra options: allow_surrogate_escapes
+First code unit = \xed
+Last code unit = \x80
+Subject length lower bound = 1
+    \x{d800}\=no_utf_check
+ 0: \x{d800}
+
+/\udfff\o{157401}/utf,alt_bsux,allow_surrogate_escapes
+    \x{dfff}\x{df01}\=no_utf_check
+ 0: \x{dfff}\x{df01}
+    
+# This has different starting code units in 8-bit mode. 
+
+/^[^ab]/IB,utf
+------------------------------------------------------------------
+        Bra
+        ^
+        [\x00-`c-\xff] (neg)
+        Ket
+        End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Compile options: utf
+Overall options: anchored utf
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 
+  5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y 
+  Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f 
+  \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 
+  \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf 
+  \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee 
+  \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd 
+  \xfe \xff 
+Subject length lower bound = 1
+    c
+ 0: c
+    \x{ff}
+ 0: \x{ff}
+    \x{100}
+ 0: \x{100}
+\= Expect no match
+    aaa
+No match
+
 # End of testinput10
diff --git a/dist2/testdata/testoutput11-16 b/dist2/testdata/testoutput11-16
index 03e04bc..e22581d 100644
--- a/dist2/testdata/testoutput11-16
+++ b/dist2/testdata/testoutput11-16
@@ -643,4 +643,22 @@
 
 /(*THEN:\[A]{65501})/expand
 
+# We can use pcre2test's utf8_input modifier to create wide pattern characters,
+# even though this test is run when UTF is not supported.
+
+/abý¿¿¿¿¿z/utf8_input
+** Failed: character value greater than 0xffff cannot be converted to 16-bit in non-UTF mode
+    abý¿¿¿¿¿z
+    ab\x{7fffffff}z
+
+/abÿý¿¿¿¿¿z/utf8_input
+** Failed: invalid UTF-8 string cannot be converted to 16-bit string
+    abÿý¿¿¿¿¿z
+    ab\x{ffffffff}z 
+
+/abÿAz/utf8_input
+** Failed: invalid UTF-8 string cannot be converted to 16-bit string
+    abÿAz
+    ab\x{80000041}z 
+
 # End of testinput11
diff --git a/dist2/testdata/testoutput11-32 b/dist2/testdata/testoutput11-32
index 390ebe0..d8a909f 100644
--- a/dist2/testdata/testoutput11-32
+++ b/dist2/testdata/testoutput11-32
@@ -646,4 +646,25 @@
 
 /(*THEN:\[A]{65501})/expand
 
+# We can use pcre2test's utf8_input modifier to create wide pattern characters,
+# even though this test is run when UTF is not supported.
+
+/abý¿¿¿¿¿z/utf8_input
+    abý¿¿¿¿¿z
+ 0: ab\x{7fffffff}z
+    ab\x{7fffffff}z
+ 0: ab\x{7fffffff}z
+
+/abÿý¿¿¿¿¿z/utf8_input
+    abÿý¿¿¿¿¿z
+ 0: ab\x{ffffffff}z
+    ab\x{ffffffff}z 
+ 0: ab\x{ffffffff}z
+
+/abÿAz/utf8_input
+    abÿAz
+ 0: ab\x{80000041}z
+    ab\x{80000041}z 
+ 0: ab\x{80000041}z
+
 # End of testinput11
diff --git a/dist2/testdata/testoutput12-16 b/dist2/testdata/testoutput12-16
index 383a032..52dbe74 100644
--- a/dist2/testdata/testoutput12-16
+++ b/dist2/testdata/testoutput12-16
@@ -557,7 +557,7 @@
  0: \x{11234}
 
 /(*UTF-32)\x{11234}/
-Failed: error 134 at offset 17: character code point value in \x{} or \o{} is too large
+Failed: error 160 at offset 5: (*VERB) not recognized or malformed
   abcd\x{11234}pqr
 
 /(*UTF-32)\x{112}/
@@ -1367,4 +1367,108 @@
     \x{110000}
 ** Failed: character \x{110000} is greater than 0x10ffff and so cannot be converted to UTF-16
 
+/(*UTF)abý¿¿¿¿¿z/B
+------------------------------------------------------------------
+        Bra
+        ab\x{fd}\x{bf}\x{bf}\x{bf}\x{bf}\x{bf}z
+        Ket
+        End
+------------------------------------------------------------------
+
+/abý¿¿¿¿¿z/utf
+** Failed: character value greater than 0x10ffff cannot be converted to UTF
+
+/[\W\p{Any}]/B
+------------------------------------------------------------------
+        Bra
+        [\x00-/:-@[-^`{-\xff\p{Any}\x{100}-\x{ffff}]
+        Ket
+        End
+------------------------------------------------------------------
+    abc
+ 0: a
+    123 
+ 0: 1
+
+/[\W\pL]/B
+------------------------------------------------------------------
+        Bra
+        [\x00-/:-@[-^`{-\xff\p{L}\x{100}-\x{ffff}]
+        Ket
+        End
+------------------------------------------------------------------
+    abc
+ 0: a
+    \x{100}
+ 0: \x{100}
+    \x{308}  
+ 0: \x{308}
+\= Expect no match
+    123     
+No match
+
+/[\s[:^ascii:]]/B,ucp
+------------------------------------------------------------------
+        Bra
+        [\x80-\xff\p{Xsp}\x{100}-\x{ffff}]
+        Ket
+        End
+------------------------------------------------------------------
+
+/\pP/ucp
+    \x{7fffffff}
+** Character \x{7fffffff} is greater than 0xffff and UTF-16 mode is not enabled.
+** Truncation will probably give the wrong result.
+No match
+
+# A special extra option allows excaped surrogate code points in 32-bit mode,
+# but subjects containing them must not be UTF-checked. These patterns give
+# errors in 16-bit mode.
+
+/\x{d800}/I,utf,allow_surrogate_escapes
+Failed: error 191 at offset 0: PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode
+    \x{d800}\=no_utf_check
+
+/\udfff\o{157401}/utf,alt_bsux,allow_surrogate_escapes
+Failed: error 191 at offset 0: PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode
+    \x{dfff}\x{df01}\=no_utf_check
+
+# This has different starting code units in 8-bit mode. 
+
+/^[^ab]/IB,utf
+------------------------------------------------------------------
+        Bra
+        ^
+        [\x00-`c-\xff] (neg)
+        Ket
+        End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Compile options: utf
+Overall options: anchored utf
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 
+  5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y 
+  Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f 
+  \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e 
+  \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d 
+  \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac 
+  \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb 
+  \xbc \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca 
+  \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 
+  \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 
+  \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 
+  \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff 
+Subject length lower bound = 1
+    c
+ 0: c
+    \x{ff}
+ 0: \x{ff}
+    \x{100}
+ 0: \x{100}
+\= Expect no match
+    aaa
+No match
+
 # End of testinput12
diff --git a/dist2/testdata/testoutput12-32 b/dist2/testdata/testoutput12-32
index 95f1834..38ff92d 100644
--- a/dist2/testdata/testoutput12-32
+++ b/dist2/testdata/testoutput12-32
@@ -1361,4 +1361,111 @@
     \x{110000}
 Failed: error -28: UTF-32 error: code points greater than 0x10ffff are not defined at offset 0
 
+/(*UTF)abý¿¿¿¿¿z/B
+------------------------------------------------------------------
+        Bra
+        ab\x{fd}\x{bf}\x{bf}\x{bf}\x{bf}\x{bf}z
+        Ket
+        End
+------------------------------------------------------------------
+
+/abý¿¿¿¿¿z/utf
+** Failed: character value greater than 0x10ffff cannot be converted to UTF
+
+/[\W\p{Any}]/B
+------------------------------------------------------------------
+        Bra
+        [\x00-/:-@[-^`{-\xff\p{Any}\x{100}-\x{ffffffff}]
+        Ket
+        End
+------------------------------------------------------------------
+    abc
+ 0: a
+    123 
+ 0: 1
+
+/[\W\pL]/B
+------------------------------------------------------------------
+        Bra
+        [\x00-/:-@[-^`{-\xff\p{L}\x{100}-\x{ffffffff}]
+        Ket
+        End
+------------------------------------------------------------------
+    abc
+ 0: a
+    \x{100}
+ 0: \x{100}
+    \x{308}  
+ 0: \x{308}
+\= Expect no match
+    123     
+No match
+
+/[\s[:^ascii:]]/B,ucp
+------------------------------------------------------------------
+        Bra
+        [\x80-\xff\p{Xsp}\x{100}-\x{ffffffff}]
+        Ket
+        End
+------------------------------------------------------------------
+
+/\pP/ucp
+    \x{7fffffff}
+No match
+
+# A special extra option allows excaped surrogate code points in 32-bit mode,
+# but subjects containing them must not be UTF-checked. These patterns give
+# errors in 16-bit mode.
+
+/\x{d800}/I,utf,allow_surrogate_escapes
+Capturing subpattern count = 0
+Options: utf
+Extra options: allow_surrogate_escapes
+First code unit = \x{d800}
+Subject length lower bound = 1
+    \x{d800}\=no_utf_check
+ 0: \x{d800}
+
+/\udfff\o{157401}/utf,alt_bsux,allow_surrogate_escapes
+    \x{dfff}\x{df01}\=no_utf_check
+ 0: \x{dfff}\x{df01}
+
+# This has different starting code units in 8-bit mode. 
+
+/^[^ab]/IB,utf
+------------------------------------------------------------------
+        Bra
+        ^
+        [\x00-`c-\xff] (neg)
+        Ket
+        End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Compile options: utf
+Overall options: anchored utf
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 
+  5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y 
+  Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f 
+  \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e 
+  \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d 
+  \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac 
+  \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb 
+  \xbc \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca 
+  \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 
+  \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 
+  \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 
+  \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff 
+Subject length lower bound = 1
+    c
+ 0: c
+    \x{ff}
+ 0: \x{ff}
+    \x{100}
+ 0: \x{100}
+\= Expect no match
+    aaa
+No match
+
 # End of testinput12
diff --git a/dist2/testdata/testoutput15 b/dist2/testdata/testoutput15
index bb29a49..b2068d0 100644
--- a/dist2/testdata/testoutput15
+++ b/dist2/testdata/testoutput15
@@ -12,13 +12,15 @@
 Last code unit = 'z'
 Subject length lower bound = 2
   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\=find_limits
-Minimum match limit = 8
-Minimum recursion limit = 6
+Minimum heap limit = 0
+Minimum match limit = 7
+Minimum depth limit = 7
  0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz
  1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaz\=find_limits
-Minimum match limit = 32768
-Minimum recursion limit = 29
+Minimum heap limit = 0
+Minimum match limit = 20481
+Minimum depth limit = 30
 No match
 
 !((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)!I
@@ -26,61 +28,71 @@
 May match empty string
 Subject length lower bound = 0
    /* this is a C style comment */\=find_limits
-Minimum match limit = 120
-Minimum recursion limit = 6
+Minimum heap limit = 0
+Minimum match limit = 64
+Minimum depth limit = 7
  0: /* this is a C style comment */
  1: /* this is a C style comment */
 
 /^(?>a)++/
     aa\=find_limits
+Minimum heap limit = 0
 Minimum match limit = 5
-Minimum recursion limit = 2
+Minimum depth limit = 3
  0: aa
     aaaaaaaaa\=find_limits
+Minimum heap limit = 0
 Minimum match limit = 12
-Minimum recursion limit = 2
+Minimum depth limit = 3
  0: aaaaaaaaa
     
 /(a)(?1)++/
     aa\=find_limits
+Minimum heap limit = 0
 Minimum match limit = 7
-Minimum recursion limit = 4
+Minimum depth limit = 5
  0: aa
  1: a
     aaaaaaaaa\=find_limits
+Minimum heap limit = 0
 Minimum match limit = 21
-Minimum recursion limit = 4
+Minimum depth limit = 5
  0: aaaaaaaaa
  1: a
 
 /a(?:.)*?a/ims
     abbbbbbbbbbbbbbbbbbbbba\=find_limits
-Minimum match limit = 65
-Minimum recursion limit = 2
+Minimum heap limit = 0
+Minimum match limit = 24
+Minimum depth limit = 3
  0: abbbbbbbbbbbbbbbbbbbbba
     
 /a(?:.(*THEN))*?a/ims
     abbbbbbbbbbbbbbbbbbbbba\=find_limits
-Minimum match limit = 86
-Minimum recursion limit = 45
+Minimum heap limit = 0
+Minimum match limit = 66
+Minimum depth limit = 45
  0: abbbbbbbbbbbbbbbbbbbbba
 
 /a(?:.(*THEN:ABC))*?a/ims
     abbbbbbbbbbbbbbbbbbbbba\=find_limits
-Minimum match limit = 86
-Minimum recursion limit = 45
+Minimum heap limit = 0
+Minimum match limit = 66
+Minimum depth limit = 45
  0: abbbbbbbbbbbbbbbbbbbbba
 
 /^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/
      aabbccddee\=find_limits
+Minimum heap limit = 0
 Minimum match limit = 7
-Minimum recursion limit = 2
+Minimum depth limit = 7
  0: aabbccddee
 
 /^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/
      aabbccddee\=find_limits
-Minimum match limit = 17
-Minimum recursion limit = 16
+Minimum heap limit = 0
+Minimum match limit = 12
+Minimum depth limit = 12
  0: aabbccddee
  1: aa
  2: bb
@@ -90,8 +102,9 @@
 
 /^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/
      aabbccddee\=find_limits
-Minimum match limit = 13
-Minimum recursion limit = 10
+Minimum heap limit = 0
+Minimum match limit = 10
+Minimum depth limit = 10
  0: aabbccddee
  1: aa
  2: cc
@@ -103,9 +116,9 @@
 /(*LIMIT_MATCH=4294967290)abc/
 Failed: error 160 at offset 24: (*VERB) not recognized or malformed
 
-/(*LIMIT_RECURSION=4294967280)abc/I
+/(*LIMIT_DEPTH=4294967280)abc/I
 Capturing subpattern count = 0
-Recursion limit = 4294967280
+Depth limit = 4294967280
 First code unit = 'a'
 Last code unit = 'c'
 Subject length lower bound = 3
@@ -117,8 +130,8 @@
 Failed: error -47: match limit exceeded
 
 /(a+)*zz/
-    aaaaaaaaaaaaaz\=recursion_limit=10
-Failed: error -53: recursion limit exceeded
+    aaaaaaaaaaaaaz\=depth_limit=10
+Failed: error -53: matching depth limit exceeded
 
 /(*LIMIT_MATCH=3000)(a+)*zz/I
 Capturing subpattern count = 1
@@ -151,36 +164,36 @@
     aaaaaaaaaaaaaz\=match_limit=3000
 Failed: error -47: match limit exceeded
 
-/(*LIMIT_RECURSION=10)(a+)*zz/I
+/(*LIMIT_DEPTH=10)(a+)*zz/I
 Capturing subpattern count = 1
-Recursion limit = 10
+Depth limit = 10
 Starting code units: a z 
 Last code unit = 'z'
 Subject length lower bound = 2
     aaaaaaaaaaaaaz
-Failed: error -53: recursion limit exceeded
-    aaaaaaaaaaaaaz\=recursion_limit=1000
-Failed: error -53: recursion limit exceeded
+Failed: error -53: matching depth limit exceeded
+    aaaaaaaaaaaaaz\=depth_limit=1000
+Failed: error -53: matching depth limit exceeded
 
-/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/I
+/(*LIMIT_DEPTH=10)(*LIMIT_DEPTH=1000)(a+)*zz/I
 Capturing subpattern count = 1
-Recursion limit = 1000
+Depth limit = 1000
 Starting code units: a z 
 Last code unit = 'z'
 Subject length lower bound = 2
     aaaaaaaaaaaaaz
 No match
 
-/(*LIMIT_RECURSION=1000)(a+)*zz/I
+/(*LIMIT_DEPTH=1000)(a+)*zz/I
 Capturing subpattern count = 1
-Recursion limit = 1000
+Depth limit = 1000
 Starting code units: a z 
 Last code unit = 'z'
 Subject length lower bound = 2
     aaaaaaaaaaaaaz
 No match
-    aaaaaaaaaaaaaz\=recursion_limit=10
-Failed: error -53: recursion limit exceeded
+    aaaaaaaaaaaaaz\=depth_limit=10
+Failed: error -53: matching depth limit exceeded
     
 # These three have infinitely nested recursions. 
     
@@ -188,7 +201,7 @@
     abc
 Failed: error -52: nested recursion at the same subject position
 
-/((?(R2)a+|(?1)b))/
+/((?(R2)a+|(?1)b))()/
     aaaabcde
 Failed: error -52: nested recursion at the same subject position
 
@@ -348,12 +361,12 @@
 Subject length lower bound = 1
     abc\=callout_fail=1
 --->abc
-  1 ^  ^    
-  1 ^ ^     
-  1 ^^      
-  1  ^ ^    
-  1  ^^     
-  1   ^^    
+  1 ^  ^    End of pattern
+  1 ^ ^     End of pattern
+  1 ^^      End of pattern
+  1  ^ ^    End of pattern
+  1  ^^     End of pattern
+  1   ^^    End of pattern
 No match
 
 /(*NO_AUTO_POSSESS)\w+(?C1)/BI
@@ -372,12 +385,23 @@
 Subject length lower bound = 1
     abc\=callout_fail=1
 --->abc
-  1 ^  ^    
-  1 ^ ^     
-  1 ^^      
-  1  ^ ^    
-  1  ^^     
-  1   ^^    
+  1 ^  ^    End of pattern
+  1 ^ ^     End of pattern
+  1 ^^      End of pattern
+  1  ^ ^    End of pattern
+  1  ^^     End of pattern
+  1   ^^    End of pattern
 No match
 
+# This test breaks the JIT stack limit 
+
+/(|]+){2,2452}/
+    (|]+){2,2452}
+ 0: 
+ 1: 
+
+/(*LIMIT_HEAP=21)\[(a)]{60}/expand
+    \[a]{60}
+Failed: error -63: heap limit exceeded
+
 # End of testinput15
diff --git a/dist2/testdata/testoutput17 b/dist2/testdata/testoutput17
index f560f1b..a0606a7 100644
--- a/dist2/testdata/testoutput17
+++ b/dist2/testdata/testoutput17
@@ -335,7 +335,7 @@
     abc
 Failed: error -46: JIT stack limit reached
 
-/((?(R2)a+|(?1)b))/
+/((?(R2)a+|(?1)b))()/
     aaaabcde
 Failed: error -46: JIT stack limit reached
 
@@ -368,6 +368,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 6
 JIT compilation was successful
 #pop jitverify
@@ -379,6 +380,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 6
 JIT compilation was successful
 #save testsaved1
diff --git a/dist2/testdata/testoutput18 b/dist2/testdata/testoutput18
index 294b121..d51423d 100644
--- a/dist2/testdata/testoutput18
+++ b/dist2/testdata/testoutput18
@@ -5,7 +5,7 @@
 #forbid_utf
 #pattern posix
 
-# Test invalid options
+# Test some invalid options
 
 /abc/auto_callout
 ** Ignored with POSIX interface: auto_callout
@@ -19,6 +19,12 @@
   abc\=partial_hard
 ** Ignored with POSIX interface: partial_hard
  0: abc
+  
+/a(())bc/parens_nest_limit=1
+** Ignored with POSIX interface: parens_nest_limit
+
+/abc/allow_surrogate_escapes,max_pattern_length=2
+** Ignored with POSIX interface: allow_surrogate_escapes max_pattern_length
 
 # Real tests
 
@@ -139,13 +145,13 @@
  0+ issippi
 
 /abc/\
-Failed: POSIX code 9: bad escape sequence at offset 3     
+Failed: POSIX code 9: bad escape sequence at offset 4     
 
 "(?(?C)"
 Failed: POSIX code 11: unbalanced () at offset 6     
 
 "(?(?C))"
-Failed: POSIX code 3: pattern error at offset 2     
+Failed: POSIX code 3: pattern error at offset 6     
 
 /abcd/substitute_extended
 ** Ignored with POSIX interface: substitute_extended
@@ -157,4 +163,47 @@
 /\[A]{1000000}**/expand,regerror_buffsize=32
 Failed: POSIX code 4: ? * + invalid at offset 1000001
 
+//posix_nosub
+    \=offset=70000
+** Ignored with POSIX interface: offset
+Matched with REG_NOSUB
+
+/(?=(a\K))/
+    a
+Start of matched string is beyond its end - displaying from end to start.
+ 0: a
+ 1: a
+     
+/^d(e)$/posix
+    acdef\=posix_startend=2:4
+ 0: de
+ 1: e
+    acde\=posix_startend=2 
+ 0: de
+ 1: e
+\= Expect no match     
+    acdef
+No match: POSIX code 17: match failed
+    acdef\=posix_startend=2 
+No match: POSIX code 17: match failed
+
+/^a\x{00}b$/posix
+    a\x{00}b\=posix_startend=0:3
+ 0: a\x00b
+
+/"A" 00 "B"/hex
+    A\x{00}B\=posix_startend=0:3
+ 0: A\x00B
+    
+/ABC/use_length 
+    ABC
+ 0: ABC
+
+/a\b(c/literal,posix
+    a\\b(c
+ 0: a\b(c
+
+/a\b(c/literal,posix,dotall
+Failed: POSIX code 16: bad argument at offset 0     
+
 # End of testdata/testinput18
diff --git a/dist2/testdata/testoutput19 b/dist2/testdata/testoutput19
index c4169ca..a4a8b1a 100644
--- a/dist2/testdata/testoutput19
+++ b/dist2/testdata/testoutput19
@@ -18,4 +18,8 @@
     +++\x{c2}
  0: \xc2
     
+/"^AB" 00 "\x{1234}$"/hex,utf
+    AB\x{00}\x{1234}\=posix_startend=0:6 
+ 0: AB\x{00}\x{1234}
+    
 # End of testdata/testinput19
diff --git a/dist2/testdata/testoutput2 b/dist2/testdata/testoutput2
index 01cb193..fcaac8f 100644
--- a/dist2/testdata/testoutput2
+++ b/dist2/testdata/testoutput2
@@ -1,12 +1,12 @@
 # This set of tests is not Perl-compatible. It checks on special features
 # of PCRE2's API, error diagnostics, and the compiled code of some patterns.
-# It also checks the non-Perl syntax that PCRE2 supports (Python, .NET, 
-# Oniguruma). There are also some tests where PCRE2 and Perl differ, 
-# either because PCRE2 can't be compatible, or there is a possible Perl 
+# It also checks the non-Perl syntax that PCRE2 supports (Python, .NET,
+# Oniguruma). There are also some tests where PCRE2 and Perl differ,
+# either because PCRE2 can't be compatible, or there is a possible Perl
 # bug.
 
 # NOTE: This is a non-UTF set of tests. When UTF support is needed, use
-# test 5. 
+# test 5.
 
 #forbid_utf
 #newline_default lf any anycrlf
@@ -72,6 +72,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 3
     abc
  0: abc
@@ -110,6 +111,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 3
     abc
  0: abc
@@ -339,6 +341,7 @@
 /the quick brown fox/I,anchored
 Capturing subpattern count = 0
 Options: anchored
+First code unit = 't'
 Subject length lower bound = 19
     the quick brown fox
  0: the quick brown fox
@@ -351,6 +354,7 @@
 
 /^abc|def/I
 Capturing subpattern count = 0
+Starting code units: a d 
 Subject length lower bound = 3
     abcdef
  0: abc
@@ -472,14 +476,13 @@
     and cattlefoo
 No match
 
-/(?<=a+)b/
-Failed: error 125 at offset 6: lookbehind assertion is not fixed length
+/abc(?<=a+)b/
+Failed: error 125 at offset 3: lookbehind assertion is not fixed length
 
-/(?<=aaa|b{0,3})b/
-Failed: error 125 at offset 14: lookbehind assertion is not fixed length
+/12345(?<=aaa|b{0,3})b/
+Failed: error 125 at offset 5: lookbehind assertion is not fixed length
 
 /(?<!(foo)a\1)bar/
-Failed: error 125 at offset 12: lookbehind assertion is not fixed length
 
 /(?i)abc/I
 Capturing subpattern count = 0
@@ -496,12 +499,14 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = '1'
 Subject length lower bound = 4
 
 /(^b|(?i)^d)/I
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+Starting code units: D b d 
 Subject length lower bound = 1
 
 /(?s).*/I
@@ -539,25 +544,25 @@
 Subject length lower bound = 1
 
 /(a)(?(1)a|b|c)/
-Failed: error 127 at offset 13: conditional group contains more than two branches
+Failed: error 127 at offset 3: conditional group contains more than two branches
 
 /(?(?=a)a|b|c)/
-Failed: error 127 at offset 12: conditional group contains more than two branches
+Failed: error 127 at offset 0: conditional group contains more than two branches
 
 /(?(1a)/
-Failed: error 114 at offset 6: missing closing parenthesis
+Failed: error 124 at offset 4: missing closing parenthesis for condition
 
 /(?(1a))/
-Failed: error 126 at offset 4: malformed number or name after (?(
+Failed: error 124 at offset 4: missing closing parenthesis for condition
 
 /(?(?i))/
-Failed: error 128 at offset 3: assertion expected after (?( or (?(?C)
+Failed: error 128 at offset 2: assertion expected after (?( or (?(?C)
 
 /(?(abc))/
-Failed: error 115 at offset 7: reference to non-existent subpattern
+Failed: error 115 at offset 3: reference to non-existent subpattern
 
 /(?(?<ab))/
-Failed: error 128 at offset 3: assertion expected after (?( or (?(?C)
+Failed: error 128 at offset 2: assertion expected after (?( or (?(?C)
 
 /((?s)blah)\s+\1/I
 Capturing subpattern count = 1
@@ -625,6 +630,7 @@
 Max lookbehind = 1
 Compile options: multiline
 Overall options: anchored multiline
+First code unit = 'a'
 Subject length lower bound = 3
 
 /^abc/Im
@@ -638,6 +644,7 @@
 Capturing subpattern count = 5
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 3
   aaaaabbbbbcccccdef
  0: aaaaabbbbbcccccdef
@@ -715,13 +722,13 @@
 No match
 
 /(?<=ab(c+)d)ef/
-Failed: error 125 at offset 11: lookbehind assertion is not fixed length
+Failed: error 125 at offset 0: lookbehind assertion is not fixed length
 
 /(?<=ab(?<=c+)d)ef/
-Failed: error 125 at offset 12: lookbehind assertion is not fixed length
+Failed: error 125 at offset 6: lookbehind assertion is not fixed length
 
 /(?<=ab(c|de)f)g/
-Failed: error 125 at offset 13: lookbehind assertion is not fixed length
+Failed: error 125 at offset 0: lookbehind assertion is not fixed length
 
 /The next three are in testinput2 because they have variable length branches/
 
@@ -809,13 +816,14 @@
 Max back reference = 1
 Compile options: <none>
 Overall options: anchored
+Starting code units: a 
 Subject length lower bound = 4
 \= Expect no match
     aaaa
 No match
     aaaaaa
 No match
-    
+
 # Perl does not fail these two for the final subjects. Neither did PCRE until
 # release 8.01. The problem is in backtracking into a subpattern that contains
 # a recursive reference to itself. PCRE has now made these into atomic patterns.
@@ -905,7 +913,7 @@
 Failed: error 114 at offset 4: missing closing parenthesis
 
 /(?<%)b/
-Failed: error 124 at offset 3: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 3: subpattern name expected
 
 /a(?{)b/
 Failed: error 111 at offset 3: unrecognized character after (? or (?-
@@ -923,22 +931,22 @@
 Failed: error 111 at offset 3: unrecognized character after (? or (?-
 
 /(?(1?)a|b)/
-Failed: error 126 at offset 4: malformed number or name after (?(
+Failed: error 124 at offset 4: missing closing parenthesis for condition
 
 /[a[:xyz:/
 Failed: error 106 at offset 8: missing terminating ] for character class
 
 /(?<=x+)y/
-Failed: error 125 at offset 6: lookbehind assertion is not fixed length
+Failed: error 125 at offset 0: lookbehind assertion is not fixed length
 
 /a{37,17}/
 Failed: error 104 at offset 7: numbers out of order in {} quantifier
 
 /abc/\
-Failed: error 101 at offset 3: \ at end of pattern
+Failed: error 101 at offset 4: \ at end of pattern
 
 /abc/\i
-Failed: error 101 at offset 3: \ at end of pattern
+Failed: error 101 at offset 4: \ at end of pattern
 
 /(a)bc(d)/I
 Capturing subpattern count = 2
@@ -1005,6 +1013,7 @@
 Capturing subpattern count = 3
 Compile options: <none>
 Overall options: anchored
+Starting code units: a b 
 Subject length lower bound = 4
     adef\=get=1,get=2,get=3,get=4,getall
  0: adef
@@ -1043,6 +1052,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 7
     abc\00def\=copy=0,getall
  0: abc\x00def
@@ -1228,6 +1238,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'i'
 Subject length lower bound = 3
     ississippi
  0: iss
@@ -1287,6 +1298,7 @@
 Contains explicit CR or LF match
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 3
     ab\nab\ncd
  0: ab\x0a
@@ -1777,6 +1789,8 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P 
+  Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 
 Subject length lower bound = 1
 
 /^[[:^alnum:]]/IB
@@ -1790,6 +1804,18 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / : ; < = > 
+  ? @ [ \ ] ^ _ ` { | } ~ \x7f \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 
+  \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 
+  \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 
+  \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 
+  \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 
+  \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 
+  \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 
+  \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 
+  \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff 
 Subject length lower bound = 1
 
 /^[[:alpha:]]/IB
@@ -1803,6 +1829,8 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
+  a b c d e f g h i j k l m n o p q r s t u v w x y z 
 Subject length lower bound = 1
 
 /^[[:^alpha:]]/IB
@@ -1816,6 +1844,19 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 
+  5 6 7 8 9 : ; < = > ? @ [ \ ] ^ _ ` { | } ~ \x7f \x80 \x81 \x82 \x83 \x84 
+  \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 
+  \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 \xa2 
+  \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 
+  \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 
+  \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf 
+  \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde 
+  \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed 
+  \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc 
+  \xfd \xfe \xff 
 Subject length lower bound = 1
 
 /[_[:alpha:]]/I
@@ -1835,6 +1876,12 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 
+  5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y 
+  Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ 
+  \x7f 
 Subject length lower bound = 1
 
 /^[[:^ascii:]]/IB
@@ -1848,6 +1895,15 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a 
+  \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 
+  \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 
+  \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 
+  \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 
+  \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 
+  \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 
+  \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 
+  \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff 
 Subject length lower bound = 1
 
 /^[[:blank:]]/IB
@@ -1861,6 +1917,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x09 \x20 
 Subject length lower bound = 1
 
 /^[[:^blank:]]/IB
@@ -1874,6 +1931,20 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0a \x0b 
+  \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a 
+  \x1b \x1c \x1d \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 
+  : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ 
+  _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 
+  \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f 
+  \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e 
+  \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad 
+  \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc 
+  \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb 
+  \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda 
+  \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 
+  \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 
+  \xf9 \xfa \xfb \xfc \xfd \xfe \xff 
 Subject length lower bound = 1
 
 /[\n\x0b\x0c\x0d[:blank:]]/I
@@ -1893,6 +1964,9 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x7f 
 Subject length lower bound = 1
 
 /^[[:digit:]]/IB
@@ -1906,6 +1980,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: 0 1 2 3 4 5 6 7 8 9 
 Subject length lower bound = 1
 
 /^[[:graph:]]/IB
@@ -1919,6 +1994,9 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : 
+  ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ 
+  ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ 
 Subject length lower bound = 1
 
 /^[[:lower:]]/IB
@@ -1932,6 +2010,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: a b c d e f g h i j k l m n o p q r s t u v w x y z 
 Subject length lower bound = 1
 
 /^[[:print:]]/IB
@@ -1945,6 +2024,9 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 
+  9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] 
+  ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ 
 Subject length lower bound = 1
 
 /^[[:punct:]]/IB
@@ -1958,6 +2040,8 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ 
+  _ ` { | } ~ 
 Subject length lower bound = 1
 
 /^[[:space:]]/IB
@@ -1971,6 +2055,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x09 \x0a \x0b \x0c \x0d \x20 
 Subject length lower bound = 1
 
 /^[[:upper:]]/IB
@@ -1984,6 +2069,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
 Subject length lower bound = 1
 
 /^[[:xdigit:]]/IB
@@ -1997,6 +2083,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f 
 Subject length lower bound = 1
 
 /^[[:word:]]/IB
@@ -2010,6 +2097,8 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P 
+  Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z 
 Subject length lower bound = 1
 
 /^[[:^cntrl:]]/IB
@@ -2023,6 +2112,18 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 
+  9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] 
+  ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x80 \x81 
+  \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 
+  \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f 
+  \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae 
+  \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd 
+  \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc 
+  \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb 
+  \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea 
+  \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 
+  \xfa \xfb \xfc \xfd \xfe \xff 
 Subject length lower bound = 1
 
 /^[12[:^digit:]]/IB
@@ -2036,6 +2137,20 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 1 2 : ; < 
+  = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a 
+  b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 
+  \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 
+  \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 
+  \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf 
+  \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe 
+  \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd 
+  \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc 
+  \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb 
+  \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa 
+  \xfb \xfc \xfd \xfe \xff 
 Subject length lower bound = 1
 
 /^[[:^blank:]]/IB
@@ -2049,6 +2164,20 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0a \x0b 
+  \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a 
+  \x1b \x1c \x1d \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 
+  : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ 
+  _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 
+  \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f 
+  \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e 
+  \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad 
+  \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc 
+  \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb 
+  \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda 
+  \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 
+  \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 
+  \xf9 \xfa \xfb \xfc \xfd \xfe \xff 
 Subject length lower bound = 1
 
 /[01[:alpha:]%]/IB
@@ -2115,7 +2244,7 @@
 Failed: error 108 at offset 9: range out of order in character class
 
 /^(?(0)f|b)oo/I
-Failed: error 135 at offset 6: invalid condition (?(0)
+Failed: error 115 at offset 5: reference to non-existent subpattern
 
 # This one's here because of the large output vector needed
 
@@ -2123,7 +2252,7 @@
 Capturing subpattern count = 271
 Max back reference = 270
 Starting code units: 0 1 2 3 4 5 6 7 8 9 
-Subject length lower bound = 272
+Subject length lower bound = 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC\=ovector=300
  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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC
  1: 1 
@@ -2419,6 +2548,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 1
     aba
  0: aba
@@ -2429,6 +2559,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2439,6 +2570,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2449,6 +2581,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2459,6 +2592,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2468,6 +2602,7 @@
 Capturing subpattern count = 3
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2479,6 +2614,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2489,6 +2625,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2498,6 +2635,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbbaa
  0: aabbbaa
@@ -2507,6 +2645,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbbaa
  0: aabbbaa
@@ -2516,6 +2655,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbaa
  0: aabbaa
@@ -2525,6 +2665,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbbaa
  0: aabbbaa
@@ -2534,6 +2675,7 @@
 Capturing subpattern count = 3
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbbaa
  0: aabbbaa
@@ -2545,6 +2687,7 @@
 Capturing subpattern count = 3
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
     aabbbbaa
  0: aabbbbaa
@@ -3053,6 +3196,7 @@
 Capturing subpattern count = 5
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 3
 
 /^x(?U)a+b/IB
@@ -3068,6 +3212,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'x'
 Last code unit = 'b'
 Subject length lower bound = 3
 
@@ -3086,6 +3231,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'x'
 Last code unit = 'b'
 Subject length lower bound = 3
 
@@ -3099,19 +3245,19 @@
 Failed: error 112 at offset 0: POSIX named classes are supported only within a class
 
 /\l/I
-Failed: error 137 at offset 1: PCRE does not support \L, \l, \N{name}, \U, or \u
+Failed: error 137 at offset 2: PCRE does not support \L, \l, \N{name}, \U, or \u
 
 /\L/I
-Failed: error 137 at offset 1: PCRE does not support \L, \l, \N{name}, \U, or \u
+Failed: error 137 at offset 2: PCRE does not support \L, \l, \N{name}, \U, or \u
 
 /\N{name}/I
-Failed: error 137 at offset 1: PCRE does not support \L, \l, \N{name}, \U, or \u
+Failed: error 137 at offset 2: PCRE does not support \L, \l, \N{name}, \U, or \u
 
 /\u/I
-Failed: error 137 at offset 1: PCRE does not support \L, \l, \N{name}, \U, or \u
+Failed: error 137 at offset 2: PCRE does not support \L, \l, \N{name}, \U, or \u
 
 /\U/I
-Failed: error 137 at offset 1: PCRE does not support \L, \l, \N{name}, \U, or \u
+Failed: error 137 at offset 2: PCRE does not support \L, \l, \N{name}, \U, or \u
 
 /a{1,3}b/ungreedy
     ab
@@ -3518,12 +3664,10 @@
  1: abc
     123abcdef\=callout_capture
 Callout 0: last capture = 1
- 0: <unset>
  1: abc
 --->123abcdef
        ^  ^       d
 Callout 1: last capture = 1
- 0: <unset>
  1: abc
 --->123abcdef
        ^    ^     f
@@ -3545,25 +3689,25 @@
 Subject length lower bound = 0
     abcabcabc
 --->abcabcabc
-  0 ^             (abc(?C1))*
-  1 ^  ^          )
-  1 ^     ^       )
-  1 ^        ^    )
+  0 ^             (
+  1 ^  ^          )*
+  1 ^     ^       )*
+  1 ^        ^    )*
  0: abcabcabc
  1: abc
-    abcabc\=callout_fail=1:3
+    abcabc\=callout_fail=1:4
 --->abcabc
-  0 ^          (abc(?C1))*
-  1 ^  ^       )
-  1 ^     ^    )
+  0 ^          (
+  1 ^  ^       )*
+  1 ^     ^    )*
  0: abcabc
  1: abc
-    abcabcabc\=callout_fail=1:3
+    abcabcabc\=callout_fail=1:4
 --->abcabcabc
-  0 ^             (abc(?C1))*
-  1 ^  ^          )
-  1 ^     ^       )
-  1 ^        ^    )
+  0 ^             (
+  1 ^  ^          )*
+  1 ^     ^       )*
+  1 ^        ^    )*
  0: abcabc
  1: abc
 
@@ -3573,38 +3717,32 @@
 Subject length lower bound = 0
     123\=callout_capture
 Callout 0: last capture = 0
- 0: <unset>
 --->123
-    ^  ^    )
+    ^  ^    )*
  0: 123
  1: 123
     123456\=callout_capture
 Callout 0: last capture = 0
- 0: <unset>
 --->123456
-    ^  ^       )
+    ^  ^       )*
 Callout 0: last capture = 1
- 0: <unset>
  1: 123
 --->123456
-    ^     ^    )
+    ^     ^    )*
  0: 123456
  1: 456
     123456789\=callout_capture
 Callout 0: last capture = 0
- 0: <unset>
 --->123456789
-    ^  ^          )
+    ^  ^          )*
 Callout 0: last capture = 1
- 0: <unset>
  1: 123
 --->123456789
-    ^     ^       )
+    ^     ^       )*
 Callout 0: last capture = 1
- 0: <unset>
  1: 456
 --->123456789
-    ^        ^    )
+    ^        ^    )*
  0: 123456789
  1: 789
 
@@ -3614,13 +3752,11 @@
 Subject length lower bound = 4
     xyzabc\=callout_capture
 Callout 0: last capture = 2
- 0: <unset>
  1: <unset>
  2: xyz
 --->xyzabc
     ^  ^       p
 Callout 1: last capture = 0
- 0: <unset>
 --->xyzabc
     ^          x
  0: xyzabc
@@ -3633,14 +3769,12 @@
 Subject length lower bound = 5
     Xxyzabc\=callout_capture
 Callout 0: last capture = 3
- 0: <unset>
  1: X
  2: <unset>
  3: xyz
 --->Xxyzabc
     ^   ^       p
 Callout 1: last capture = 1
- 0: <unset>
  1: X
 --->Xxyzabc
     ^^          x
@@ -3655,7 +3789,6 @@
 Subject length lower bound = 6
     abcdef\=callout_capture
 Callout 0: last capture = 1
- 0: <unset>
  1: abc
 --->abcdef
     ^          a
@@ -3669,12 +3802,10 @@
 Subject length lower bound = 6
     abcxyz\=callout_capture
 Callout 1: last capture = 1
- 0: <unset>
  1: abc
 --->abcxyz
     ^  ^       d
 Callout 2: last capture = 0
- 0: <unset>
 --->abcxyz
     ^          a
  0: abcxyz
@@ -3687,7 +3818,6 @@
 Subject length lower bound = 3
    abcxyz\=callout_capture
 Callout 0: last capture = 1
- 0: <unset>
  1: abc
 --->abcxyz
        ^       )
@@ -3702,7 +3832,7 @@
 \= Expect no match
     abbbbbccc\=callout_data=1
 --->abbbbbccc
-  1 ^        ^    
+  1 ^        ^    End of pattern
 Callout data = 1
 No match
 
@@ -3714,21 +3844,21 @@
 \= Expect no match
     abbbbbccc\=callout_data=1
 --->abbbbbccc
-  1 ^ ^           
+  1 ^ ^           End of pattern
 Callout data = 1
-  1 ^  ^          
+  1 ^  ^          End of pattern
 Callout data = 1
-  1 ^   ^         
+  1 ^   ^         End of pattern
 Callout data = 1
-  1 ^    ^        
+  1 ^    ^        End of pattern
 Callout data = 1
-  1 ^     ^       
+  1 ^     ^       End of pattern
 Callout data = 1
-  1 ^      ^      
+  1 ^      ^      End of pattern
 Callout data = 1
-  1 ^       ^     
+  1 ^       ^     End of pattern
 Callout data = 1
-  1 ^        ^    
+  1 ^        ^    End of pattern
 Callout data = 1
 No match
 
@@ -3742,6 +3872,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 3
 
 /(?C)a|b/I
@@ -3749,6 +3880,16 @@
 Starting code units: a b 
 Subject length lower bound = 1
 
+/a|(b)(?C)/I
+Capturing subpattern count = 1
+Starting code units: a b 
+Subject length lower bound = 1
+    b
+--->b
+  0 ^^    End of pattern
+ 0: b
+ 1: b
+
 /x(ab|(bc|(de|(?R))))/I
 Capturing subpattern count = 3
 First code unit = 'x'
@@ -3802,6 +3943,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = '>'
 Last code unit = '<'
 Subject length lower bound = 10
    >abc>123<xyz<
@@ -3835,7 +3977,7 @@
         Bra
         CBra 1
         a
-        Once
+        SBra
         Recurse
         KetRmax
         b
@@ -3852,6 +3994,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+Starting code units: ( - 0 1 2 3 4 5 6 7 8 9 
 Subject length lower bound = 1
     12
  0: 12
@@ -3871,6 +4014,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+First code unit = 'x'
 Subject length lower bound = 3
     xyz
  0: xyz
@@ -3930,6 +4074,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 9
     abcdefabc
  0: abcdefabc
@@ -3939,7 +4084,8 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
-Subject length lower bound = 3
+Starting code units: a b c 
+Subject length lower bound = 2
     a=a
  0: a=a
  1: a
@@ -3954,6 +4100,7 @@
 Capturing subpattern count = 2
 Compile options: <none>
 Overall options: anchored
+Starting code units: a b c 
 Subject length lower bound = 2
     a=a
  0: a=a
@@ -4263,7 +4410,7 @@
 Callout data = 1
  0: ab
  1: ab
-\= Expect no match    
+\= Expect no match
    aaabbb\=callout_data=-1
 --->aaabbb
   1 ^  ^       b
@@ -4355,10 +4502,10 @@
   C aa (2) A (group 2)
 
 /(?P<x>eks)(?P<x>eccs)/I
-Failed: error 143 at offset 15: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
+Failed: error 143 at offset 16: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
 
 /(?P<abc>abc(?P<def>def)(?P<abc>xyz))/I
-Failed: error 143 at offset 30: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
+Failed: error 143 at offset 31: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
 
 "\[((?P<elem>\d+)(,(?P>elem))*)\]"I
 Capturing subpattern count = 3
@@ -4581,7 +4728,7 @@
  +2 ^ ^       c
  +3 ^  ^      d
  +4 ^   ^     e
- +5 ^    ^    
+ +5 ^    ^    End of pattern
  0: abcde
 \= Expect no match
   abcdfe
@@ -4613,13 +4760,13 @@
 --->ab
  +0 ^      a*
  +2 ^^     b
- +3 ^ ^    
+ +3 ^ ^    End of pattern
  0: ab
   aaaab
 --->aaaab
  +0 ^         a*
  +2 ^   ^     b
- +3 ^    ^    
+ +3 ^    ^    End of pattern
  0: aaaab
   aaaacb
 --->aaaacb
@@ -4633,7 +4780,7 @@
  +2    ^^      b
  +0      ^     a*
  +2      ^     b
- +3      ^^    
+ +3      ^^    End of pattern
  0: b
 
 /a*b/IB,auto_callout
@@ -4656,13 +4803,13 @@
 --->ab
  +0 ^      a*
  +2 ^^     b
- +3 ^ ^    
+ +3 ^ ^    End of pattern
  0: ab
   aaaab
 --->aaaab
  +0 ^         a*
  +2 ^   ^     b
- +3 ^    ^    
+ +3 ^    ^    End of pattern
  0: aaaab
   aaaacb
 --->aaaacb
@@ -4676,7 +4823,7 @@
  +2    ^^      b
  +0      ^     a*
  +2      ^     b
- +3      ^^    
+ +3      ^^    End of pattern
  0: b
 
 /a+b/IB,auto_callout
@@ -4699,15 +4846,15 @@
 --->ab
  +0 ^      a+
  +2 ^^     b
- +3 ^ ^    
+ +3 ^ ^    End of pattern
  0: ab
   aaaab
 --->aaaab
  +0 ^         a+
  +2 ^   ^     b
- +3 ^    ^    
+ +3 ^    ^    End of pattern
  0: aaaab
-\= Expect no match 
+\= Expect no match
   aaaacb
 --->aaaacb
  +0 ^          a+
@@ -4723,7 +4870,7 @@
 /(abc|def)x/IB,auto_callout
 ------------------------------------------------------------------
         Bra
-        Callout 255 0 9
+        Callout 255 0 1
         CBra 1
         Callout 255 1 1
         a
@@ -4731,7 +4878,7 @@
         b
         Callout 255 3 1
         c
-        Callout 255 4 0
+        Callout 255 4 1
         Alt
         Callout 255 5 1
         d
@@ -4739,7 +4886,7 @@
         e
         Callout 255 7 1
         f
-        Callout 255 8 0
+        Callout 255 8 1
         Ket
         Callout 255 9 1
         x
@@ -4754,38 +4901,38 @@
 Subject length lower bound = 4
   abcx
 --->abcx
- +0 ^        (abc|def)
+ +0 ^        (
  +1 ^        a
  +2 ^^       b
  +3 ^ ^      c
  +4 ^  ^     |
  +9 ^  ^     x
-+10 ^   ^    
++10 ^   ^    End of pattern
  0: abcx
  1: abc
   defx
 --->defx
- +0 ^        (abc|def)
+ +0 ^        (
  +1 ^        a
  +5 ^        d
  +6 ^^       e
  +7 ^ ^      f
  +8 ^  ^     )
  +9 ^  ^     x
-+10 ^   ^    
++10 ^   ^    End of pattern
  0: defx
  1: def
-\= Expect no match 
+\= Expect no match
   abcdefzx
 --->abcdefzx
- +0 ^            (abc|def)
+ +0 ^            (
  +1 ^            a
  +2 ^^           b
  +3 ^ ^          c
  +4 ^  ^         |
  +9 ^  ^         x
  +5 ^            d
- +0    ^         (abc|def)
+ +0    ^         (
  +1    ^         a
  +5    ^         d
  +6    ^^        e
@@ -4797,7 +4944,7 @@
 /(abc|def)x/IB,auto_callout
 ------------------------------------------------------------------
         Bra
-        Callout 255 0 9
+        Callout 255 0 1
         CBra 1
         Callout 255 1 1
         a
@@ -4805,7 +4952,7 @@
         b
         Callout 255 3 1
         c
-        Callout 255 4 0
+        Callout 255 4 1
         Alt
         Callout 255 5 1
         d
@@ -4813,7 +4960,7 @@
         e
         Callout 255 7 1
         f
-        Callout 255 8 0
+        Callout 255 8 1
         Ket
         Callout 255 9 1
         x
@@ -4828,38 +4975,38 @@
 Subject length lower bound = 4
   abcx
 --->abcx
- +0 ^        (abc|def)
+ +0 ^        (
  +1 ^        a
  +2 ^^       b
  +3 ^ ^      c
  +4 ^  ^     |
  +9 ^  ^     x
-+10 ^   ^    
++10 ^   ^    End of pattern
  0: abcx
  1: abc
   defx
 --->defx
- +0 ^        (abc|def)
+ +0 ^        (
  +1 ^        a
  +5 ^        d
  +6 ^^       e
  +7 ^ ^      f
  +8 ^  ^     )
  +9 ^  ^     x
-+10 ^   ^    
++10 ^   ^    End of pattern
  0: defx
  1: def
-\= Expect no match 
+\= Expect no match
   abcdefzx
 --->abcdefzx
- +0 ^            (abc|def)
+ +0 ^            (
  +1 ^            a
  +2 ^^           b
  +3 ^ ^          c
  +4 ^  ^         |
  +9 ^  ^         x
  +5 ^            d
- +0    ^         (abc|def)
+ +0    ^         (
  +1    ^         a
  +5    ^         d
  +6    ^^        e
@@ -4875,7 +5022,7 @@
 Subject length lower bound = 6
   ababab
 --->ababab
- +0 ^          (ab|cd){3,4}
+ +0 ^          (
  +1 ^          a
  +2 ^^         b
  +3 ^ ^        |
@@ -4887,55 +5034,55 @@
  +3 ^     ^    |
  +1 ^     ^    a
  +4 ^     ^    c
-+12 ^     ^    
++12 ^     ^    End of pattern
  0: ababab
  1: ab
   abcdabcd
 --->abcdabcd
- +0 ^            (ab|cd){3,4}
+ +0 ^            (
  +1 ^            a
  +2 ^^           b
  +3 ^ ^          |
  +1 ^ ^          a
  +4 ^ ^          c
  +5 ^  ^         d
- +6 ^   ^        )
+ +6 ^   ^        ){3,4}
  +1 ^   ^        a
  +2 ^    ^       b
  +3 ^     ^      |
  +1 ^     ^      a
  +4 ^     ^      c
  +5 ^      ^     d
- +6 ^       ^    )
-+12 ^       ^    
+ +6 ^       ^    ){3,4}
++12 ^       ^    End of pattern
  0: abcdabcd
  1: cd
   abcdcdcdcdcd
 --->abcdcdcdcdcd
- +0 ^                (ab|cd){3,4}
+ +0 ^                (
  +1 ^                a
  +2 ^^               b
  +3 ^ ^              |
  +1 ^ ^              a
  +4 ^ ^              c
  +5 ^  ^             d
- +6 ^   ^            )
+ +6 ^   ^            ){3,4}
  +1 ^   ^            a
  +4 ^   ^            c
  +5 ^    ^           d
- +6 ^     ^          )
+ +6 ^     ^          ){3,4}
  +1 ^     ^          a
  +4 ^     ^          c
  +5 ^      ^         d
- +6 ^       ^        )
-+12 ^       ^        
+ +6 ^       ^        ){3,4}
++12 ^       ^        End of pattern
  0: abcdcdcd
  1: cd
 
 /([ab]{,4}c|xy)/IB,auto_callout
 ------------------------------------------------------------------
         Bra
-        Callout 255 0 14
+        Callout 255 0 1
         CBra 1
         Callout 255 1 4
         [ab]
@@ -4949,13 +5096,13 @@
         }
         Callout 255 9 1
         c
-        Callout 255 10 0
+        Callout 255 10 1
         Alt
         Callout 255 11 1
         x
         Callout 255 12 1
         y
-        Callout 255 13 0
+        Callout 255 13 1
         Ket
         Callout 255 14 0
         Ket
@@ -4965,18 +5112,18 @@
 Options: auto_callout
 Starting code units: a b x 
 Subject length lower bound = 2
-\= Expect no match 
+\= Expect no match
     Note: that { does NOT introduce a quantifier
 --->Note: that { does NOT introduce a quantifier
- +0         ^                                        ([ab]{,4}c|xy)
+ +0         ^                                        (
  +1         ^                                        [ab]
  +5         ^^                                       {
 +11         ^                                        x
- +0                                 ^                ([ab]{,4}c|xy)
+ +0                                 ^                (
  +1                                 ^                [ab]
  +5                                 ^^               {
 +11                                 ^                x
- +0                                     ^            ([ab]{,4}c|xy)
+ +0                                     ^            (
  +1                                     ^            [ab]
  +5                                     ^^           {
 +11                                     ^            x
@@ -4985,7 +5132,7 @@
 /([ab]{,4}c|xy)/IB,auto_callout
 ------------------------------------------------------------------
         Bra
-        Callout 255 0 14
+        Callout 255 0 1
         CBra 1
         Callout 255 1 4
         [ab]
@@ -4999,13 +5146,13 @@
         }
         Callout 255 9 1
         c
-        Callout 255 10 0
+        Callout 255 10 1
         Alt
         Callout 255 11 1
         x
         Callout 255 12 1
         y
-        Callout 255 13 0
+        Callout 255 13 1
         Ket
         Callout 255 14 0
         Ket
@@ -5015,18 +5162,18 @@
 Options: auto_callout
 Starting code units: a b x 
 Subject length lower bound = 2
-\= Expect no match 
+\= Expect no match
     Note: that { does NOT introduce a quantifier
 --->Note: that { does NOT introduce a quantifier
- +0         ^                                        ([ab]{,4}c|xy)
+ +0         ^                                        (
  +1         ^                                        [ab]
  +5         ^^                                       {
 +11         ^                                        x
- +0                                 ^                ([ab]{,4}c|xy)
+ +0                                 ^                (
  +1                                 ^                [ab]
  +5                                 ^^               {
 +11                                 ^                x
- +0                                     ^            ([ab]{,4}c|xy)
+ +0                                     ^            (
  +1                                     ^            [ab]
  +5                                     ^^           {
 +11                                     ^            x
@@ -5035,58 +5182,58 @@
 /([ab]{1,4}c|xy){4,5}?123/IB,auto_callout
 ------------------------------------------------------------------
         Bra
-        Callout 255 0 21
+        Callout 255 0 1
         CBra 1
         Callout 255 1 9
         [ab]{1,4}+
         Callout 255 10 1
         c
-        Callout 255 11 0
+        Callout 255 11 1
         Alt
         Callout 255 12 1
         x
         Callout 255 13 1
         y
-        Callout 255 14 0
+        Callout 255 14 7
         Ket
         CBra 1
         Callout 255 1 9
         [ab]{1,4}+
         Callout 255 10 1
         c
-        Callout 255 11 0
+        Callout 255 11 1
         Alt
         Callout 255 12 1
         x
         Callout 255 13 1
         y
-        Callout 255 14 0
+        Callout 255 14 7
         Ket
         CBra 1
         Callout 255 1 9
         [ab]{1,4}+
         Callout 255 10 1
         c
-        Callout 255 11 0
+        Callout 255 11 1
         Alt
         Callout 255 12 1
         x
         Callout 255 13 1
         y
-        Callout 255 14 0
+        Callout 255 14 7
         Ket
         CBra 1
         Callout 255 1 9
         [ab]{1,4}+
         Callout 255 10 1
         c
-        Callout 255 11 0
+        Callout 255 11 1
         Alt
         Callout 255 12 1
         x
         Callout 255 13 1
         y
-        Callout 255 14 0
+        Callout 255 14 7
         Ket
         Braminzero
         CBra 1
@@ -5094,13 +5241,13 @@
         [ab]{1,4}+
         Callout 255 10 1
         c
-        Callout 255 11 0
+        Callout 255 11 1
         Alt
         Callout 255 12 1
         x
         Callout 255 13 1
         y
-        Callout 255 14 0
+        Callout 255 14 7
         Ket
         Callout 255 21 1
         1
@@ -5119,7 +5266,7 @@
 Subject length lower bound = 11
     aacaacaacaacaac123
 --->aacaacaacaacaac123
- +0 ^                      ([ab]{1,4}c|xy){4,5}?
+ +0 ^                      (
  +1 ^                      [ab]{1,4}
 +10 ^ ^                    c
 +11 ^  ^                   |
@@ -5139,7 +5286,7 @@
 +21 ^              ^       1
 +22 ^               ^      2
 +23 ^                ^     3
-+24 ^                 ^    
++24 ^                 ^    End of pattern
  0: aacaacaacaacaac123
  1: aac
 
@@ -5190,6 +5337,7 @@
 Capturing subpattern count = 3
 Compile options: <none>
 Overall options: anchored
+Starting code units: 0 1 2 3 4 5 6 7 8 9 
 Last code unit = '/'
 Subject length lower bound = 6
     13/05/04\=ps
@@ -5287,6 +5435,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: 0 1 2 3 4 5 6 7 8 9 
 Last code unit = 'X'
 Subject length lower bound = 4
     1\=ps
@@ -5651,7 +5800,7 @@
 Subject length lower bound = 1
 
 /^((?P<A>a1)|(?P<A>a2)b)/I
-Failed: error 143 at offset 17: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
+Failed: error 143 at offset 18: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
 
 /^((?P<A>a1)|(?P<A>a2)b)/I,dupnames
 Capturing subpattern count = 3
@@ -5660,6 +5809,7 @@
   A   3
 Compile options: dupnames
 Overall options: anchored dupnames
+First code unit = 'a'
 Subject length lower bound = 2
     a1b\=copy=A
  0: a1
@@ -5679,7 +5829,7 @@
 Number not found for group 'Z'
 Copy substring 'Z' failed (-49): unknown substring
   C a1 (2) A (non-unique)
-    
+
 /(?|(?<a>)(?<b>)(?<a>)|(?<a>)(?<b>)(?<a>))/I,dupnames
 Capturing subpattern count = 3
 Named capturing subpatterns:
@@ -5697,6 +5847,7 @@
   A   2
 Compile options: dupnames
 Overall options: anchored dupnames
+First code unit = 'a'
 Subject length lower bound = 2
     ab\=copy=A
  0: ab
@@ -5710,6 +5861,7 @@
   A   1
   A   2
 Options: dupnames
+Starting code units: a c 
 Subject length lower bound = 2
     ab\=copy=A
  0: ab
@@ -5728,6 +5880,7 @@
   A   3
   A   4
 Options: dupnames
+Starting code units: a c 
 Subject length lower bound = 2
     cdefgh\=copy=A
  0: cdefgh
@@ -5744,6 +5897,7 @@
   A   3
 Compile options: dupnames
 Overall options: anchored dupnames
+First code unit = 'a'
 Subject length lower bound = 2
     a1b\=get=A
  0: a1
@@ -5771,6 +5925,7 @@
   A   2
 Compile options: dupnames
 Overall options: anchored dupnames
+First code unit = 'a'
 Subject length lower bound = 2
     ab\=get=A
  0: ab
@@ -5784,6 +5939,7 @@
   A   1
   A   2
 Options: dupnames
+Starting code units: a c 
 Subject length lower bound = 2
     ab\=get=A
  0: ab
@@ -5802,6 +5958,7 @@
   A   3
   A   4
 Options: dupnames
+Starting code units: a c 
 Subject length lower bound = 2
     cdefgh\=get=A
  0: cdefgh
@@ -5819,6 +5976,7 @@
 Compile options: <none>
 Overall options: anchored
 Duplicate name status changes
+First code unit = 'a'
 Subject length lower bound = 2
     a1b\=copy=A
  0: a1
@@ -5833,7 +5991,7 @@
   C a2 (2) A (non-unique)
 
 /^(?P<A>a) (?J:(?P<B>b)(?P<B>c)) (?P<A>d)/I
-Failed: error 143 at offset 37: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
+Failed: error 143 at offset 38: two named subpatterns have the same name (PCRE2_DUPNAMES not set)
 
 # In this next test, J is not set at the outer level; consequently it isn't set
 # in the pattern's options; consequently pcre2_substring_get_byname() produces
@@ -5849,6 +6007,7 @@
 Compile options: <none>
 Overall options: anchored
 Duplicate name status changes
+First code unit = 'a'
 Subject length lower bound = 6
     a bc d\=copy=A,copy=B,copy=C
  0: a bc d
@@ -5889,10 +6048,10 @@
  1: X
 
 /(?:(?(2y)a|b)(X))+/I
-Failed: error 126 at offset 7: malformed number or name after (?(
+Failed: error 124 at offset 7: missing closing parenthesis for condition
 
 /(?:(?(ZA)a|b)(?P<ZZ>X))+/I
-Failed: error 115 at offset 9: reference to non-existent subpattern
+Failed: error 115 at offset 6: reference to non-existent subpattern
 
 /(?:(?(ZZ)a|b)(?(ZZ)a|b)(?P<ZZ>X))+/I
 Capturing subpattern count = 1
@@ -5998,7 +6157,7 @@
 No match
     xyz\rabclf
 No match
-    
+
 /^abc/Im,newline=cr
 Capturing subpattern count = 0
 Options: multiline
@@ -6250,6 +6409,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: a b 
 Last code unit = 'b'
 Subject length lower bound = 2
 
@@ -6266,6 +6426,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: a b 
 Last code unit = 'b'
 Subject length lower bound = 2
 
@@ -6282,6 +6443,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+Starting code units: a b 
 Last code unit = 'b'
 Subject length lower bound = 2
 
@@ -6298,6 +6460,7 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Last code unit = 'A'
 Subject length lower bound = 3
     aaaA5
@@ -6319,6 +6482,7 @@
 Capturing subpattern count = 0
 Compile options: caseless
 Overall options: anchored caseless
+Starting code units: A a 
 Last code unit = 'A' (caseless)
 Subject length lower bound = 2
     aaaA5
@@ -7023,7 +7187,7 @@
 No match
 
 /^(?P>abc)(?<abcd>xxx)/
-Failed: error 115 at offset 8: reference to non-existent subpattern
+Failed: error 115 at offset 5: reference to non-existent subpattern
 
 /^(?P>abc)(?<abc>x|y)/
     xx
@@ -7283,13 +7447,13 @@
 No match
 
 /(?(<bc))/
-Failed: error 126 at offset 6: malformed number or name after (?(
+Failed: error 142 at offset 6: syntax error in subpattern name (missing terminator)
 
 /(?(''))/
-Failed: error 128 at offset 4: assertion expected after (?( or (?(?C)
+Failed: error 162 at offset 4: subpattern name expected
 
 /(?('R')stuff)/
-Failed: error 115 at offset 7: reference to non-existent subpattern
+Failed: error 115 at offset 4: reference to non-existent subpattern
 
 /((abc (?(R) (?(R1)1) (?(R2)2) X  |  (?1)  (?2)   (?R) ))) /x
     abcabc1Xabc2XabcXabcabc
@@ -7304,10 +7468,10 @@
  2: abcabc1Xabc2XabcX
 
 /(?<A> (?'B' abc (?(R) (?(R&C)1) (?(R&B)2) X  |  (?1)  (?2)   (?R) ))) /x
-Failed: error 115 at offset 29: reference to non-existent subpattern
+Failed: error 115 at offset 27: reference to non-existent subpattern
 
 /^(?(DEFINE) abc | xyz ) /x
-Failed: error 154 at offset 22: DEFINE group contains more than one branch
+Failed: error 154 at offset 4: DEFINE group contains more than one branch
 
 /(?(DEFINE) abc) xyz/Ix
 Capturing subpattern count = 0
@@ -7513,19 +7677,19 @@
 No match
 
 /^(a)\g-2/
-Failed: error 115 at offset 7: reference to non-existent subpattern
+Failed: error 115 at offset 8: reference to non-existent subpattern
 
 /^(a)\g/
-Failed: error 158 at offset 5: a numbered reference must not be zero
+Failed: error 157 at offset 6: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
 
 /^(a)\g{0}/
-Failed: error 158 at offset 8: a numbered reference must not be zero
+Failed: error 115 at offset 9: reference to non-existent subpattern
 
 /^(a)\g{3/
-Failed: error 157 at offset 8: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
+Failed: error 157 at offset 6: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
 
 /^(a)\g{aa}/
-Failed: error 115 at offset 9: reference to non-existent subpattern
+Failed: error 115 at offset 7: reference to non-existent subpattern
 
 /^a.b/newline=lf
     a\rb
@@ -7568,13 +7732,13 @@
  0: \x0d\x0afoo
     \nfoo
  0: \x0afoo
-    
+
 /^$/gm,newline=any
     abc\r\rxyz
  0: 
-    abc\n\rxyz  
+    abc\n\rxyz
  0: 
-\= Expect no match 
+\= Expect no match
     abc\r\nxyz
 No match
 
@@ -7589,7 +7753,7 @@
  0+ \x0d\x0a
  0: \x0d\x0a
  0+ 
-    
+
 /(?m)$/g,newline=any,aftertext
     abc\r\n\r\n
  0: 
@@ -7609,7 +7773,7 @@
 /^X/m
     XABC
  0: X
-\= Expect no match 
+\= Expect no match
     XABC\=notbol
 No match
 
@@ -7644,17 +7808,17 @@
  0: xyabcabc
  1: abc
 \= Expect no match
-    xyabc  
+    xyabc
 No match
-    
+
 /x(?-0)y/
-Failed: error 158 at offset 5: a numbered reference must not be zero
+Failed: error 126 at offset 5: a relative value of zero is not allowed
 
 /x(?-1)y/
 Failed: error 115 at offset 5: reference to non-existent subpattern
 
 /x(?+0)y/
-Failed: error 158 at offset 5: a numbered reference must not be zero
+Failed: error 126 at offset 5: a relative value of zero is not allowed
 
 /x(?+1)y/
 Failed: error 115 at offset 5: reference to non-existent subpattern
@@ -7682,9 +7846,9 @@
     Y
  0: Y
 \= Expect no match
-    abcY   
+    abcY
 No match
-    
+
 /^((?(+1)X|Y)(abc))+/B
 ------------------------------------------------------------------
         Bra
@@ -7712,11 +7876,11 @@
  1: Xabc
  2: abc
 \= Expect no match
-    XabcXabc  
+    XabcXabc
 No match
 
 /(?(-1)a)/B
-Failed: error 115 at offset 6: reference to non-existent subpattern
+Failed: error 115 at offset 5: reference to non-existent subpattern
 
 /((?(-1)a))/B
 ------------------------------------------------------------------
@@ -7732,7 +7896,7 @@
 ------------------------------------------------------------------
 
 /((?(-2)a))/B
-Failed: error 115 at offset 7: reference to non-existent subpattern
+Failed: error 115 at offset 6: reference to non-existent subpattern
 
 /^(?(+1)X|Y)(.)/B
 ------------------------------------------------------------------
@@ -7758,11 +7922,11 @@
     tom-tom
  0: tom-tom
  1: tom
-    bon-bon 
+    bon-bon
  0: bon-bon
  1: bon
 \= Expect no match
-    tom-bon  
+    tom-bon
 No match
 
 /\g{A/
@@ -7786,7 +7950,7 @@
    >abc<
  0: abc
  1: abc
-   >xyz< 
+   >xyz<
  0: xyz
  1: xyz
 
@@ -7816,7 +7980,7 @@
  1: x
  2: abc
  3: x
-    xxyzx 
+    xxyzx
  0: xxyzx
  1: x
  2: xyz
@@ -7852,7 +8016,7 @@
  2: abc
  3: pqr
  4: x
-    xxyzx 
+    xxyzx
  0: xxyzx
  1: x
  2: xyz
@@ -7870,7 +8034,7 @@
 \= Expect no match
     XXXX
 No match
-    
+
 /\H+\hY/B
 ------------------------------------------------------------------
         Bra
@@ -7880,7 +8044,7 @@
         Ket
         End
 ------------------------------------------------------------------
-    XXXX Y 
+    XXXX Y
  0: XXXX Y
 
 /\H+ Y/B
@@ -8107,7 +8271,7 @@
  +3 ^ ^        (*FAIL)
  +3 ^^         (*FAIL)
 No match
-    
+
 /a+b?c+(*FAIL)/auto_callout
 \= Expect no match
     aaabccc
@@ -8171,7 +8335,7 @@
 +15 ^     ^     (*FAIL)
 +15 ^    ^      (*FAIL)
 No match
-    
+
 /a+b?(*SKIP)c+(*FAIL)/auto_callout
 \= Expect no match
     aaabcccaaabccc
@@ -8218,15 +8382,15 @@
 +13   ^   ^     (*FAIL)
 +13   ^  ^      (*FAIL)
 No match
-    
+
 /a(*MARK)b/
 Failed: error 166 at offset 7: (*MARK) must have an argument
 
 /(?i:A{1,}\6666666666)/
-Failed: error 161 at offset 19: number is too big
+Failed: error 161 at offset 19: group number is too big
 
 /\g6666666666/
-Failed: error 161 at offset 11: number is too big
+Failed: error 161 at offset 7: group number is too big
 
 /[\g6666666666]/B
 ------------------------------------------------------------------
@@ -8243,17 +8407,17 @@
 \= Expect no match
     \r\nA
 No match
-    
+
 /\nA/newline=crlf
-    \r\nA 
+    \r\nA
  0: \x0aA
 
 /[\r\n]A/newline=crlf
-    \r\nA 
+    \r\nA
  0: \x0aA
 
 /(\r|\n)A/newline=crlf
-    \r\nA 
+    \r\nA
  0: \x0aA
  1: \x0a
 
@@ -8264,52 +8428,52 @@
     a\nb
  0: a\x0ab
 \= Expect no match
-    a\rb  
+    a\rb
 No match
 
 /(*CR)a.b/newline=lf
     a\nb
  0: a\x0ab
 \= Expect no match
-    a\rb  
+    a\rb
 No match
 
 /(*LF)a.b/newline=CRLF
     a\rb
  0: a\x0db
 \= Expect no match
-    a\nb  
+    a\nb
 No match
 
 /(*CRLF)a.b/
     a\rb
  0: a\x0db
-    a\nb  
+    a\nb
  0: a\x0ab
 \= Expect no match
-    a\r\nb  
+    a\r\nb
 No match
 
 /(*ANYCRLF)a.b/newline=CR
 \= Expect no match
     a\rb
 No match
-    a\nb  
+    a\nb
 No match
-    a\r\nb  
+    a\r\nb
 No match
 
 /(*ANY)a.b/newline=cr
 \= Expect no match
     a\rb
 No match
-    a\nb  
+    a\nb
 No match
-    a\r\nb  
+    a\r\nb
 No match
-    a\x85b 
+    a\x85b
 No match
-    
+
 /(*ANY).*/g
     abc\r\ndef
  0: abc
@@ -8331,6 +8495,31 @@
  0: def
  0: 
 
+/(*NUL)^.*/
+    a\nb\x00ccc
+ 0: a\x0ab
+
+/(*NUL)^.*/s
+    a\nb\x00ccc
+ 0: a\x0ab\x00ccc
+
+/^x/m,newline=NUL
+    ab\x00xy
+ 0: x
+
+/'#comment' 0d 0a 00 '^x\' 0a 'y'/x,newline=nul,hex
+    x\nyz
+ 0: x\x0ay
+
+/(*NUL)^X\NY/
+    X\nY
+ 0: X\x0aY
+    X\rY
+ 0: X\x0dY
+\= Expect no match
+    X\x00Y
+No match
+
 /a\Rb/I,bsr=anycrlf
 Capturing subpattern count = 0
 \R matches CR, LF, or CRLF
@@ -8346,7 +8535,7 @@
 \= Expect no match
     a\x85b
 No match
-    a\x0bb     
+    a\x0bb
 No match
 
 /a\Rb/I,bsr=unicode
@@ -8363,9 +8552,9 @@
  0: a\x0d\x0ab
     a\x85b
  0: a\x85b
-    a\x0bb     
+    a\x0bb
  0: a\x0bb
-    
+
 /a\R?b/I,bsr=anycrlf
 Capturing subpattern count = 0
 \R matches CR, LF, or CRLF
@@ -8381,7 +8570,7 @@
 \= Expect no match
     a\x85b
 No match
-    a\x0bb     
+    a\x0bb
 No match
 
 /a\R?b/I,bsr=unicode
@@ -8398,9 +8587,9 @@
  0: a\x0d\x0ab
     a\x85b
  0: a\x85b
-    a\x0bb     
+    a\x0bb
  0: a\x0bb
-    
+
 /a\R{2,4}b/I,bsr=anycrlf
 Capturing subpattern count = 0
 \R matches CR, LF, or CRLF
@@ -8416,7 +8605,7 @@
 \= Expect no match
     a\x85\x85b
 No match
-    a\x0b\x0bb     
+    a\x0b\x0bb
 No match
 
 /a\R{2,4}b/I,bsr=unicode
@@ -8433,12 +8622,12 @@
  0: a\x0d\x0a\x0a\x0d\x0db
     a\x85\x85b
  0: a\x85\x85b
-    a\x0b\x0bb     
+    a\x0b\x0bb
  0: a\x0b\x0bb
-\= Expect no match 
-    a\r\r\r\r\rb 
+\= Expect no match
+    a\r\r\r\r\rb
 No match
- 
+
 /(*BSR_ANYCRLF)a\Rb/I
 Capturing subpattern count = 0
 \R matches CR, LF, or CRLF
@@ -8447,7 +8636,7 @@
 Subject length lower bound = 3
     a\nb
  0: a\x0ab
-    a\rb 
+    a\rb
  0: a\x0db
 
 /(*BSR_UNICODE)a\Rb/I
@@ -8468,7 +8657,7 @@
 Subject length lower bound = 3
     a\nb
  0: a\x0ab
-    a\rb 
+    a\rb
  0: a\x0db
 
 /(*CRLF)(*BSR_UNICODE)a\Rb/I
@@ -8493,25 +8682,25 @@
 Failed: error 162 at offset 9: subpattern name expected
 
 /(?<abc>)(?&a)/
-Failed: error 115 at offset 12: reference to non-existent subpattern
+Failed: error 115 at offset 11: reference to non-existent subpattern
 
 /(?<a>)(?&aaaaaaaaaaaaaaaaaaaaaaa)/
-Failed: error 115 at offset 32: reference to non-existent subpattern
+Failed: error 115 at offset 9: reference to non-existent subpattern
 
 /(?+-a)/
-Failed: error 163 at offset 3: digit expected after (?+
+Failed: error 129 at offset 2: digit expected after (?+ or (?-
 
 /(?-+a)/
 Failed: error 111 at offset 3: unrecognized character after (? or (?-
 
 /(?(-1))/
-Failed: error 115 at offset 6: reference to non-existent subpattern
+Failed: error 115 at offset 5: reference to non-existent subpattern
 
 /(?(+10))/
-Failed: error 115 at offset 7: reference to non-existent subpattern
+Failed: error 115 at offset 4: reference to non-existent subpattern
 
 /(?(10))/
-Failed: error 115 at offset 6: reference to non-existent subpattern
+Failed: error 115 at offset 3: reference to non-existent subpattern
 
 /(?(+2))()()/
 
@@ -8527,10 +8716,10 @@
 Failed: error 162 at offset 3: subpattern name expected
 
 /\k/
-Failed: error 169 at offset 1: \k is not followed by a braced, angle-bracketed, or quoted name
+Failed: error 169 at offset 2: \k is not followed by a braced, angle-bracketed, or quoted name
 
 /\kabc/
-Failed: error 169 at offset 1: \k is not followed by a braced, angle-bracketed, or quoted name
+Failed: error 169 at offset 2: \k is not followed by a braced, angle-bracketed, or quoted name
 
 /(?P=)/
 Failed: error 162 at offset 4: subpattern name expected
@@ -8571,10 +8760,10 @@
 /^(?+1)(?<a>x|y){0}z/
     xzxx
  0: xz
-    yzyy 
+    yzyy
  0: yz
 \= Expect no match
-    xxz  
+    xxz
 No match
 
 /(\3)(\1)(a)/
@@ -8588,13 +8777,13 @@
  1: 
  2: 
  3: a
-    
+
 /TA]/
-    The ACTA] comes 
+    The ACTA] comes
  0: TA]
 
 /TA]/alt_bsux,allow_empty_class,match_unset_backref,dupnames
-    The ACTA] comes 
+    The ACTA] comes
  0: TA]
 
 /(?2)[]a()b](abc)/
@@ -8609,7 +8798,7 @@
     abcbabc
  0: abcbabc
  1: abc
-\= Expect no match 
+\= Expect no match
     abcXabc
 No match
 
@@ -8617,7 +8806,7 @@
     abcXabc
  0: abcXabc
  1: abc
-\= Expect no match 
+\= Expect no match
     abcbabc
 No match
 
@@ -8628,11 +8817,11 @@
  2: xyz
 
 /(?&N)[]a(?<N>)](?<M>abc)/
-Failed: error 115 at offset 4: reference to non-existent subpattern
+Failed: error 115 at offset 3: reference to non-existent subpattern
    abc<abc
 
 /(?&N)[]a(?<N>)](abc)/
-Failed: error 115 at offset 4: reference to non-existent subpattern
+Failed: error 115 at offset 3: reference to non-existent subpattern
    abc<abc
 
 /a[]b/
@@ -8648,30 +8837,30 @@
 
 /a[]+b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
 \= Expect no match
-    ab 
+    ab
 No match
 
 /a[]*+b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
 \= Expect no match
-    ab 
+    ab
 No match
 
 /a[^]b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
     aXb
  0: aXb
-    a\nb 
+    a\nb
  0: a\x0ab
 \= Expect no match
-    ab  
+    ab
 No match
-    
+
 /a[^]+b/alt_bsux,allow_empty_class,match_unset_backref,dupnames
     aXb
  0: aXb
-    a\nX\nXb 
+    a\nX\nXb
  0: a\x0aX\x0aXb
 \= Expect no match
-    ab  
+    ab
 No match
 
 /a(?!)b/B
@@ -8712,8 +8901,8 @@
 Subject length lower bound = 0
    adc
 --->adc
- +0 ^       (?(?=.*b)b|^)
- +2 ^       (?=.*b)
+ +0 ^       (?
+ +2 ^       (?=
  +5 ^       .*
  +7 ^  ^    b
  +7 ^ ^     b
@@ -8721,20 +8910,20 @@
  +7 ^       b
 +11 ^       ^
 +12 ^       )
-+13 ^       
++13 ^       End of pattern
  0: 
-   abc 
+   abc
 --->abc
- +0 ^       (?(?=.*b)b|^)
- +2 ^       (?=.*b)
+ +0 ^       (?
+ +2 ^       (?=
  +5 ^       .*
  +7 ^  ^    b
  +7 ^ ^     b
  +7 ^^      b
  +8 ^ ^     )
  +9 ^       b
- +0  ^      (?(?=.*b)b|^)
- +2  ^      (?=.*b)
+ +0  ^      (?
+ +2  ^      (?=
  +5  ^      .*
  +7  ^ ^    b
  +7  ^^     b
@@ -8742,41 +8931,40 @@
  +8  ^^     )
  +9  ^      b
 +10  ^^     |
-+13  ^^     
++13  ^^     End of pattern
  0: b
-   
+
 /(?(?=b).*b|^d)/I
 Capturing subpattern count = 0
 Subject length lower bound = 1
 
 /(?(?=.*b).*b|^d)/I
 Capturing subpattern count = 0
-First code unit at start or follows newline
 Subject length lower bound = 1
 
 /xyz/auto_callout
-  xyz 
+  xyz
 --->xyz
  +0 ^       x
  +1 ^^      y
  +2 ^ ^     z
- +3 ^  ^    
+ +3 ^  ^    End of pattern
  0: xyz
-  abcxyz 
+  abcxyz
 --->abcxyz
  +0    ^       x
  +1    ^^      y
  +2    ^ ^     z
- +3    ^  ^    
+ +3    ^  ^    End of pattern
  0: xyz
-\= Expect no match 
+\= Expect no match
   abc
 No match
-  abcxypqr  
+  abcxypqr
 No match
-  
+
 /xyz/auto_callout,no_start_optimize
-  abcxyz 
+  abcxyz
 --->abcxyz
  +0 ^          x
  +0  ^         x
@@ -8784,9 +8972,9 @@
  +0    ^       x
  +1    ^^      y
  +2    ^ ^     z
- +3    ^  ^    
+ +3    ^  ^    End of pattern
  0: xyz
-\= Expect no match 
+\= Expect no match
   abc
 --->abc
  +0 ^       x
@@ -8794,7 +8982,7 @@
  +0   ^     x
  +0    ^    x
 No match
-  abcxypqr  
+  abcxypqr
 --->abcxypqr
  +0 ^            x
  +0  ^           x
@@ -8808,7 +8996,7 @@
  +0        ^     x
  +0         ^    x
 No match
-  
+
 /(*NO_START_OPT)xyz/auto_callout
   abcxyz
 --->abcxyz
@@ -8818,9 +9006,9 @@
 +15    ^       x
 +16    ^^      y
 +17    ^ ^     z
-+18    ^  ^    
++18    ^  ^    End of pattern
  0: xyz
-  
+
 /(*NO_AUTO_POSSESS)a+b/B
 ------------------------------------------------------------------
         Bra
@@ -8831,7 +9019,7 @@
 ------------------------------------------------------------------
 
 /xyz/auto_callout,no_start_optimize
-  abcxyz 
+  abcxyz
 --->abcxyz
  +0 ^          x
  +0  ^         x
@@ -8839,7 +9027,7 @@
  +0    ^       x
  +1    ^^      y
  +2    ^ ^     z
- +3    ^  ^    
+ +3    ^  ^    End of pattern
  0: xyz
 
 /^"((?(?=[a])[^"])|b)*"$/auto_callout
@@ -8847,28 +9035,28 @@
 --->"ab"
  +0 ^        ^
  +1 ^        "
- +2 ^^       ((?(?=[a])[^"])|b)*
- +3 ^^       (?(?=[a])[^"])
- +5 ^^       (?=[a])
+ +2 ^^       (
+ +3 ^^       (?
+ +5 ^^       (?=
  +8 ^^       [a]
 +11 ^ ^      )
 +12 ^^       [^"]
 +16 ^ ^      )
 +17 ^ ^      |
- +3 ^ ^      (?(?=[a])[^"])
- +5 ^ ^      (?=[a])
+ +3 ^ ^      (?
+ +5 ^ ^      (?=
  +8 ^ ^      [a]
 +17 ^ ^      |
 +21 ^ ^      "
 +18 ^ ^      b
-+19 ^  ^     )
- +3 ^  ^     (?(?=[a])[^"])
- +5 ^  ^     (?=[a])
++19 ^  ^     )*
+ +3 ^  ^     (?
+ +5 ^  ^     (?=
  +8 ^  ^     [a]
 +17 ^  ^     |
 +21 ^  ^     "
 +22 ^   ^    $
-+23 ^   ^    
++23 ^   ^    End of pattern
  0: "ab"
  1: 
 
@@ -8889,7 +9077,7 @@
  3: c
  4: d
  5: Y
- 
+
 /Xa{2,4}b/
     X\=ps
 Partial match: X
@@ -8901,7 +9089,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /Xa{2,4}?b/
     X\=ps
 Partial match: X
@@ -8913,7 +9101,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /Xa{2,4}+b/
     X\=ps
 Partial match: X
@@ -8925,7 +9113,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /X\d{2,4}b/
     X\=ps
 Partial match: X
@@ -8937,7 +9125,7 @@
 Partial match: X333
     X3333\=ps
 Partial match: X3333
-    
+
 /X\d{2,4}?b/
     X\=ps
 Partial match: X
@@ -8949,7 +9137,7 @@
 Partial match: X333
     X3333\=ps
 Partial match: X3333
-    
+
 /X\d{2,4}+b/
     X\=ps
 Partial match: X
@@ -8961,7 +9149,7 @@
 Partial match: X333
     X3333\=ps
 Partial match: X3333
-    
+
 /X\D{2,4}b/
     X\=ps
 Partial match: X
@@ -8973,7 +9161,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /X\D{2,4}?b/
     X\=ps
 Partial match: X
@@ -8985,7 +9173,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /X\D{2,4}+b/
     X\=ps
 Partial match: X
@@ -8997,7 +9185,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /X[abc]{2,4}b/
     X\=ps
 Partial match: X
@@ -9009,7 +9197,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /X[abc]{2,4}?b/
     X\=ps
 Partial match: X
@@ -9021,7 +9209,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /X[abc]{2,4}+b/
     X\=ps
 Partial match: X
@@ -9033,7 +9221,7 @@
 Partial match: Xaaa
     Xaaaa\=ps
 Partial match: Xaaaa
-    
+
 /X[^a]{2,4}b/
     X\=ps
 Partial match: X
@@ -9045,7 +9233,7 @@
 Partial match: Xzzz
     Xzzzz\=ps
 Partial match: Xzzzz
-    
+
 /X[^a]{2,4}?b/
     X\=ps
 Partial match: X
@@ -9057,7 +9245,7 @@
 Partial match: Xzzz
     Xzzzz\=ps
 Partial match: Xzzzz
-    
+
 /X[^a]{2,4}+b/
     X\=ps
 Partial match: X
@@ -9069,7 +9257,7 @@
 Partial match: Xzzz
     Xzzzz\=ps
 Partial match: Xzzzz
-    
+
 /(Y)X\1{2,4}b/
     YX\=ps
 Partial match: YX
@@ -9081,7 +9269,7 @@
 Partial match: YXYYY
     YXYYYY\=ps
 Partial match: YXYYYY
-    
+
 /(Y)X\1{2,4}?b/
     YX\=ps
 Partial match: YX
@@ -9093,7 +9281,7 @@
 Partial match: YXYYY
     YXYYYY\=ps
 Partial match: YXYYYY
-    
+
 /(Y)X\1{2,4}+b/
     YX\=ps
 Partial match: YX
@@ -9105,7 +9293,7 @@
 Partial match: YXYYY
     YXYYYY\=ps
 Partial match: YXYYYY
-    
+
 /\++\KZ|\d+X|9+Y/startchar
     ++++123999\=ps
 Partial match: 123999
@@ -9121,7 +9309,7 @@
 No match
     ZA\=ps
 No match
-    
+
 /Z(?!)/
 \= Expect no match
     Z\=ps
@@ -9134,7 +9322,7 @@
  0: dog
     dogs\=ph
 Partial match: dogs
-    
+
 /dog(sbody)??/
     dogs\=ps
  0: dog
@@ -9146,7 +9334,7 @@
  0: dog
     dogs\=ph
  0: dog
- 
+
 /dogsbody|dog/
     dogs\=ps
  0: dog
@@ -9164,7 +9352,7 @@
  0: abc
    abc\=ph
  0: abc
-   
+
 /abc\K123/startchar
     xyzabc123pqr
  0: abc123
@@ -9173,9 +9361,9 @@
 Partial match: abc12
     xyzabc12\=ph
 Partial match: abc12
-    
+
 /(?<=abc)123/
-    xyzabc123pqr 
+    xyzabc123pqr
  0: 123
     xyzabc12\=ps
 Partial match: abc12
@@ -9280,7 +9468,7 @@
 No match
     xyzabcdef\=notempty
 No match
-    
+
 /^(?:(?=abc)|abc\K)/aftertext,startchar
     abcdef
  0: 
@@ -9289,7 +9477,7 @@
  0: abc
     ^^^
  0+ def
-\= Expect no match 
+\= Expect no match
     abcdef\=notempty
 No match
 
@@ -9309,7 +9497,7 @@
     xyz\=notempty_atstart
  0: 
  0+ yz
-\= Expect no match 
+\= Expect no match
     xyz\=notempty
 No match
 
@@ -9320,7 +9508,7 @@
     xyzabc
  0: 
  0+ xyzabc
-\= Expect no match 
+\= Expect no match
     xyzabc\=notempty
 No match
     xyzabc\=notempty_atstart
@@ -9329,7 +9517,7 @@
 No match
     xyz\=notempty
 No match
-    
+
 /^(?<name>a|b\g<name>c)/
     aaaa
  0: a
@@ -9337,7 +9525,7 @@
     bacxxx
  0: bac
  1: bac
-    bbaccxxx 
+    bbaccxxx
  0: bbacc
  1: bbacc
     bbbacccxx
@@ -9351,7 +9539,7 @@
     bacxxx
  0: bac
  1: bac
-    bbaccxxx 
+    bbaccxxx
  0: bbacc
  1: bbacc
     bbbacccxx
@@ -9365,7 +9553,7 @@
     bacxxx
  0: bac
  1: bac
-    bbaccxxx 
+    bbaccxxx
  0: bbacc
  1: bbacc
     bbbacccxx
@@ -9379,7 +9567,7 @@
     bacxxx
  0: bac
  1: bac
-    bbaccxxx 
+    bbaccxxx
  0: bbacc
  1: bbacc
     bbbacccxx
@@ -9393,7 +9581,7 @@
     bacxxx
  0: bac
  1: bac
-    bbaccxxx 
+    bbaccxxx
  0: bbacc
  1: bbacc
     bbbacccxx
@@ -9409,7 +9597,7 @@
  0: bac
  1: bac
  2: bac
-    bbaccxxx 
+    bbaccxxx
  0: bbacc
  1: bbacc
  2: bbacc
@@ -9422,7 +9610,7 @@
     XaaX
  0: aa
  1: a
-    XAAX 
+    XAAX
  0: AA
  1: A
 
@@ -9430,15 +9618,15 @@
     XaaX
  0: aa
  1: a
-\= Expect no match 
-    XAAX 
+\= Expect no match
+    XAAX
 No match
 
 /(?-i:\g<+1>)(?i:(a))/
     XaaX
  0: aa
  1: a
-    XAAX 
+    XAAX
  0: AA
  1: A
 
@@ -9448,7 +9636,7 @@
    abc
  0: abc
  1: a
-   accccbbb 
+   accccbbb
  0: accccbbb
  1: a
 
@@ -9467,27 +9655,26 @@
     xbaax
  0: a
  1: a
-    xzzzax 
+    xzzzax
  0: a
  1: a
 
 /(a)(?<=b\1)/
-Failed: error 125 at offset 10: lookbehind assertion is not fixed length
 
 /(a)(?<=b+(?1))/
-Failed: error 125 at offset 13: lookbehind assertion is not fixed length
+Failed: error 125 at offset 3: lookbehind assertion is not fixed length
 
 /(a+)(?<=b(?1))/
-Failed: error 125 at offset 14: lookbehind assertion is not fixed length
+Failed: error 125 at offset 4: lookbehind assertion is not fixed length
 
 /(a(?<=b(?1)))/
-Failed: error 125 at offset 13: lookbehind assertion is not fixed length
+Failed: error 125 at offset 2: lookbehind assertion is not fixed length
 
 /(?<=b(?1))xyz/
 Failed: error 115 at offset 8: reference to non-existent subpattern
 
 /(?<=b(?1))xyz(b+)pqrstuvew/
-Failed: error 125 at offset 26: lookbehind assertion is not fixed length
+Failed: error 125 at offset 0: lookbehind assertion is not fixed length
 
 /(a|bc)\1/I
 Capturing subpattern count = 1
@@ -9534,6 +9721,7 @@
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'F'
 Last code unit = ':'
 Subject length lower bound = 22
 
@@ -9584,7 +9772,7 @@
     (?: [0-9a-f]{1,4} |       # 1-4 hex digits or
     (?(1)0 | () ) )           # if null previously matched, fail; else null
     :                         # followed by colon
-  ){1,7}                      # end item; 1-7 of them required               
+  ){1,7}                      # end item; 1-7 of them required
   [0-9a-f]{1,4} $             # final hex number at end of string
   (?(1)|.)                    # check that there was an empty component
   /Iix
@@ -9611,10 +9799,10 @@
   C B (1) a (group 1)
 
 /(?|(?<a>A)|(?<b>B))/
-Failed: error 165 at offset 15: different names for subpatterns of the same number are not allowed
+Failed: error 165 at offset 16: different names for subpatterns of the same number are not allowed
 
 /(?:a(?<quote> (?<apostrophe>')|(?<realquote>")) |
-    b(?<quote> (?<apostrophe>')|(?<realquote>")) ) 
+    b(?<quote> (?<apostrophe>')|(?<realquote>")) )
     (?('quote')[a-z]+|[0-9]+)/Ix,dupnames
 Capturing subpattern count = 6
 Max back reference = 4
@@ -9633,7 +9821,7 @@
  1: "
  2: <unset>
  3: "
-    b"aaaaa 
+    b"aaaaa
  0: b"aaaaa
  1: <unset>
  2: <unset>
@@ -9641,12 +9829,12 @@
  4: "
  5: <unset>
  6: "
-\= Expect no match 
+\= Expect no match
     b"11111
 No match
-    a"11111 
+    a"11111
 No match
-    
+
 /^(?|(a)(b)(c)(?<D>d)|(?<D>e)) (?('D')X|Y)/IBx,dupnames
 ------------------------------------------------------------------
         Bra
@@ -9685,6 +9873,7 @@
   D   1
 Compile options: dupnames extended
 Overall options: anchored dupnames extended
+Starting code units: a e 
 Subject length lower bound = 2
     abcdX
  0: abcdX
@@ -9698,9 +9887,9 @@
 \= Expect no match
     abcdY
 No match
-    ey     
+    ey
 No match
-    
+
 /(?<A>a) (b)(c)  (?<A>d  (?(R&A)$ | (?4)) )/IBx,dupnames
 ------------------------------------------------------------------
         Bra
@@ -9741,7 +9930,7 @@
  3: c
  4: dd
 \= Expect no match
-    abcdde  
+    abcdde
 No match
 
 /abcd*/
@@ -9779,29 +9968,6 @@
     xxxxabcde\=ph
 Partial match: abcde
 
-# This is not in the Perl-compatible test because Perl seems currently to be
-# broken and not behaving as specified in that it *does* bumpalong after
-# hitting (*COMMIT). 
-
-/(?1)(A(*COMMIT)|B)D/
-    ABD
- 0: ABD
- 1: B
-    XABD
- 0: ABD
- 1: B
-    BAD
- 0: BAD
- 1: A
-    ABXABD  
- 0: ABD
- 1: B
-\= Expect no match 
-    ABX 
-No match
-    BAXBAD  
-No match
-
 /(\3)(\1)(a)/alt_bsux,allow_empty_class,match_unset_backref,dupnames
     cat
  0: a
@@ -9838,7 +10004,7 @@
 Subject length lower bound = 1
     i
  0: i
-    
+
 /()i(?(1)a)/I
 Capturing subpattern count = 1
 Max back reference = 1
@@ -9862,10 +10028,10 @@
  0: ab
     XAbX
  0: Ab
-    CcC 
+    CcC
  0: c
 \= Expect no match
-    XABX   
+    XABX
 No match
 
 /(?i)a(?s)b|c/B
@@ -9925,7 +10091,7 @@
  0: xabcxd
  1: abcxd
  2: cx
-    
+
 /^(?&t)*+(?(DEFINE)(?<t>.))$/B
 ------------------------------------------------------------------
         Bra
@@ -9950,7 +10116,7 @@
         Bra
         ^
         Brazero
-        Once
+        SBra
         Recurse
         KetRmax
         Cond
@@ -9966,9 +10132,9 @@
 
 # This one is here because Perl gives the match as "b" rather than "ab". I
 # believe this to be a Perl bug.
-      
+
 /(?>a\Kb)z|(ab)/
-    ab\=startchar 
+    ab\=startchar
  0: ab
  1: ab
 
@@ -9977,7 +10143,7 @@
  0: 
  1: 
  2: 
-    0abc 
+    0abc
  0: 0
  1: 0
  2: 0
@@ -9989,9 +10155,9 @@
 Failed: error 166 at offset 6: (*MARK) must have an argument
 
 /abc(*FAIL:123)xyz/
-Failed: error 159 at offset 13: an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)
+Failed: error 159 at offset 10: an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)
 
-# This should, and does, fail. In Perl, it does not, which I think is a 
+# This should, and does, fail. In Perl, it does not, which I think is a
 # bug because replacing the B in the pattern by (B|D) does make it fail.
 
 /A(*COMMIT)B/aftertext,mark
@@ -10010,7 +10176,7 @@
 \= Expect no match
     AC
 No match
-    
+
 # Mark names can be duplicated. Perl doesn't give a mark for this one,
 # though PCRE2 does.
 
@@ -10018,35 +10184,35 @@
 \= Expect no match
     XAQQ
 No match, mark = A
-    
-# COMMIT at the start of a pattern should be the same as an anchor. Perl 
+
+# COMMIT at the start of a pattern should be the same as an anchor. Perl
 # optimizations defeat this. So does the PCRE2 optimization unless we disable
 # it.
 
 /(*COMMIT)ABC/
     ABCDEFG
  0: ABC
-    
+
 /(*COMMIT)ABC/no_start_optimize
 \= Expect no match
     DEFGABC
 No match
-    
+
 /^(ab (c+(*THEN)cd) | xyz)/x
 \= Expect no match
-    abcccd  
+    abcccd
 No match
 
 /^(ab (c+(*PRUNE)cd) | xyz)/x
 \= Expect no match
-    abcccd  
+    abcccd
 No match
 
 /^(ab (c+(*FAIL)cd) | xyz)/x
 \= Expect no match
-    abcccd  
+    abcccd
 No match
-    
+
 # Perl gets some of these wrong
 
 /(?>.(*ACCEPT))*?5/
@@ -10083,7 +10249,7 @@
 \= Expect no match
     A\nB
 No match
-    ACB\n   
+    ACB\n
 No match
 
 /A\NB./Bs
@@ -10098,19 +10264,19 @@
 ------------------------------------------------------------------
     ACBD
  0: ACBD
-    ACB\n 
+    ACB\n
  0: ACB\x0a
 \= Expect no match
-    A\nB  
+    A\nB
 No match
-  
+
 /A\NB/newline=crlf
     A\nB
  0: A\x0aB
     A\rB
  0: A\x0dB
 \= Expect no match
-    A\r\nB    
+    A\r\nB
 No match
 
 /\R+b/B
@@ -10288,7 +10454,7 @@
 \= Bad offsets
     abc\=offset=4
 Failed: error -33: bad offset value
-    abc\=offset=-4 
+    abc\=offset=-4
 ** Invalid value in 'offset=-4'
 \= Valid data
     abc\=offset=0
@@ -10335,7 +10501,7 @@
 Failed: error 142 at offset 29: syntax error in subpattern name (missing terminator)
 
 /(?P<abn>(?P=axn)xxx)/B
-Failed: error 115 at offset 15: reference to non-existent subpattern
+Failed: error 115 at offset 12: reference to non-existent subpattern
 
 /(?P<abn>(?P=axn)xxx)(?<axn>yy)/B
 ------------------------------------------------------------------
@@ -10351,18 +10517,18 @@
         End
 ------------------------------------------------------------------
 
-# These tests are here because Perl gets the first one wrong. 
+# These tests are here because Perl gets the first one wrong.
 
 /(\R*)(.)/s
     \r\n
  0: \x0d
  1: 
  2: \x0d
-    \r\r\n\n\r 
+    \r\r\n\n\r
  0: \x0d\x0d\x0a\x0a\x0d
  1: \x0d\x0d\x0a\x0a
  2: \x0d
-    \r\r\n\n\r\n 
+    \r\r\n\n\r\n
  0: \x0d\x0d\x0a\x0a\x0d
  1: \x0d\x0d\x0a\x0a
  2: \x0d
@@ -10372,11 +10538,11 @@
  0: \x0d
  1: <unset>
  2: \x0d
-    \r\r\n\n\r 
+    \r\r\n\n\r
  0: \x0d\x0d\x0a\x0a\x0d
  1: \x0a
  2: \x0d
-    \r\r\n\n\r\n 
+    \r\r\n\n\r\n
  0: \x0d\x0d\x0a\x0a\x0d
  1: \x0a
  2: \x0d
@@ -10386,16 +10552,16 @@
  0: \x0d
  1: 
  2: \x0d
-    \r\r\n\n\r 
+    \r\r\n\n\r
  0: \x0d\x0d\x0a\x0a\x0d
  1: \x0d\x0d\x0a\x0a
  2: \x0d
-    \r\r\n\n\r\n 
+    \r\r\n\n\r\n
  0: \x0d\x0d\x0a\x0a\x0d
  1: \x0d\x0d\x0a\x0a
  2: \x0d
 
-# ------------- 
+# -------------
 
 /^abc$/B
 ------------------------------------------------------------------
@@ -10422,7 +10588,7 @@
  0: aaaaX
  1: a
  2: X
-\= Expect no match 
+\= Expect no match
     aaaa
 No match
 
@@ -10430,7 +10596,7 @@
     aaaaX
  0: aaaaX
  1: X
-\= Expect no match 
+\= Expect no match
     aaaa
 No match
 
@@ -10456,18 +10622,20 @@
 Subject length lower bound = 5
 
 /(?<=(abc)+)X/
-Failed: error 125 at offset 10: lookbehind assertion is not fixed length
+Failed: error 125 at offset 0: lookbehind assertion is not fixed length
 
 /(^ab)/I
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
 
 /(^ab)++/I
 Capturing subpattern count = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
 
 /(^ab|^)+/I
@@ -10488,12 +10656,14 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
 
 /(?:^ab)++/I
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 2
 
 /(?:^ab|^)+/I
@@ -10605,7 +10775,7 @@
 
 /(abc)\1+/
 
-# Perl doesn't get these right IMO (the 3rd is PCRE2-specific) 
+# Perl doesn't get these right IMO (the 3rd is PCRE2-specific)
 
 /(?1)(?:(b(*ACCEPT))){0}/
     b
@@ -10614,8 +10784,8 @@
 /(?1)(?:(b(*ACCEPT))){0}c/
     bc
  0: bc
-\= Expect no match 
-    b 
+\= Expect no match
+    b
 No match
 
 /(?1)(?:((*ACCEPT))){0}c/
@@ -10625,7 +10795,7 @@
  0: c
 
 /^.*?(?(?=a)a|b(*THEN)c)/
-\= Expect no match 
+\= Expect no match
     ba
 No match
 
@@ -10634,20 +10804,20 @@
  0: ba
 
 /^.*?(?(?=a)a(*THEN)b|c)/
-\= Expect no match 
+\= Expect no match
     ac
 No match
 
 /^.*?(?(?=a)a(*THEN)b)c/
-\= Expect no match 
+\= Expect no match
     ac
 No match
 
 /^.*?(a(*THEN)b)c/
-\= Expect no match 
+\= Expect no match
     aabc
 No match
-    
+
 /^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x
     aabc
  0: aabc
@@ -10670,12 +10840,12 @@
  0: C
  1: C
 MK: A
-\= Expect no match 
+\= Expect no match
     D
 No match, mark = A
-     
+
 /(*:A)A+(*SKIP:A)(B|Z)/mark
-\= Expect no match 
+\= Expect no match
     AAAC
 No match, mark = A
 
@@ -10686,17 +10856,17 @@
  0: c
     c\=notempty
  0: c
-    
+
 /(?1)c(?(DEFINE)((*ACCEPT)b))/
     c
  0: c
     c\=notempty
  0: c
-    
+
 /(?>(*ACCEPT)b)c/
     c
  0: 
-\= Expect no match 
+\= Expect no match
     c\=notempty
 No match
 
@@ -10711,7 +10881,7 @@
     ac\=ovector=1
  0: ac
  0+ 
-    
+
 /(a)(b)x|abc/allaftertext
      abc\=ovector=2
  0: abc
@@ -10744,7 +10914,8 @@
 
 /(?(DEFINE)(a(?2)|b)(b(?1)|a))(?:(?1)|(?2))/I
 Capturing subpattern count = 2
-Subject length lower bound = 1
+May match empty string
+Subject length lower bound = 0
 
 /(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/I
 Capturing subpattern count = 2
@@ -10783,7 +10954,7 @@
  1: <unset>
  2: <unset>
  3: baz
-    foobarbazX    
+    foobarbazX
  0: bazX
  1: <unset>
  2: <unset>
@@ -10966,26 +11137,26 @@
     adz
 --->adz
  +0 ^       ^
- +1 ^       (a(*:A)(d|e(*:B))z|aeq)
+ +1 ^       (
  +2 ^       a
  +3 ^^      (*:A)
- +8 ^^      (d|e(*:B))
+ +8 ^^      (
 Latest Mark: A
  +9 ^^      d
 +10 ^ ^     |
 +18 ^ ^     z
 +19 ^  ^    |
-+24 ^  ^    
++24 ^  ^    End of pattern
  0: adz
  1: adz
  2: d
     aez
 --->aez
  +0 ^       ^
- +1 ^       (a(*:A)(d|e(*:B))z|aeq)
+ +1 ^       (
  +2 ^       a
  +3 ^^      (*:A)
- +8 ^^      (d|e(*:B))
+ +8 ^^      (
 Latest Mark: A
  +9 ^^      d
 +11 ^^      e
@@ -10994,17 +11165,17 @@
 Latest Mark: B
 +18 ^ ^     z
 +19 ^  ^    |
-+24 ^  ^    
++24 ^  ^    End of pattern
  0: aez
  1: aez
  2: e
     aeqwerty
 --->aeqwerty
  +0 ^            ^
- +1 ^            (a(*:A)(d|e(*:B))z|aeq)
+ +1 ^            (
  +2 ^            a
  +3 ^^           (*:A)
- +8 ^^           (d|e(*:B))
+ +8 ^^           (
 Latest Mark: A
  +9 ^^           d
 +11 ^^           e
@@ -11016,7 +11187,7 @@
 +21 ^^           e
 +22 ^ ^          q
 +23 ^  ^         )
-+24 ^  ^         
++24 ^  ^         End of pattern
  0: aeq
  1: aeq
 
@@ -11083,7 +11254,7 @@
 ------------------------------------------------------------------
         Bra
         ^
-        Once_NC
+        Once
         a++
         Ket
         Once
@@ -11099,7 +11270,7 @@
  0: aaaazzzzb
  1: zzzz
 \= Expect no match
-    aazz  
+    aazz
 No match
 
 /(.)(\1|a(?2))/
@@ -11107,15 +11278,15 @@
  0: bab
  1: b
  2: ab
-    
+
 /\1|(.)(?R)\1/
     cbbbc
  0: cbbbc
  1: c
-    
+
 /(.)((?(1)c|a)|a(?2))/
 \= Expect no match
-    baa  
+    baa
 No match
 
 /(?P<abn>(?P=abn)xxx)/B
@@ -11223,14 +11394,14 @@
 ------------------------------------------------------------------
 
 /a[\NB]c/
-Failed: error 171 at offset 3: \N is not supported in a class
+Failed: error 171 at offset 4: \N is not supported in a class
     aNc
-    
+
 /a[B-\Nc]/
-Failed: error 150 at offset 5: invalid range in character class
+Failed: error 150 at offset 6: invalid range in character class
 
 /a[B\Nc]/
-Failed: error 171 at offset 4: \N is not supported in a class
+Failed: error 171 at offset 5: \N is not supported in a class
 
 /(a)(?2){0,1999}?(b)/
 
@@ -11239,14 +11410,14 @@
 # This test, with something more complicated than individual letters, causes
 # different behaviour in Perl. Perhaps it disables some optimization; no tag is
 # passed back for the failures, whereas in PCRE2 there is a tag.
-    
+
 /(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/x,mark
     AABC
  0: AB
  1: A
  2: B
 MK: A
-    XXYZ 
+    XXYZ
  0: XXY
  1: <unset>
  2: <unset>
@@ -11255,40 +11426,40 @@
  5: Y
 MK: B
 \= Expect no match
-    XAQQ  
+    XAQQ
 No match, mark = A
-    XAQQXZZ  
+    XAQQXZZ
 No match, mark = A
-    AXQQQ 
+    AXQQQ
 No match, mark = A
-    AXXQQQ 
+    AXXQQQ
 No match, mark = B
 
 # Perl doesn't give marks for these, though it does if the alternatives are
-# replaced by single letters. 
-    
+# replaced by single letters.
+
 /(b|q)(*:m)f|a(*:n)w/mark
-    aw 
+    aw
  0: aw
 MK: n
-\= Expect no match 
+\= Expect no match
     abc
 No match, mark = m
 
 /(q|b)(*:m)f|a(*:n)w/mark
-    aw 
+    aw
  0: aw
 MK: n
-\= Expect no match 
+\= Expect no match
     abc
 No match, mark = m
 
-# After a partial match, the behaviour is as for a failure. 
+# After a partial match, the behaviour is as for a failure.
 
 /^a(*:X)bcde/mark
    abc\=ps
 Partial match, mark=X: abc
-   
+
 # These are here because Perl doesn't return a mark, except for the first.
 
 /(?=(*:x))(q|)/aftertext,mark
@@ -11418,7 +11589,7 @@
     abababx
  0: abababx
  1: ab
-    ababababx  
+    ababababx
  0: ababababx
  1: ab
 
@@ -11432,10 +11603,10 @@
     abababx
  0: abababx
  1: ab
-    ababababx  
+    ababababx
  0: ababababx
  1: ab
-    
+
 /^(..)(\1{2,3})ab/
     abababab
  0: abababab
@@ -11447,7 +11618,7 @@
  0: \x0d
     \r\=ph
 Partial match: \x0d
-    
+
 /^\R{2,3}x/
     \r\=ps
 Partial match: \x0d
@@ -11463,7 +11634,7 @@
 Partial match: \x0d\x0d\x0d
     \r\rx
  0: \x0d\x0dx
-    \r\r\rx    
+    \r\r\rx
  0: \x0d\x0d\x0dx
 
 /^\R{2,3}?x/
@@ -11481,9 +11652,9 @@
 Partial match: \x0d\x0d\x0d
     \r\rx
  0: \x0d\x0dx
-    \r\r\rx    
+    \r\r\rx
  0: \x0d\x0d\x0dx
-    
+
 /^\R?x/
     \r\=ps
 Partial match: \x0d
@@ -11491,7 +11662,7 @@
 Partial match: \x0d
     x
  0: x
-    \rx  
+    \rx
  0: \x0dx
 
 /^\R+x/
@@ -11503,7 +11674,7 @@
 Partial match: \x0d\x0a
     \r\n\=ph
 Partial match: \x0d\x0a
-    \rx  
+    \rx
  0: \x0dx
 
 /^a$/newline=crlf
@@ -11537,7 +11708,7 @@
  0: \x0d
     \r\=ph
 Partial match: \x0d
-  
+
 /.{2,3}/newline=crlf
     \r\=ps
 Partial match: \x0d
@@ -11570,9 +11741,9 @@
     ABCDGHI\=ovector=01
 Matched, but too many substrings
  0: ABCD
-    
+
 # These are all run as real matches in test 1; here we are just checking the
-# settings of the anchored and startline bits.  
+# settings of the anchored and startline bits.
 
 /(?>.*?a)(?<=ba)/I
 Capturing subpattern count = 0
@@ -11602,6 +11773,7 @@
 Capturing subpattern count = 0
 Compile options: dotall
 Overall options: anchored dotall
+First code unit = 'a'
 Subject length lower bound = 2
 
 /.*?a(*SKIP)b/I
@@ -11624,6 +11796,7 @@
 Capturing subpattern count = 0
 Compile options: dotall
 Overall options: anchored dotall
+First code unit = 'a'
 Subject length lower bound = 2
 
 /(?>.*?)(?<=(abcd)|(wxyz))/I
@@ -11671,43 +11844,36 @@
 /(?:(a)+(?C1)bb|aa(?C2)b)/
     aab\=callout_capture
 Callout 1: last capture = 1
- 0: <unset>
  1: a
 --->aab
     ^ ^     b
 Callout 1: last capture = 1
- 0: <unset>
  1: a
 --->aab
     ^^      b
 Callout 2: last capture = 0
- 0: <unset>
 --->aab
     ^ ^     b
  0: aab
-   
+
 /(?:(a)++(?C1)bb|aa(?C2)b)/
     aab\=callout_capture
 Callout 1: last capture = 1
- 0: <unset>
  1: a
 --->aab
     ^ ^     b
 Callout 2: last capture = 0
- 0: <unset>
 --->aab
     ^ ^     b
  0: aab
-    
+
 /(?:(?>(a))(?C1)bb|aa(?C2)b)/
     aab\=callout_capture
 Callout 1: last capture = 1
- 0: <unset>
  1: a
 --->aab
     ^^      b
 Callout 2: last capture = 0
- 0: <unset>
 --->aab
     ^ ^     b
  0: aab
@@ -11715,15 +11881,12 @@
 /(?:(?1)(?C1)x|ab(?C2))((a)){0}/
     aab\=callout_capture
 Callout 1: last capture = 0
- 0: <unset>
 --->aab
     ^^      x
 Callout 1: last capture = 0
- 0: <unset>
 --->aab
      ^^     x
 Callout 2: last capture = 0
- 0: <unset>
 --->aab
      ^ ^    )
  0: ab
@@ -11731,45 +11894,39 @@
 /(?1)(?C1)((a)(?C2)){0}/
     aab\=callout_capture
 Callout 2: last capture = 2
- 0: <unset>
  1: <unset>
  2: a
 --->aab
-    ^^      )
+    ^^      ){0}
 Callout 1: last capture = 0
- 0: <unset>
 --->aab
-    ^^      ((a)(?C2)){0}
+    ^^      (
  0: a
 
 /(?:(a)+(?C1)bb|aa(?C2)b)++/
     aab\=callout_capture
 Callout 1: last capture = 1
- 0: <unset>
  1: a
 --->aab
     ^ ^     b
 Callout 1: last capture = 1
- 0: <unset>
  1: a
 --->aab
     ^^      b
 Callout 2: last capture = 0
- 0: <unset>
 --->aab
     ^ ^     b
  0: aab
     aab\=callout_capture,ovector=1
 Callout 1: last capture = 1
- 0: <unset>
+ 1: a
 --->aab
     ^ ^     b
 Callout 1: last capture = 1
- 0: <unset>
+ 1: a
 --->aab
     ^^      b
 Callout 2: last capture = 0
- 0: <unset>
 --->aab
     ^ ^     b
  0: aab
@@ -11779,7 +11936,7 @@
  0: ab
     ab\=ovector=1
  0: ab
-  
+
 /(?<=123)(*MARK:xx)abc/mark
     xxxx123a\=ph
 Partial match, mark=xx: 123a
@@ -11787,7 +11944,7 @@
     xxxx123a\=ps
 Partial match, mark=xx: 123a
                         <<<
-    
+
 /123\Kabc/startchar
     xxxx123a\=ph
 Partial match: 123a
@@ -11798,26 +11955,26 @@
     bb
 --->bb
  +0 ^      ^
- +1 ^      (?(?=a)aa|bb)
- +3 ^      (?=a)
+ +1 ^      (?
+ +3 ^      (?=
  +6 ^      a
 +11 ^      b
 +12 ^^     b
 +13 ^ ^    )
-+14 ^ ^    
++14 ^ ^    End of pattern
  0: bb
 
 /(?C1)^(?C2)(?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10))(?C11)/
     bb
 --->bb
   1 ^      ^
-  2 ^      (?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10))
- 99 ^      (?=(?C3)a(?C4))
+  2 ^      (?
+ 99 ^      (?=
   3 ^      a
   8 ^      b
   9 ^^     b
  10 ^ ^    )
- 11 ^ ^    
+ 11 ^ ^    End of pattern
  0: bb
 
 # Perl seems to have a bug with this one.
@@ -11825,18 +11982,18 @@
 /aaaaa(*COMMIT)(*PRUNE)b|a+c/
     aaaaaac
  0: aaaac
-    
+
 # Here are some that Perl treats differently because of the way it handles
-# backtracking verbs. 
+# backtracking verbs.
 
 /(?!a(*COMMIT)b)ac|ad/
      ac
  0: ac
-     ad 
+     ad
  0: ad
 
 /^(?!a(*THEN)b|ac)../
-     ad 
+     ad
  0: ad
 \= Expect no match
      ac
@@ -11845,7 +12002,7 @@
 /^(?=a(*THEN)b|ac)/
     ac
  0: 
-    
+
 /\A.*?(?:a|b(*THEN)c)/
     ba
  0: ba
@@ -11859,7 +12016,7 @@
  0: ba
 
 /(?:(a(*MARK:X)a+(*SKIP:X)b)){0}(?:(?1)|aac)/
-    aac 
+    aac
  0: aac
 
 /\A.*?(a|b(*THEN)c)/
@@ -11868,24 +12025,23 @@
  1: a
 
 /^(A(*THEN)B|A(*THEN)D)/
-    AD           
+    AD
  0: AD
  1: AD
-    
+
 /(?!b(*THEN)a)bn|bnn/
     bnn
  0: bn
 
 /(?(?=b(*SKIP)a)bn|bnn)/
-\= Expect no match
     bnn
-No match
+ 0: bnn
 
 /(?=b(*THEN)a|)bn|bnn/
     bnn
  0: bn
 
-# This test causes a segfault with Perl 5.18.0 
+# This test causes a segfault with Perl 5.18.0
 
 /^(?=(a)){0}b(?1)/
     backgammon
@@ -12545,7 +12701,7 @@
         Ket
         a
         CBraPos 1
-        a++
+        a+
         KetRpos
         a
         Ket
@@ -12568,7 +12724,7 @@
         cc
         Ket
         a++
-        Once_NC
+        Once
         bb
         Alt
         cc
@@ -12917,7 +13073,7 @@
 ------------------------------------------------------------------
         Bra
         [a-f]*+
-        Once_NC
+        Once
         gg
         Alt
         hh
@@ -12925,7 +13081,7 @@
         #
         [a-f]*+
         Brazero
-        Once_NC
+        Once
         gg
         Alt
         hh
@@ -12933,7 +13089,7 @@
         #
         [a-f]*
         Brazero
-        Once_NC
+        Once
         gg
         Alt
         hh
@@ -12941,7 +13097,7 @@
         a#
         [a-f]*+
         Brazero
-        Once_NC
+        Once
         gg
         Alt
         hh
@@ -13016,15 +13172,15 @@
 Last code unit = 'd'
 Subject length lower bound = 1
 
-# End of special auto-possessive tests 
+# End of special auto-possessive tests
 
 /^A\o{1239}B/
 Failed: error 164 at offset 8: non-octal character in \o{} (closing brace missing?)
     A\123B
 
 /^A\oB/
-Failed: error 155 at offset 3: missing opening brace after \o
-    
+Failed: error 155 at offset 4: missing opening brace after \o
+
 /^A\x{zz}B/
 Failed: error 167 at offset 5: non-hex character in \x{} (closing brace missing?)
 
@@ -13032,7 +13188,7 @@
 Failed: error 167 at offset 7: non-hex character in \x{} (closing brace missing?)
 
 /^A\x{/
-Failed: error 167 at offset 5: non-hex character in \x{} (closing brace missing?)
+Failed: error 178 at offset 5: digits missing in \x{} or \o{}
 
 /[ab]++/B,no_auto_possess
 ------------------------------------------------------------------
@@ -13067,16 +13223,16 @@
 ------------------------------------------------------------------
 
 /[a-[:digit:]]+/
-Failed: error 150 at offset 3: invalid range in character class
+Failed: error 150 at offset 4: invalid range in character class
 
 /[A-[:digit:]]+/
-Failed: error 150 at offset 3: invalid range in character class
+Failed: error 150 at offset 4: invalid range in character class
 
 /[a-[.xxx.]]+/
-Failed: error 150 at offset 3: invalid range in character class
+Failed: error 150 at offset 4: invalid range in character class
 
 /[a-[=xxx=]]+/
-Failed: error 150 at offset 3: invalid range in character class
+Failed: error 150 at offset 4: invalid range in character class
 
 /[a-[!xxx!]]+/
 Failed: error 108 at offset 3: range out of order in character class
@@ -13086,13 +13242,13 @@
  0: A]]]
 
 /[a-\d]+/
-Failed: error 150 at offset 4: invalid range in character class
+Failed: error 150 at offset 5: invalid range in character class
 
 /(?<0abc>xx)/
 Failed: error 144 at offset 3: group name must start with a non-digit
 
 /(?&1abc)xx(?<1abc>y)/
-Failed: error 144 at offset 13: group name must start with a non-digit
+Failed: error 144 at offset 3: group name must start with a non-digit
 
 /(?<ab-cd>xx)/
 Failed: error 142 at offset 5: syntax error in subpattern name (missing terminator)
@@ -13116,13 +13272,13 @@
 Failed: error 144 at offset 4: group name must start with a non-digit
 
 /\g{4df}/
-Failed: error 144 at offset 3: group name must start with a non-digit
+Failed: error 157 at offset 2: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
 
 /(?&1abc)xx(?<1abc>y)/
-Failed: error 144 at offset 13: group name must start with a non-digit
+Failed: error 144 at offset 3: group name must start with a non-digit
 
 /(?P>1abc)xx(?<1abc>y)/
-Failed: error 144 at offset 14: group name must start with a non-digit
+Failed: error 144 at offset 4: group name must start with a non-digit
 
 /\g'3gh'/
 Failed: error 157 at offset 2: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
@@ -13137,7 +13293,7 @@
 Failed: error 144 at offset 4: group name must start with a non-digit
 
 /(?(4gh)abc)/
-Failed: error 126 at offset 4: malformed number or name after (?(
+Failed: error 124 at offset 4: missing closing parenthesis for condition
 
 /(?(R&6yh)abc)/
 Failed: error 144 at offset 5: group name must start with a non-digit
@@ -13186,18 +13342,18 @@
 ------------------------------------------------------------------
     little red riding hood
  0: red
-    a /red/ thing 
+    a /red/ thing
  0: red
     red is a colour
  0: red
-    put it all on red  
+    put it all on red
  0: red
 \= Expect no match
     no reduction
 No match
     Alfred Winifred
 No match
-    
+
 /[a[:<:]] should give error/
 Failed: error 130 at offset 4: unknown POSIX class name
 
@@ -13211,14 +13367,14 @@
 \= Expect no match
     xx\nxabcd
 No match
-    
+
 # Test stack guard external calls.
 
 /(((a)))/stackguard=1
-Failed: error 133 at offset 2: parentheses are too deeply nested (stack check)
+Failed: error 133 at offset 7: parentheses are too deeply nested (stack check)
 
 /(((a)))/stackguard=2
-Failed: error 133 at offset 3: parentheses are too deeply nested (stack check)
+Failed: error 133 at offset 7: parentheses are too deeply nested (stack check)
 
 /(((a)))/stackguard=3
 
@@ -13231,7 +13387,7 @@
         Bra
         ^
         \w+
-        Once_NC
+        Once
         \s*+
         Ket
         AssertB
@@ -13243,10 +13399,10 @@
 ------------------------------------------------------------------
 
 /\othing/
-Failed: error 155 at offset 1: missing opening brace after \o
+Failed: error 155 at offset 2: missing opening brace after \o
 
 /\o{}/
-Failed: error 178 at offset 1: digits missing in \x{} or \o{}
+Failed: error 178 at offset 3: digits missing in \x{} or \o{}
 
 /\o{whatever}/
 Failed: error 164 at offset 3: non-octal character in \o{} (closing brace missing?)
@@ -13265,9 +13421,9 @@
 /A\9B/
 Failed: error 115 at offset 2: reference to non-existent subpattern
 
-# This one is here because Perl fails to match "12" for this pattern when the $ 
+# This one is here because Perl fails to match "12" for this pattern when the $
 # is present.
-    
+
 /^(?(?=abc)\w{3}:|\d\d)$/
     abc:
  0: abc:
@@ -13276,10 +13432,10 @@
 \= Expect no match
     123
 No match
-    xyz    
+    xyz
 No match
 
-# Perl gets this one wrong, giving "a" as the after text for ca and failing to 
+# Perl gets this one wrong, giving "a" as the after text for ca and failing to
 # match for cd.
 
 /(?(?=ab)ab)/aftertext
@@ -13289,11 +13445,11 @@
     ca
  0: 
  0+ ca
-    cd 
+    cd
  0: 
  0+ cd
-    
-# This should test both paths for processing OP_RECURSE. 
+
+# This should test both paths for processing OP_RECURSE.
 
 /(?(R)a+|(?R)b)/
     aaaabcde
@@ -13310,14 +13466,14 @@
  0: a
     ba
  0: b
-    cb  
+    cb
  0: b
 
 /(*NOTEMPTY_ATSTART)a*?b*?/aftertext
     ab
  0: a
  0+ b
-    cdab 
+    cdab
  0: 
  0+ dab
 
@@ -13326,7 +13482,7 @@
 Subject length lower bound = 2
     yesno
  0: yes
-    
+
 /(?(VERSION=8)yes){3}/BI,aftertext
 ------------------------------------------------------------------
         Bra
@@ -13350,7 +13506,7 @@
     yesnononoyes
  0: nonono
 \= Expect no match
-    yesno   
+    yesno
 No match
 
 /(?:(?<VERSION>abc)|xyz)(?(VERSION)yes|no)/I
@@ -13368,20 +13524,20 @@
 \= Expect no match
     abcno
 No match
-    xyzyes    
+    xyzyes
 No match
 
 /(?(VERSION<10)yes|no)/
-Failed: error 179 at offset 10: syntax error in (?(VERSION condition
+Failed: error 179 at offset 10: syntax error or number too big in (?(VERSION condition
 
 /(?(VERSION>10)yes|no)/
-Failed: error 179 at offset 11: syntax error in (?(VERSION condition
+Failed: error 179 at offset 11: syntax error or number too big in (?(VERSION condition
 
 /(?(VERSION>=10.0.0)yes|no)/
-Failed: error 179 at offset 16: syntax error in (?(VERSION condition
+Failed: error 179 at offset 16: syntax error or number too big in (?(VERSION condition
 
 /(?(VERSION=10.101)yes|no)/
-Failed: error 179 at offset 17: syntax error in (?(VERSION condition
+Failed: error 179 at offset 17: syntax error or number too big in (?(VERSION condition
 
 /abcd/I
 Capturing subpattern count = 0
@@ -13402,18 +13558,17 @@
    abd
  0: abd
  1: ab
-   xyd 
+   xyd
  0: d
 
 /(|ab)*?d/I,no_start_optimize
 Capturing subpattern count = 1
 Options: no_start_optimize
-Last code unit = 'd'
 Subject length lower bound = 0
    abd
  0: abd
  1: ab
-   xyd 
+   xyd
  0: d
 
 /\k<A>*(?<A>aa)(?<A>bb)/match_unset_backref,dupnames
@@ -13500,7 +13655,7 @@
 /abc/replace=[9]XYZ
     123abc123
 Failed: error -48: no more memory
-    
+
 /abc/replace=xyz
     1abc2\=partial_hard
 Failed: error -34: bad option value
@@ -13518,29 +13673,29 @@
 /(?<=abc)(|def)/g,replace=<$0>
     123abcxyzabcdef789abcpqr
  4: 123abc<>xyzabc<><def>789abc<>pqr
-    
+
 /./replace=$0
     a
  1: a
-    
+
 /(.)(.)/replace=$2+$1
     abc
  1: b+ac
-    
+
 /(?<A>.)(?<B>.)/replace=$B+$A
     abc
  1: b+ac
-    
+
 /(.)(.)/g,replace=$2$1
-    abcdefgh  
+    abcdefgh
  4: badcfehg
-    
+
 /(*:pear)apple|(*:orange)lemon|(*:strawberry)blackberry/g,replace=${*MARK}
     apple lemon blackberry
  3: pear orange strawberry
     apple strudel
  1: pear strudel
-    fruitless  
+    fruitless
  0: fruitless
 
 /(*:pear)apple|(*:orange)lemon|(*:strawberry)blackberry/replace=${*MARK} sauce,
@@ -13552,10 +13707,10 @@
  3: <pear> <orange> <strawberry>
     apple strudel
  1: <pear> strudel
-    fruitless  
+    fruitless
  0: fruitless
-    
-/(*:pear)apple/g,replace=${*MARKING} 
+
+/(*:pear)apple/g,replace=${*MARKING}
     apple lemon blackberry
 Failed: error -35 at offset 11 in replacement: invalid replacement string
 
@@ -13563,7 +13718,7 @@
     apple lemon blackberry
 Failed: error -58 at offset 7 in replacement: expected closing curly bracket in replacement string
 
-/(*:pear)apple/g,replace=${*mark} 
+/(*:pear)apple/g,replace=${*mark}
     apple lemon blackberry
 Failed: error -35 at offset 8 in replacement: invalid replacement string
 
@@ -13627,13 +13782,13 @@
 Get substring 4 failed (-49): unknown substring
  0L c
  1L 
-    
+
 /x(?=ab\K)/
-    xab\=get=0 
+    xab\=get=0
 Start of matched string is beyond its end - displaying from end to start.
  0: ab
  0G  (0)
-    xab\=copy=0 
+    xab\=copy=0
 Start of matched string is beyond its end - displaying from end to start.
  0: ab
  0C  (0)
@@ -13674,12 +13829,14 @@
 Capturing subpattern count = 0
 Compile options: <none>
 Overall options: anchored
+First code unit = 'a'
 Subject length lower bound = 3
 
 /^abc/info,no_dotstar_anchor
 Capturing subpattern count = 0
 Compile options: no_dotstar_anchor
 Overall options: anchored no_dotstar_anchor
+First code unit = 'a'
 Subject length lower bound = 3
 
 /.*\d/info,auto_callout
@@ -13797,7 +13954,7 @@
      456
  0: 456
 \= Expect no match
-     356   
+     356
 No match
 
 '^(a)*+(\w)'
@@ -13805,7 +13962,7 @@
  0: g
  1: <unset>
  2: g
-    g\=ovector=1 
+    g\=ovector=1
 Matched, but too many substrings
  0: g
 
@@ -13813,10 +13970,10 @@
     g
  0: g
  1: g
-    g\=ovector=1 
+    g\=ovector=1
 Matched, but too many substrings
  0: g
-    
+
 # These two pattern showeds up compile-time bugs
 
 "((?2){0,1999}())?"
@@ -13897,7 +14054,6 @@
 /^a(b)c(?C1)def/
       abcdef\=callout_capture
 Callout 1: last capture = 1
- 0: <unset>
  1: b
 --->abcdef
     ^  ^       d
@@ -13920,7 +14076,6 @@
 ------------------------------------------------------------------
       abcdef\=callout_capture
 Callout (10): {AB} last capture = 1
- 0: <unset>
  1: b
 --->abcdef
     ^  ^       d
@@ -13955,15 +14110,15 @@
         Bra
         Bra
         a
-        CalloutStr `code` 8 14 0
+        CalloutStr `code` 8 14 4
         Ket
         Bra
         a
-        CalloutStr `code` 8 14 0
+        CalloutStr `code` 8 14 4
         Ket
         Bra
         a
-        CalloutStr `code` 8 14 0
+        CalloutStr `code` 8 14 4
         Ket
         Ket
         End
@@ -13974,7 +14129,7 @@
         Bra
         ^
         Cond
-        Callout 25 9 7
+        Callout 25 9 3
         Assert
         abc
         Ket
@@ -13985,14 +14140,14 @@
         Ket
         End
 ------------------------------------------------------------------
-Callout 25  (?=abc)
+Callout 25  (?=
     abcdefg
 --->abcdefg
- 25 ^           (?=abc)
+ 25 ^           (?=
  0: abcd
-    xyz123 
+    xyz123
 --->xyz123
- 25 ^          (?=abc)
+ 25 ^          (?=
  0: xyz
 
 /^(?(?C$abc$)(?=abc)abcd|xyz)/B
@@ -14000,7 +14155,7 @@
         Bra
         ^
         Cond
-        CalloutStr $abc$ 7 12 7
+        CalloutStr $abc$ 7 12 3
         Assert
         abc
         Ket
@@ -14014,12 +14169,12 @@
     abcdefg
 Callout (7): $abc$
 --->abcdefg
-    ^           (?=abc)
+    ^           (?=
  0: abcd
-    xyz123 
+    xyz123
 Callout (7): $abc$
 --->xyz123
-    ^          (?=abc)
+    ^          (?=
  0: xyz
 
 /^ab(?C'first')cd(?C"second")ef/
@@ -14036,13 +14191,13 @@
     aaaXY
 Callout (8): `code`
 --->aaaXY
-    ^^        )
+    ^^        ){3}
 Callout (8): `code`
 --->aaaXY
-    ^ ^       )
+    ^ ^       ){3}
 Callout (8): `code`
 --->aaaXY
-    ^  ^      )
+    ^  ^      ){3}
  0: aaaX
 
 # Binary zero in callout string
@@ -14060,8 +14215,8 @@
 /(?(?!)a|b)/
     bbb
  0: b
-\= Expect no match 
-    aaa 
+\= Expect no match
+    aaa
 No match
 
 # JIT gives a different error message for the infinite recursion
@@ -14073,7 +14228,7 @@
 # Perl fails to diagnose the absence of an assertion
 
 "(?(?<E>.*!.*)?)"
-Failed: error 128 at offset 3: assertion expected after (?( or (?(?C)
+Failed: error 128 at offset 2: assertion expected after (?( or (?(?C)
 
 "X((?2)()*+){2}+"B
 ------------------------------------------------------------------
@@ -14124,7 +14279,7 @@
 Failed: error 115 at offset 15: reference to non-existent subpattern
 
 ";(?<=()((?3))((?2)))"
-Failed: error 125 at offset 20: lookbehind assertion is not fixed length
+Failed: error 125 at offset 1: lookbehind assertion is not fixed length
 
 # Perl loops on this (PCRE2 used to!)
 
@@ -14163,9 +14318,9 @@
 \= Expect no match
     \[9x!xxx(]{9999}
 No match
-    
+
 /(abc)*/
-    \[abc]{5} 
+    \[abc]{5}
  0: abcabcabcabcabc
  1: abc
 
@@ -14211,7 +14366,7 @@
 /A\8B\9C/
 Failed: error 115 at offset 2: reference to non-existent subpattern
     A8B9C
-    
+
 /(?x:((?'a')) # comment (with parentheses) and | vertical
 (?-x:#not a comment (?'b')) # this is a comment ()
 (?'c')) # not a comment (?'d')/info
@@ -14239,14 +14394,14 @@
  1: 
  2: 2
  3: 
-    B32A 
+    B32A
  0: 3
  1: 
  2: 
  3: 3
 
 # These are some patterns that used to cause buffer overflows or other errors
-# while compiling. 
+# while compiling.
 
 /.((?2)(?R)|\1|$)()/B
 ------------------------------------------------------------------
@@ -14306,7 +14461,7 @@
 "(?J)(?'d'(?'d'\g{d}))"
 
 "(?=!((?2)(?))({8(?<=(?1){29}8bbbb\x16\xd\xc6^($(\xa9H4){4}h}?1)B))\x15')"
-Failed: error 125 at offset 72: lookbehind assertion is not fixed length
+Failed: error 125 at offset 16: lookbehind assertion is not fixed length
 
 /A(?'')Z/
 Failed: error 162 at offset 4: subpattern name expected
@@ -14314,7 +14469,7 @@
 "(?J:(?|(?'R')(\k'R')|((?'R'))))"
 
 /(?<=|(\,\$(?73591620449005828816)\xa8.{7}){6}\x09)/
-Failed: error 161 at offset 32: number is too big
+Failed: error 161 at offset 17: group number is too big
 
 /^(?:(?(1)x|)+)+$()/B
 ------------------------------------------------------------------
@@ -14335,16 +14490,16 @@
 ------------------------------------------------------------------
 
 /[[:>:]](?<)/
-Failed: error 124 at offset 10: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 10: subpattern name expected
 
 /((?x)(*:0))#(?'/
-Failed: error 124 at offset 15: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 15: subpattern name expected
 
 /(?C$[$)(?<]/
-Failed: error 124 at offset 10: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 10: subpattern name expected
 
 /(?C$)$)(?<]/
-Failed: error 124 at offset 10: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 10: subpattern name expected
 
 /(?(R))*+/B
 ------------------------------------------------------------------
@@ -14362,7 +14517,7 @@
  0: 
 
 /((?x)(?#))#(?'/
-Failed: error 124 at offset 14: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 14: subpattern name expected
 
 /((?x)(?#))#(?'abc')/I
 Capturing subpattern count = 2
@@ -14372,7 +14527,7 @@
 Subject length lower bound = 1
 
 /[[:\\](?<[::]/
-Failed: error 124 at offset 9: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 9: subpattern name expected
 
 /[[:\\](?'abc')[a:]/I
 Capturing subpattern count = 1
@@ -14401,13 +14556,13 @@
 ------------------------------------------------------------------
 
 /(?R-:(?</
-Failed: error 114 at offset 8: missing closing parenthesis
+Failed: error 158 at offset 3: (?R (recursive pattern call) must be followed by a closing parenthesis
 
 /(?R-:(?<)/
-Failed: error 129 at offset 3: (?R or (?[+-]digits must be followed by )
+Failed: error 158 at offset 3: (?R (recursive pattern call) must be followed by a closing parenthesis
 
 /(?(?C{\Q})(?!(?'/
-Failed: error 124 at offset 16: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 16: subpattern name expected
 
 /(?(?C{\Q})(?!(?'abc')))/I
 Capturing subpattern count = 1
@@ -14478,7 +14633,7 @@
  0: {4,5a}bc
 
 /\x0{ab}/
-    \0{ab} 
+    \0{ab}
  0: \x00{ab}
 
 /^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/
@@ -14505,10 +14660,10 @@
  0: ab
 
 /(?(8000000000/
-Failed: error 114 at offset 13: missing closing parenthesis
+Failed: error 161 at offset 8: group number is too big
 
 /((?(R8000000000)))/
-Failed: error 161 at offset 16: number is too big
+Failed: error 161 at offset 9: group number is too big
 
 /0(?0)|(1)(*THEN)(*SKIP:0)(*FAIL)/
 \= Expect no match
@@ -14516,7 +14671,7 @@
 No match
 
 /(?(1)()\983040\2)/
-Failed: error 115 at offset 13: reference to non-existent subpattern
+Failed: error 161 at offset 14: group number is too big
 
 /(*LIMIT_MATCH=)abc/
 Failed: error 160 at offset 14: (*VERB) not recognized or malformed
@@ -14538,9 +14693,9 @@
     aacb
 No match
 
-/(*MARK:a\zb)z/alt_verbnames 
-Failed: error 140 at offset 9: invalid escape sequence in (*VERB) name
-    
+/(*MARK:a\zb)z/alt_verbnames
+Failed: error 140 at offset 10: invalid escape sequence in (*VERB) name
+
 /(*:ab\t(d\)c)xxx/
 Failed: error 122 at offset 12: unmatched closing parenthesis
 
@@ -14553,20 +14708,38 @@
     x
  0: x
 MK: Axx)xB
-    
+
 /(*:A\ExxxB)x/alt_verbnames,mark
-    x 
+    x
  0: x
 MK: AxxxB
-    
+
 /(*: A \ and #comment
      \ B)x/x,alt_verbnames,mark
-    x  
+    x
  0: x
 MK: A and B
-    
+
+/(*: A \ and #comment
+     \ B)x/alt_verbnames,mark
+    x
+ 0: x
+MK:  A  and #comment\x0a      B
+
+/(*: A \ and #comment
+     \ B)x/x,mark
+    x
+ 0: x
+MK:  A \ and #comment\x0a     \ B
+
+/(*: A \ and #comment
+     \ B)x/mark
+    x
+ 0: x
+MK:  A \ and #comment\x0a     \ B
+
 /(*:A
-B)x/alt_verbnames,mark 
+B)x/alt_verbnames,mark
     x
  0: x
 MK: A\x0aB
@@ -14595,7 +14768,7 @@
 \= Expect no match
     1234abc\=offset_limit=6
 No match
-    
+
 /A/g,replace=-,use_offset_limit
     XAXAXAXAXA\=offset_limit=4
  2: X-X-XAXAXA
@@ -14614,20 +14787,20 @@
 /abcd/null_context
     abcd\=null_context
  0: abcd
-\= Expect error     
+\= Expect error
     abcd\=null_context,find_limits
 ** Not allowed together: find_limits null_context
-    abcd\=allusedtext,startchar 
+    abcd\=allusedtext,startchar
 ** Not allowed together: allusedtext startchar
 
 /abcd/replace=w\rx\x82y\o{333}z(\Q12\$34$$\x34\E5$$),substitute_extended
     abcd
  1: w\x0dx\x82y\xdbz(12\$34$$\x345$)
-    
+
 /a(bc)(DE)/replace=a\u$1\U$1\E$1\l$2\L$2\Eab\Uab\LYZ\EDone,substitute_extended
     abcDE
  1: aBcBCbcdEdeabAByzDone
- 
+
 /abcd/replace=xy\kz,substitute_extended
     abcd
 Failed: error -57 at offset 4 in replacement: bad escape sequence in replacement string
@@ -14681,9 +14854,9 @@
 /(?J)(?:(?<A>a)|(?<A>b))/replace=<$A>
     [a]
  1: [<a>]
-    [b] 
+    [b]
  1: [<b>]
-\= Expect error     
+\= Expect error
     (a)\=ovector=1
 Failed: error -54 at offset 3 in replacement: requested value is not available
 
@@ -14701,6 +14874,7 @@
 Max back reference = 1
 Compile options: <none>
 Overall options: anchored
+First code unit = 'o'
 Last code unit = '}'
 Subject length lower bound = 65535
 
@@ -14715,7 +14889,7 @@
 Failed: error -49 at offset 3 in replacement: unknown substring
 
 /(?<!a{65535}a{5})x/I
-Failed: error 187 at offset 16: lookbehind assertion is too long
+Failed: error 187 at offset 0: lookbehind assertion is too long
 
 /(?<!a{65535})x/I
 Capturing subpattern count = 0
@@ -14726,11 +14900,11 @@
 /(?=a\K)/replace=z
     BaCaD
 Failed: error -60: match with end before start is not supported
-    
+
 /(?'abcdefghijklmnopqrstuvwxyzABCDEFG'toolong)/
 Failed: error 148 at offset 36: subpattern name is too long (maximum 32 characters)
- 
-/(?'abcdefghijklmnopqrstuvwxyzABCDEF'justright)/ 
+
+/(?'abcdefghijklmnopqrstuvwxyzABCDEF'justright)/
 
 # These two use zero-termination
 /abcd/max_pattern_length=3
@@ -14744,7 +14918,7 @@
 
 /abcdef/hex,max_pattern_length=3
 
-# These two patterns used to take a long time to compile
+# These patterns used to take a long time to compile
 
 "(.*)
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
@@ -14767,21 +14941,21 @@
 Options: extended
 Subject length lower bound = 0
 
-# When (?| is used and groups of the same number may be different,
-# we have to rely on a count to catch overly complicated patterns.
-
 "(?|()|())(.*)
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))"xI
-Failed: error 186 at offset 148: regular expression is too complicated
+Capturing subpattern count = 13
+May match empty string
+Options: extended
+Subject length lower bound = 0
 
 "(?|()|())(?<=a()
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
 ((?-2)(?-2))((?-2)(?-2))((?-2)(?-2))
 a)"xI
-Failed: error 186 at offset 154: regular expression is too complicated
+Failed: error 135 at offset 9: lookbehind is too complicated
 
 # Test the use of malloc for caching group information when there are more
 # groups than fit into the on-stack workspace.
@@ -14950,11 +15124,11 @@
 /(A*)\E+/B,auto_callout
 ------------------------------------------------------------------
         Bra
-        Callout 255 0 7
+        Callout 255 0 1
         SCBra 1
         Callout 255 1 2
         A*
-        Callout 255 3 0
+        Callout 255 3 4
         KetRmax
         Callout 255 7 0
         Ket
@@ -14964,10 +15138,10 @@
 /()\Q\E*]/B,auto_callout
 ------------------------------------------------------------------
         Bra
-        Callout 255 0 7
+        Callout 255 0 1
         Brazero
         SCBra 1
-        Callout 255 1 0
+        Callout 255 1 6
         KetRmax
         Callout 255 7 1
         ]
@@ -14977,10 +15151,10 @@
 ------------------------------------------------------------------
     a[bc]d
 --->a[bc]d
- +0     ^      ()\Q\E*
- +1     ^      )
+ +0     ^      (
+ +1     ^      )\Q\E*
  +7     ^      ]
- +8     ^^     
+ +8     ^^     End of pattern
  0: ]
  1: 
 
@@ -15077,12 +15251,12 @@
 (?-x):?/extended
 
 /(8(*:6^\x09x\xa6l\)6!|\xd0:[^:|)\x09d\Z\d{85*m(?'(?<1!)*\W[*\xff]!!h\w]*\xbe;/alt_bsux,alt_verbnames,allow_empty_class,dollar_endonly,extended,multiline,never_utf,no_dotstar_anchor,no_start_optimize
-Failed: error 124 at offset 49: letter or underscore expected after (?< or (?'
+Failed: error 162 at offset 49: subpattern name expected
 
 /a|(b)c/replace=>$1<,substitute_unset_empty
     cat
  1: c><t
-    xbcom 
+    xbcom
  1: x>b<om
 
 /a|(b)c/
@@ -15104,23 +15278,23 @@
 /a|(?'X'b)c/replace=>$X<,substitute_unset_empty
     cat
  1: c><t
-    xbcom 
+    xbcom
  1: x>b<om
 
 /a|(?'X'b)c/replace=>$Y<,substitute_unset_empty
     cat
 Failed: error -49 at offset 3 in replacement: unknown substring
-    cat\=substitute_unknown_unset 
+    cat\=substitute_unknown_unset
  1: c><t
-    cat\=substitute_unknown_unset,-substitute_unset_empty 
+    cat\=substitute_unknown_unset,-substitute_unset_empty
 Failed: error -55 at offset 3 in replacement: requested value is not set
 
 /a|(b)c/replace=>$2<,substitute_unset_empty
     cat
 Failed: error -49 at offset 3 in replacement: unknown substring
-    cat\=substitute_unknown_unset 
+    cat\=substitute_unknown_unset
  1: c><t
-    cat\=substitute_unknown_unset,-substitute_unset_empty 
+    cat\=substitute_unknown_unset,-substitute_unset_empty
 Failed: error -55 at offset 3 in replacement: requested value is not set
 
 /()()()/use_offset_limit
@@ -15130,13 +15304,13 @@
 ** Invalid value in 'callout_fail=11000000000'
     \=callout_fail=1:11000000000
 ** Invalid value in 'callout_fail=1:11000000000'
-    \=callout_data=11000000000 
+    \=callout_data=11000000000
 ** Invalid value in 'callout_data=11000000000'
-    \=callout_data=-11000000000 
+    \=callout_data=-11000000000
 ** Invalid value in 'callout_data=-11000000000'
-    \=offset_limit=1100000000000000000000 
+    \=offset_limit=1100000000000000000000
 ** Invalid value in 'offset_limit=1100000000000000000000'
-    \=copy=11000000000 
+    \=copy=11000000000
 ** Invalid value in 'copy=11000000000'
 
 /(*MARK:A\x00b)/mark
@@ -15160,13 +15334,13 @@
 MK: A\x00b
 
 /efg/hex
-** Unexpected non-hex-digit 'g' in hex pattern: quote missing?
+** Unexpected non-hex-digit 'g' at offset 2 in hex pattern: quote missing?
 
 /eff/hex
 ** Odd number of digits in hex pattern
 
 /effg/hex
-** Unexpected non-hex-digit 'g' in hex pattern: quote missing?
+** Unexpected non-hex-digit 'g' at offset 3 in hex pattern: quote missing?
 
 /(?J)(?'a'))(?'a')/
 Failed: error 122 at offset 10: unmatched closing parenthesis
@@ -15195,12 +15369,1219 @@
 /\[AB]{6000000000000000000000}/expand
 ** Pattern repeat count too large
 
-# End of testinput2 
-Error -63: PCRE2_ERROR_BADDATA (unknown error number)
+# Hex uses pattern length, not zero-terminated. This tests for overrunning
+# the given length of a pattern.
+
+/'(*U'/hex
+Failed: error 160 at offset 3: (*VERB) not recognized or malformed
+
+/'(*'/hex
+Failed: error 109 at offset 1: quantifier does not follow a repeatable item
+
+/'('/hex
+Failed: error 114 at offset 1: missing closing parenthesis
+
+//hex
+
+# These tests are here because Perl never allows a back reference in a
+# lookbehind. PCRE2 supports some limited cases.
+
+/([ab])...(?<=\1)z/
+    a11az
+ 0: a11az
+ 1: a
+    b11bz
+ 0: b11bz
+ 1: b
+\= Expect no match
+    b11az
+No match
+
+/(?|([ab]))...(?<=\1)z/
+Failed: error 125 at offset 13: lookbehind assertion is not fixed length
+
+/([ab])(\1)...(?<=\2)z/
+    aa11az
+ 0: aa11az
+ 1: a
+ 2: a
+
+/(a\2)(b\1)(?<=\2)/
+Failed: error 125 at offset 10: lookbehind assertion is not fixed length
+
+/(?<A>[ab])...(?<=\k'A')z/
+    a11az
+ 0: a11az
+ 1: a
+    b11bz
+ 0: b11bz
+ 1: b
+\= Expect no match
+    b11az
+No match
+
+/(?<A>[ab])...(?<=\k'A')(?<A>)z/dupnames
+Failed: error 125 at offset 13: lookbehind assertion is not fixed length
+
+# Perl does not support \g+n
+
+/((\g+1X)?([ab]))+/
+    aaXbbXa
+ 0: aaXbbXa
+ 1: bXa
+ 2: bX
+ 3: a
+
+/ab(?C1)c/auto_callout
+    abc
+--->abc
+ +0 ^       a
+ +1 ^^      b
+  1 ^ ^     c
+ +8 ^  ^    End of pattern
+ 0: abc
+
+/'ab(?C1)c'/hex,auto_callout
+    abc
+--->abc
+ +0 ^       a
+ +1 ^^      b
+  1 ^ ^     c
+ +8 ^  ^    End of pattern
+ 0: abc
+
+# Perl accepts these, but gives a warning. We can't warn, so give an error.
+
+/[a-[:digit:]]+/
+Failed: error 150 at offset 4: invalid range in character class
+    a-a9-a
+
+/[A-[:digit:]]+/
+Failed: error 150 at offset 4: invalid range in character class
+    A-A9-A
+
+/[a-\d]+/
+Failed: error 150 at offset 5: invalid range in character class
+    a-a9-a
+
+/(?<RA>abc)(?(R)xyz)/B
+------------------------------------------------------------------
+        Bra
+        CBra 1
+        abc
+        Ket
+        Cond
+        Cond recurse any
+        xyz
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?<R>abc)(?(R)xyz)/B
+------------------------------------------------------------------
+        Bra
+        CBra 1
+        abc
+        Ket
+        Cond
+      1 Cond ref
+        xyz
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?=.*[A-Z])/I
+Capturing subpattern count = 0
+May match empty string
+Subject length lower bound = 0
+
+/()(?<=(?0))/
+Failed: error 125 at offset 2: lookbehind assertion is not fixed length
+
+/(?<!|!(?<!))/
+
+/(?<!|!|!||||||(?<!)||(?<!)!|!||(?<!)!|!(?<!)!|!|!|!||||!!|<!)!|!||||!|/
+
+/{2,2{2,2/use_length
+
+/.>*?\g'0/use_length
+Failed: error 157 at offset 6: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
+
+/.>*?\g'0/
+Failed: error 157 at offset 6: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
+
+/{„Í„Í̈́Í{'{22{2{{2{'{22{{22{2{'{22{2{{2{{222{{2{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{222{2Ą̈́Í̈́Í{'{22{2{{2{'{22{{11{2{'{22{2{{2{{'{22{2{{2{'{22{{22{1{'{22{2{{2{{222{{2{'{22{2{22{2{'{/auto_callout
+
+//
+\=get=i00000000000000000000000000000000
+** Group name in 'get' is too long
+\=get=i2345678901234567890123456789012,get=i1245678901234567890123456789012
+** Too many characters in named 'get' modifiers
+
+"(?(?C))"
+Failed: error 128 at offset 6: assertion expected after (?( or (?(?C)
+
+/(?(?(?(?(?(?))))))/
+Failed: error 128 at offset 2: assertion expected after (?( or (?(?C)
+
+/(?<=(?1))((?s))/anchored
+
+/(*:ab)*/
+Failed: error 109 at offset 6: quantifier does not follow a repeatable item
+
+%(*:(:(svvvvvvvvvv:]*[   Z!*;[]*[^[]*!^[+.+{{2,7}'      _\\\\\\\\\\\\\)?.:..    *w////\\\Q\\\\\\\\\\\\\\\T\\\\\+/?/////'+\\\EEE?/////'+/*+/[^K]?]//(w)%never_backslash_c,alt_verbnames,auto_callout
+
+/./newline=crlf
+    \=ph
+No match
+
+/(\x0e00\000000\xc)/replace=\P,substitute_extended
+    \x0e00\000000\xc
+Failed: error -57 at offset 2 in replacement: bad escape sequence in replacement string
+
+//replace=0
+    \=offset=7
+Failed: error -33: bad offset value
+
+".+\QX\E+"B,no_auto_possess
+------------------------------------------------------------------
+        Bra
+        Any+
+        X+
+        Ket
+        End
+------------------------------------------------------------------
+
+".+\QX\E+"B,auto_callout,no_auto_possess
+------------------------------------------------------------------
+        Bra
+        Callout 255 0 4
+        Any+
+        Callout 255 4 4
+        X+
+        Callout 255 8 0
+        Ket
+        End
+------------------------------------------------------------------
+
+# This one is here because Perl gives an 'unmatched )' error which goes away
+# if one of the \) sequences is removed - which is weird. PCRE finds it too
+# complicated to find a minimum matching length.
+
+"()X|((((((((()))))))((((())))))\2())((((((\2\2)))\2)(\22((((\2\2)2))\2)))(2\ZZZ)+:)Z^|91ZiZZnter(ZZ |91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z+:)Z|91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z((Z*(\2(Z\':))\0)i|||||||||||||||loZ\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \)\0nte!rnal errpr\2\\21r(2\ZZZ)+:)Z!|91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \)\0(2\ZZZ)+:)Z^|91ZiZZnter(ZZ |91Z(ZZ ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \)\0(2\ZZZ)+:)Z^)))int \)\0(2\ZZZ)+:)Z^|91ZiZZnter(ZZernZal ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)2))\2Z)))int \))\ZZ(\r2Z( or#(\Z2(Z\Z(\2\2)2))\2Z)Z(\22Z((\Z2(Z\Z(\2\2)))\2))))((((((\2\2))))))"I
+Capturing subpattern count = 108
+Max back reference = 22
+Contains explicit CR or LF match
+Subject length lower bound = 1
+
+# This checks that new code for handling groups that may match an empty string
+# works on a very large number of alternatives. This pattern used to provoke a
+# complaint that it was too complicated.
+
+/(?:\[A|B|C|D|E|F|G|H|I|J|]{200}Z)/expand
+
+# This one used to compile rubbish instead of a compile error, and then
+# behave unpredictably at match time.
+
+/.+(?(?C'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'))?!XXXX.=X/
+Failed: error 128 at offset 63: assertion expected after (?( or (?(?C)
+    .+(?(?C'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'))?!XXXX.=X
+
+/[:[:alnum:]-[[a:lnum:]+/
+Failed: error 150 at offset 11: invalid range in character class
+
+/((?(?C'')\QX\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
+Failed: error 128 at offset 11: assertion expected after (?( or (?(?C)
+
+/((?(?C'')\Q\E(?!((?(?C'')(?!X=X));=)r*X=X));=)/
+
+/abcd/auto_callout
+    abcd\=callout_error=255:2
+--->abcd
+ +0 ^        a
+ +1 ^^       b
+Failed: error -37: callout error code
+
+/()(\g+65534)/
+Failed: error 161 at offset 11: group number is too big
+
+/()(\g+65533)/
+Failed: error 115 at offset 10: reference to non-existent subpattern
+
+/Á\x00\x00\x00š(\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\2*\x00k\d+\x00‎\x00\x00\x00\x00\x00\2*\x00\x00\1*.){36}int^\x00\x00ÿÿ\x00š(\1{50779}?)J\w2/I
+Capturing subpattern count = 2
+Max back reference = 2
+First code unit = \xc1
+Last code unit = '2'
+Subject length lower bound = 65535
+
+/(a)(b)\2\1\1\1\1/I
+Capturing subpattern count = 2
+Max back reference = 2
+First code unit = 'a'
+Last code unit = 'b'
+Subject length lower bound = 7
+
+/(?<a>a)(?<b>b)\g{b}\g{a}\g{a}\g{a}\g{a}(?<a>xx)(?<b>zz)/I,dupnames
+Capturing subpattern count = 4
+Max back reference = 4
+Named capturing subpatterns:
+  a   1
+  a   3
+  b   2
+  b   4
+Options: dupnames
+First code unit = 'a'
+Last code unit = 'z'
+Subject length lower bound = 11
+
+//
+    \=ovector=7777777777
+** Invalid value in 'ovector=7777777777'
+
+# This is here because Perl matches, even though a COMMIT is encountered
+# outside of the recursion.
+
+/(?1)(A(*COMMIT)|B)D/
+    BAXBAD
+No match
+
+"(?1){2}(a)"B
+------------------------------------------------------------------
+        Bra
+        Recurse
+        Recurse
+        CBra 1
+        a
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
+"(?1){2,4}(a)"B
+------------------------------------------------------------------
+        Bra
+        Recurse
+        Recurse
+        Brazero
+        Bra
+        Bra
+        Recurse
+        Ket
+        Brazero
+        Bra
+        Recurse
+        Ket
+        Ket
+        CBra 1
+        a
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
+# This test differs from Perl for the first subject. Perl ends up with
+# $1 set to 'B'; PCRE2 has it unset (which I think is right).
+
+/^(?:
+(?:A| (?:B|B(*ACCEPT)) (?<=(.)) D)
+(Z)
+)+$/x
+    AZB
+ 0: AZB
+ 1: <unset>
+ 2: Z
+    AZBDZ
+ 0: AZBDZ
+ 1: B
+ 2: Z
+
+# The first of these, when run by Perl, gives the mark 'aa', which is wrong.
+
+'(?>a(*:aa))b|ac' mark
+    ac
+ 0: ac
+
+'(?:a(*:aa))b|ac' mark
+    ac
+ 0: ac
+
+/(R?){65}/
+    (R?){65}
+ 0: 
+ 1: 
+
+/\[(a)]{60}/expand
+    aaaa
+No match
+
+/(?<!\1((?U)1((?U))))(*F)/never_backslash_c,alt_bsux,anchored,extended
+
+/\g{3/
+Failed: error 157 at offset 2: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number
+
+/(a(?C1)(b)(c)d)+/
+  abcdabcd\=callout_capture
+Callout 1: last capture = 0
+--->abcdabcd
+    ^^           (
+Callout 1: last capture = 1
+ 1: abcd
+ 2: b
+ 3: c
+--->abcdabcd
+    ^    ^       (
+ 0: abcdabcd
+ 1: abcd
+ 2: b
+ 3: c
+
+# Perl matches this one, but PCRE does not because (*ACCEPT) clears out any
+# pending backtracks in the recursion.
+
+/^ (?(DEFINE) (..(*ACCEPT)|...) ) (?1)$/x
+\= Expect no match
+    abc
+No match
+
+# Perl gives no match for this one
+
+/(a(*MARK:m)(*ACCEPT)){0}(?1)/mark
+    abc
+ 0: a
+MK: m
+
+/abc/endanchored
+    xyzabc
+ 0: abc
+\= Expect no match
+    xyzabcdef
+No match
+\= Expect error
+    xyzabc\=ph
+Failed: error -34: bad option value
+
+/abc/
+    xyzabc\=endanchored
+ 0: abc
+\= Expect no match
+    xyzabcdef\=endanchored
+No match
+\= Expect error
+    xyzabc\=ps,endanchored
+Failed: error -34: bad option value
+
+/abc(*ACCEPT)d/endanchored
+    xyzabc
+ 0: abc
+\= Expect no match
+    xyzabcdef
+No match
+
+/abc|bcd/endanchored
+    xyzabcd
+ 0: bcd
+\= Expect no match
+    xyzabcdef
+No match
+
+/a(*ACCEPT)x|aa/endanchored
+    aaa
+ 0: a
+
+# Check auto-anchoring when there is a group that is never obeyed at
+# the start of a branch.
+
+/(?(DEFINE)(a))^bc/I
+Capturing subpattern count = 1
+Compile options: <none>
+Overall options: anchored
+First code unit = 'b'
+Subject length lower bound = 2
+
+/(a){0}.*bc/sI
+Capturing subpattern count = 1
+Compile options: dotall
+Overall options: anchored dotall
+Last code unit = 'c'
+Subject length lower bound = 2
+
+# This should be anchored, as the condition is always false and there is
+# no alternative branch.
+
+/(?(VERSION>=999)yes)^bc/I
+Capturing subpattern count = 0
+Compile options: <none>
+Overall options: anchored
+Subject length lower bound = 2
+
+# This should not be anchored.
+
+/(?(VERSION>=999)yes|no)^bc/I
+Capturing subpattern count = 0
+Last code unit = 'c'
+Subject length lower bound = 4
+
+/(*LIMIT_HEAP=0)xxx/I
+Capturing subpattern count = 0
+Heap limit = 0
+First code unit = 'x'
+Last code unit = 'x'
+Subject length lower bound = 3
+
+/\d{0,3}(*:abc)(?C1)xxx/callout_info
+Callout 1  x
+
+# ----------------------------------------------------------------------
+
+# These are a whole pile of tests that touch lines of code that are not
+# used by any other tests (at least when these were created).
+
+/^a+?x/i,no_start_optimize,no_auto_possess
+\= Expect no match
+    aaa
+No match
+
+/^[^a]{3,}?x/i,no_start_optimize,no_auto_possess
+\= Expect no match
+    bbb
+No match
+    cc
+No match
+
+/^X\S/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\W/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\H/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\h/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\V/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\v/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\h/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY
+No match
+
+/^X\V/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\n
+No match
+
+/^X\v/no_start_optimize,no_auto_possess
+\= Expect no match
+    XX
+No match
+
+/^X.+?/s,no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\R+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    XX
+No match
+
+/^X\H+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\h+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+
+/^X\V+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+    X\n
+No match
+
+/^X\D+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+    X9
+No match
+
+/^X\S+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+    X\n
+No match
+
+/^X\W+?/no_start_optimize,no_auto_possess
+\= Expect no match
+    X
+No match
+    XX
+No match
+
+/^X.+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+No match
+
+/(*CRLF)^X.+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\r\=ps
+Partial match: XY\x0d
+
+/^X\R+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\nX
+No match
+    X\n\r\n
+No match
+    X\n\rY
+No match
+    X\n\nY
+No match
+    X\n\x{0c}Y
+No match
+
+/(*BSR_ANYCRLF)^X\R+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\nX
+No match
+    X\n\r\n
+No match
+    X\n\rY
+No match
+    X\n\nY
+No match
+    X\n\x{0c}Y
+No match
+
+/^X\H+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\t
+No match
+    XYY
+No match
+
+/^X\h+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\t\t
+No match
+    X\tY
+No match
+
+/^X\V+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+No match
+    XYY
+No match
+
+/^X\v+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\n\n
+No match
+    X\nY
+No match
+
+/^X\D+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY9
+No match
+    XYY
+No match
+
+/^X\d+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X99
+No match
+    X9Y
+No match
+
+/^X\S+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+No match
+    XYY
+No match
+
+/^X\s+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\n\n
+No match
+    X\nY
+No match
+
+/^X\W+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X.A
+No match
+    X++
+No match
+
+/^X\w+?Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    Xa.
+No match
+    Xaa
+No match
+
+/^X.{1,3}Z/s,no_start_optimize,no_auto_possess
+\= Expect no match
+    Xa.bd
+No match
+
+/^X\h+Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    X\t\t
+No match
+    X\tY
+No match
+
+/^X\V+Z/no_start_optimize,no_auto_possess
+\= Expect no match
+    XY\n
+No match
+    XYY
+No match
+
+/^(X(*THEN)Y|AB){0}(?1)/
+    ABX
+ 0: AB
+\= Expect no match
+    XAB
+No match
+
+/^(?!A(?C1)B)C/
+    ABC\=callout_error=1,no_jit
+No match
+
+/^(?!A(?C1)B)C/no_start_optimize
+    ABC\=callout_error=1
+--->ABC
+  1 ^^      B
+Failed: error -37: callout error code
+
+/^(?(?!A(?C1)B)C)/
+    ABC\=callout_error=1
+--->ABC
+  1 ^^      B
+Failed: error -37: callout error code
+
+# ----------------------------------------------------------------------
+
+/[a b c]/BxxI
+------------------------------------------------------------------
+        Bra
+        [a-c]
+        Ket
+        End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: extended_more
+Starting code units: a b c 
+Subject length lower bound = 1
+
+/[a b c]/BxxxI
+------------------------------------------------------------------
+        Bra
+        [a-c]
+        Ket
+        End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: extended extended_more
+Starting code units: a b c 
+Subject length lower bound = 1
+
+/[a b c]/B,extended_more
+------------------------------------------------------------------
+        Bra
+        [a-c]
+        Ket
+        End
+------------------------------------------------------------------
+
+/[ a b c ]/B,extended_more
+------------------------------------------------------------------
+        Bra
+        [a-c]
+        Ket
+        End
+------------------------------------------------------------------
+
+/[a b](?xx: [ 12 ] (?-xx:[ 34 ]) )y z/B
+------------------------------------------------------------------
+        Bra
+        [ ab]
+        Bra
+        [12]
+        Bra
+        [ 34]
+        Ket
+        Ket
+        y z
+        Ket
+        End
+------------------------------------------------------------------
+
+# Unsetting /x also unsets /xx
+
+/[a b](?xx: [ 12 ] (?-x:[ 34 ]) )y z/B
+------------------------------------------------------------------
+        Bra
+        [ ab]
+        Bra
+        [12]
+        Bra
+        [ 34]
+        Ket
+        Ket
+        y z
+        Ket
+        End
+------------------------------------------------------------------
+
+/(a)(?-n:(b))(c)/nB
+------------------------------------------------------------------
+        Bra
+        Bra
+        a
+        Ket
+        Bra
+        CBra 1
+        b
+        Ket
+        Ket
+        Bra
+        c
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
+# ----------------------------------------------------------------------
+# These test the dangerous PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL option.
+
+/\j\x{z}\o{82}\L\uabcd\u\U\g{\g/B,\bad_escape_is_literal
+** Unrecognized modifier '\' in '\bad_escape_is_literal'
+
+/\N{\c/IB,bad_escape_is_literal
+------------------------------------------------------------------
+        Bra
+        N{c
+        Ket
+        End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Extra options: bad_escape_is_literal
+First code unit = 'N'
+Last code unit = 'c'
+Subject length lower bound = 3
+
+/[\j\x{z}\o\gA-\Nb-\g]/B,bad_escape_is_literal
+------------------------------------------------------------------
+        Bra
+        [A-Nb-gjoxz{}]
+        Ket
+        End
+------------------------------------------------------------------
+
+/[Q-\N]/B,bad_escape_is_literal
+Failed: error 108 at offset 4: range out of order in character class
+
+# ----------------------------------------------------------------------
+
+/a\b(c/literal
+    a\\b(c
+ 0: a\b(c
+
+/a\b(c/literal,caseless
+    a\\b(c
+ 0: a\b(c
+    a\\B(c
+ 0: a\B(c
+
+/a\b(c/literal,firstline
+    XYYa\\b(c
+ 0: a\b(c
+\= Expect no match
+    X\na\\b(c
+No match
+
+/a\b?c/literal,use_offset_limit
+    XXXXa\\b?c\=offset_limit=4
+ 0: a\b?c
+\= Expect no match
+    XXXXa\\b?c\=offset_limit=3
+No match
+
+/a\b(c/literal,anchored,endanchored
+    a\\b(c
+ 0: a\b(c
+\= Expect no match
+    Xa\\b(c
+No match
+    a\\b(cX
+No match
+    Xa\\b(cX
+No match
+
+//literal,extended
+Failed: error 192 at offset 0: invalid option bits with PCRE2_LITERAL
+
+/a\b(c/literal,auto_callout,no_start_optimize
+    XXXXa\\b(c
+--->XXXXa\b(c
+ +0 ^             a
+ +0  ^            a
+ +0   ^           a
+ +0    ^          a
+ +0     ^         a
+ +1     ^^        \
+ +2     ^ ^       b
+ +3     ^  ^      (
+ +4     ^   ^     c
+ +5     ^    ^    End of pattern
+ 0: a\b(c
+
+/a\b(c/literal,auto_callout
+    XXXXa\\b(c
+--->XXXXa\b(c
+ +0     ^         a
+ +1     ^^        \
+ +2     ^ ^       b
+ +3     ^  ^      (
+ +4     ^   ^     c
+ +5     ^    ^    End of pattern
+ 0: a\b(c
+
+/(*CR)abc/literal
+    (*CR)abc
+ 0: (*CR)abc
+
+/cat|dog/I,match_word
+Capturing subpattern count = 0
+Max lookbehind = 1
+Extra options: match_word
+Starting code units: c d 
+Subject length lower bound = 3
+    the cat sat
+ 0: cat
+\= Expect no match
+    caterpillar
+No match
+    snowcat
+No match
+    syndicate
+No match
+
+/(cat)|dog/I,match_line,literal
+Capturing subpattern count = 0
+Compile options: literal
+Overall options: anchored literal
+Extra options: match_line
+First code unit = '('
+Subject length lower bound = 9
+    (cat)|dog
+ 0: (cat)|dog
+\= Expect no match
+    the cat sat
+No match
+    caterpillar
+No match
+    snowcat
+No match
+    syndicate
+No match
+
+/a whole line/match_line,multiline
+    Rhubarb \na whole line\n custard
+ 0: a whole line
+\= Expect no match
+    Not a whole line
+No match
+
+# Perl gets this wrong, failing to capture 'b' in group 1.
+
+/^(b+|a){1,2}?bc/
+    bbc
+ 0: bbc
+ 1: b
+    
+# And again here, for the "babc" subject string. 
+
+/^(b*|ba){1,2}?bc/
+    babc
+ 0: babc
+ 1: ba
+    bbabc
+ 0: bbabc
+ 1: ba
+    bababc
+ 0: bababc
+ 1: ba
+\= Expect no match
+    bababbc
+No match
+    babababc
+No match
+
+/[[:digit:]-a]/
+Failed: error 150 at offset 10: invalid range in character class
+
+/[[:digit:]-[:print:]]/
+Failed: error 150 at offset 10: invalid range in character class
+
+/[\d-a]/
+Failed: error 150 at offset 3: invalid range in character class
+
+/[\H-z]/
+Failed: error 150 at offset 3: invalid range in character class
+
+/[\d-[:print:]]/
+Failed: error 150 at offset 3: invalid range in character class
+
+# Perl gets the second of these wrong, giving no match.
+
+"(?<=(a))\1?b"I
+Capturing subpattern count = 1
+Max back reference = 1
+Max lookbehind = 1
+Last code unit = 'b'
+Subject length lower bound = 1
+    ab
+ 0: b
+ 1: a
+    aaab 
+ 0: ab
+ 1: a
+
+"(?=(a))\1?b"I
+Capturing subpattern count = 1
+Max back reference = 1
+First code unit = 'a'
+Last code unit = 'b'
+Subject length lower bound = 1
+    ab
+ 0: ab
+ 1: a
+    aaab
+ 0: ab
+ 1: a
+    
+# JIT does not support callout_extra  
+    
+/(*NO_JIT)(a+)b/auto_callout,no_start_optimize,no_auto_possess
+\= Expect no match
+    aac\=callout_extra 
+New match attempt
+--->aac
+ +9 ^       (
++10 ^       a+
++12 ^ ^     )
++13 ^ ^     b
+Backtrack
+--->aac
++12 ^^      )
++13 ^^      b
+Backtrack
+No other matching paths
+New match attempt
+--->aac
+ +9  ^      (
++10  ^      a+
++12  ^^     )
++13  ^^     b
+Backtrack
+No other matching paths
+New match attempt
+--->aac
+ +9   ^     (
++10   ^     a+
+Backtrack
+No other matching paths
+New match attempt
+--->aac
+ +9    ^    (
++10    ^    a+
+No match
+    
+/(*NO_JIT)a+(?C'XXX')b/no_start_optimize,no_auto_possess
+\= Expect no match
+    aac\=callout_extra 
+New match attempt
+Callout (15): 'XXX'
+--->aac
+    ^ ^     b
+Backtrack
+Callout (15): 'XXX'
+--->aac
+    ^^      b
+Backtrack
+No other matching paths
+New match attempt
+Callout (15): 'XXX'
+--->aac
+     ^^     b
+No match
+
+/\n/firstline
+    xyz\nabc
+ 0: \x0a
+
+/\nabc/firstline
+    xyz\nabc
+ 0: \x0aabc
+
+/\x{0a}abc/firstline,newline=crlf
+\= Expect no match
+    xyz\r\nabc
+No match
+
+/[abc]/firstline
+\= Expect no match
+    \na
+No match
+    
+# These tests are matched in test 1 as they are Perl compatible. Here we are
+# looking at what does and does not get auto-possessified. 
+
+/(?(DEFINE)(?<optional_a>a?))^(?&optional_a)a$/B
+------------------------------------------------------------------
+        Bra
+        Cond
+        Cond false
+        CBra 1
+        a?
+        Ket
+        Ket
+        ^
+        Recurse
+        a
+        $
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?(DEFINE)(?<optional_a>a?)X)^(?&optional_a)a$/B
+------------------------------------------------------------------
+        Bra
+        Cond
+        Cond false
+        CBra 1
+        a?
+        Ket
+        X
+        Ket
+        ^
+        Recurse
+        a
+        $
+        Ket
+        End
+------------------------------------------------------------------
+    
+/^(a?)b(?1)a/B
+------------------------------------------------------------------
+        Bra
+        ^
+        CBra 1
+        a?
+        Ket
+        b
+        Recurse
+        a
+        Ket
+        End
+------------------------------------------------------------------
+
+/^(a?)+b(?1)a/B
+------------------------------------------------------------------
+        Bra
+        ^
+        SCBra 1
+        a?
+        KetRmax
+        b
+        Recurse
+        a
+        Ket
+        End
+------------------------------------------------------------------
+
+/^(a?)++b(?1)a/B
+------------------------------------------------------------------
+        Bra
+        ^
+        SCBraPos 1
+        a?
+        KetRpos
+        b
+        Recurse
+        a
+        Ket
+        End
+------------------------------------------------------------------
+
+/^(a?)+b/B
+------------------------------------------------------------------
+        Bra
+        ^
+        SCBra 1
+        a?
+        KetRmax
+        b
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?=a+)a(a+)++b/B
+------------------------------------------------------------------
+        Bra
+        Assert
+        a++
+        Ket
+        a
+        CBraPos 1
+        a++
+        KetRpos
+        b
+        Ket
+        End
+------------------------------------------------------------------
+
+# End of testinput2
+Error -65: PCRE2_ERROR_BADDATA (unknown error number)
 Error -62: bad serialized data
 Error -2: partial match
 Error -1: no match
 Error 0: PCRE2_ERROR_BADDATA (unknown error number)
 Error 100: no error
-Error 188: pattern string is longer than the limit set by the application
-Error 189: PCRE2_ERROR_BADDATA (unknown error number)
+Error 101: \ at end of pattern
+Error 191: PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode
+Error 200: PCRE2_ERROR_BADDATA (unknown error number)
diff --git a/dist2/testdata/testoutput20 b/dist2/testdata/testoutput20
index 952b0bb..d6265fd 100644
--- a/dist2/testdata/testoutput20
+++ b/dist2/testdata/testoutput20
@@ -40,25 +40,25 @@
 Options: dupnames
 Starting code units: b f 
 Subject length lower bound = 6
-    foofoo             
+    foofoo
  0: foofoo
  1: foo
     barbar
  0: barbar
  1: <unset>
  2: bar
-    
+
 #pop mark
     C
  0: C
  1: C
 MK: A
-\= Expect no match     
-    D 
+\= Expect no match
+    D
 No match, mark = A
-    
+
 #pop
-    AmanaplanacanalPanama   
+    AmanaplanacanalPanama
  0: AmanaplanacanalPanama
  1: <unset>
  2: <unset>
@@ -78,7 +78,7 @@
  0: metcalfe 33
  1: metcalfe
  2: 33
-    
+
 # Check for an error when different tables are used.
 
 /abc/push,tables=1
@@ -97,13 +97,13 @@
 #pop should give an error
 ** Can't pop off an empty stack
     pqr
-    
+
 /abcd/pushcopy
     abcd
  0: abcd
-    
+
 #pop
-    abcd 
+    abcd
  0: abcd
 
 #pop should give an error
@@ -113,21 +113,21 @@
 #popcopy
     abcd
  0: abcd
-    
+
 #pop
-    abcd 
+    abcd
  0: abcd
-    
+
 /abcd/push
 #save testsaved1
 #pop should give an error
 ** Can't pop off an empty stack
 
 #load testsaved1
-#popcopy 
+#popcopy
     abcd
  0: abcd
-    
+
 #pop
     abcd
  0: abcd
@@ -135,4 +135,27 @@
 #pop should give an error
 ** Can't pop off an empty stack
 
+/abcd/pushtablescopy
+    abcd
+ 0: abcd
+
+#popcopy
+    abcd
+ 0: abcd
+
+#pop
+    abcd
+ 0: abcd
+
+# Must only specify one of these
+
+//push,pushcopy
+** Not allowed together: push pushcopy
+
+//push,pushtablescopy
+** Not allowed together: push pushtablescopy
+
+//pushcopy,pushtablescopy
+** Not allowed together: pushcopy pushtablescopy
+
 # End of testinput20
diff --git a/dist2/testdata/testoutput21 b/dist2/testdata/testoutput21
index 6bf3f60..cba1326 100644
--- a/dist2/testdata/testoutput21
+++ b/dist2/testdata/testoutput21
@@ -76,7 +76,7 @@
 ------------------------------------------------------------------
 
 /ab\Cde/never_backslash_c
-Failed: error 183 at offset 3: using \C is disabled by the application
+Failed: error 183 at offset 4: using \C is disabled by the application
 
 /ab\Cde/info
 Capturing subpattern count = 0
diff --git a/dist2/testdata/testoutput22-16 b/dist2/testdata/testoutput22-16
index 01c9153..88f827c 100644
--- a/dist2/testdata/testoutput22-16
+++ b/dist2/testdata/testoutput22-16
Binary files differ
diff --git a/dist2/testdata/testoutput22-32 b/dist2/testdata/testoutput22-32
index 100333f..ac485fc 100644
--- a/dist2/testdata/testoutput22-32
+++ b/dist2/testdata/testoutput22-32
Binary files differ
diff --git a/dist2/testdata/testoutput22-8 b/dist2/testdata/testoutput22-8
index 4814039..3d31fbc 100644
--- a/dist2/testdata/testoutput22-8
+++ b/dist2/testdata/testoutput22-8
Binary files differ
diff --git a/dist2/testdata/testoutput23 b/dist2/testdata/testoutput23
index 1da1c39..c6f0aa2 100644
--- a/dist2/testdata/testoutput23
+++ b/dist2/testdata/testoutput23
@@ -3,6 +3,6 @@
 # correct error message.
 
 /a\Cb/
-Failed: error 185 at offset 2: using \C is disabled in this PCRE2 library
+Failed: error 185 at offset 3: using \C is disabled in this PCRE2 library
 
 # End of testinput23
diff --git a/dist2/testdata/testoutput24 b/dist2/testdata/testoutput24
new file mode 100644
index 0000000..9c59893
--- /dev/null
+++ b/dist2/testdata/testoutput24
@@ -0,0 +1,624 @@
+# This file tests the auxiliary pattern conversion features of the PCRE2
+# library, in non-UTF mode.
+
+#forbid_utf
+#newline_default lf any anycrlf
+
+# -------- Tests of glob conversion --------
+
+# Set the glob separator explicitly so that different OS defaults are not a
+# problem. Then test various errors.
+
+#pattern convert=glob,convert_glob_escape=\,convert_glob_separator=/
+
+/abc/posix
+** The convert and posix modifiers are mutually exclusive
+
+# Separator must be / \ or .
+
+/a*b/convert_glob_separator=%
+** Invalid glob separator '%'
+
+# Can't have separator in a class
+
+"[ab/cd]"
+(?s)\A[ab/cd](?<!/)\z
+
+"[,-/]"
+(?s)\A[,-/](?<!/)\z
+
+/[ab/
+** Pattern conversion error at offset 3: missing terminating ] for character class
+
+# Length check
+
+/abc/convert_length=11
+** Pattern conversion error at offset 3: no more memory
+
+/abc/convert_length=12
+(?s)\Aabc\z
+
+# Now some actual tests
+
+/a?b[]xy]*c/
+(?s)\Aa[^/]b[\]xy](*COMMIT)[^/]*?c\z
+    azb]1234c
+ 0: azb]1234c
+
+# Tests from the gitwildmatch list, with some additions
+
+/foo/
+(?s)\Afoo\z
+    foo
+ 0: foo
+/= Expect no match
+No match
+    bar
+No match
+
+//
+(?s)\A\z
+    \
+ 0: 
+
+/???/
+(?s)\A[^/][^/][^/]\z
+    foo
+ 0: foo
+\= Expect no match
+    foobar
+No match
+
+/*/
+(?s)\A[^/]*+\z
+    foo
+ 0: foo
+    \
+ 0: 
+
+/f*/
+(?s)\Af(*COMMIT)[^/]*+\z
+    foo
+ 0: foo
+    f
+ 0: f
+
+/*f/
+(?s)\A[^/]*?f\z
+    oof
+ 0: oof
+\= Expect no match
+    foo
+No match
+
+/*foo*/
+(?s)\A[^/]*?foo(*COMMIT)[^/]*+\z
+    foo
+ 0: foo
+    food
+ 0: food
+    aprilfool
+ 0: aprilfool
+
+/*ob*a*r*/
+(?s)\A[^/]*?ob(*COMMIT)[^/]*?a(*COMMIT)[^/]*?r(*COMMIT)[^/]*+\z
+    foobar
+ 0: foobar
+
+/*ab/
+(?s)\A[^/]*?ab\z
+    aaaaaaabababab
+ 0: aaaaaaabababab
+
+/foo\*/
+(?s)\Afoo\*\z
+    foo*
+ 0: foo*
+
+/foo\*bar/
+(?s)\Afoo\*bar\z
+\= Expect no match
+    foobar
+No match
+
+/f\\oo/
+(?s)\Af\\oo\z
+    f\\oo
+ 0: f\oo
+
+/*[al]?/
+(?s)\A[^/]*?[al][^/]\z
+    ball
+ 0: ball
+
+/[ten]/
+(?s)\A[ten]\z
+\= Expect no match
+    ten
+No match
+
+/t[a-g]n/
+(?s)\At[a-g]n\z
+    ten
+ 0: ten
+
+/a[]]b/
+(?s)\Aa[\]]b\z
+    a]b
+ 0: a]b
+
+/a[]a-]b/
+(?s)\Aa[\]a\-]b\z
+
+/a[]-]b/
+(?s)\Aa[\]\-]b\z
+    a-b
+ 0: a-b
+    a]b
+ 0: a]b
+\= Expect no match
+    aab
+No match
+
+/a[]a-z]b/
+(?s)\Aa[\]a-z]b\z
+    aab
+ 0: aab
+
+/]/
+(?s)\A\]\z
+    ]
+ 0: ]
+
+/t[!a-g]n/
+(?s)\At[^/a-g]n\z
+    ton
+ 0: ton
+\= Expect no match
+    ten
+No match
+
+'[[:alpha:]][[:digit:]][[:upper:]]'
+(?s)\A[[:alpha:]][[:digit:]][[:upper:]]\z
+    a1B
+ 0: a1B
+
+'[[:digit:][:upper:][:space:]]'
+(?s)\A[[:digit:][:upper:][:space:]]\z
+    A
+ 0: A
+    1
+ 0: 1
+    \ \=
+ 0:  
+\= Expect no match
+    a
+No match
+    .
+No match
+
+'[a-c[:digit:]x-z]'
+(?s)\A[a-c[:digit:]x-z]\z
+    5
+ 0: 5
+    b
+ 0: b
+    y
+ 0: y
+\= Expect no match
+    q
+No match
+
+# End of gitwildmatch tests
+
+/*.j?g/
+(?s)\A[^/]*?\.j[^/]g\z
+    pic01.jpg
+ 0: pic01.jpg
+    .jpg
+ 0: .jpg
+    pic02.jxg
+ 0: pic02.jxg
+\= Expect no match
+    pic03.j/g
+No match
+
+/A[+-0]B/
+(?s)\AA[+-0](?<!/)B\z
+    A+B
+ 0: A+B
+    A.B
+ 0: A.B
+    A0B
+ 0: A0B
+\= Expect no match
+    A/B
+No match
+
+/*x?z/
+(?s)\A[^/]*?x[^/]z\z
+    abc.xyz
+ 0: abc.xyz
+\= Expect no match
+    .xyz
+ 0: .xyz
+
+/?x?z/
+(?s)\A[^/]x[^/]z\z
+    axyz
+ 0: axyz
+\= Expect no match
+    .xyz
+ 0: .xyz
+
+"[,-0]x?z"
+(?s)\A[,-0](?<!/)x[^/]z\z
+    ,xyz
+ 0: ,xyz
+\= Expect no match
+    /xyz
+No match
+    .xyz
+ 0: .xyz
+
+".x*"
+(?s)\A\.x(*COMMIT)[^/]*+\z
+    .xabc
+ 0: .xabc
+
+/a[--0]z/
+(?s)\Aa[\--0](?<!/)z\z
+    a-z
+ 0: a-z
+    a.z
+ 0: a.z
+    a0z
+ 0: a0z
+\= Expect no match
+    a/z
+No match
+    a1z
+No match
+
+/<[a-c-d]>/
+(?s)\A<[a-c\-d]>\z
+    <a>
+ 0: <a>
+    <b>
+ 0: <b>
+    <c>
+ 0: <c>
+    <d>
+ 0: <d>
+    <->
+ 0: <->
+
+/a[[:digit:].]z/
+(?s)\Aa[[:digit:].]z\z
+    a1z
+ 0: a1z
+    a.z
+ 0: a.z
+\= Expect no match
+    a:z
+No match
+
+/a[[:digit].]z/
+(?s)\Aa[\[:digit]\.\]z\z
+    a[.]z
+ 0: a[.]z
+    a:.]z
+ 0: a:.]z
+    ad.]z
+ 0: ad.]z
+
+/<[[:a[:digit:]b]>/
+(?s)\A<[\[:a[:digit:]b]>\z
+    <[>
+ 0: <[>
+    <:>
+ 0: <:>
+    <a>
+ 0: <a>
+    <9>
+ 0: <9>
+    <b>
+ 0: <b>
+\= Expect no match
+    <d>
+No match
+
+/a*b/convert_glob_separator=\
+(?s)\Aa(*COMMIT)[^\\]*?b\z
+
+/a*b/convert_glob_separator=.
+(?s)\Aa(*COMMIT)[^\.]*?b\z
+
+/a*b/convert_glob_separator=/
+(?s)\Aa(*COMMIT)[^/]*?b\z
+
+# Non control character checking
+
+/A\B\\C\D/
+(?s)\AAB\\CD\z
+
+/\\{}\?\*+\[\]()|.^$/
+(?s)\A\\\{\}\?\*\+\[\]\(\)\|\.\^\$\z
+
+/*a*\/*b*/
+(?s)\A[^/]*?a(*COMMIT)[^/]*?/(*COMMIT)[^/]*?b(*COMMIT)[^/]*+\z
+
+/?a?\/?b?/
+(?s)\A[^/]a[^/]/[^/]b[^/]\z
+
+/[a\\b\c][]][-][\]\-]/
+(?s)\A[a\\bc][\]][\-][\]\-]\z
+
+/[^a\\b\c][!]][!-][^\]\-]/
+(?s)\A[^/a\\bc][^/\]][^/\-][^/\]\-]\z
+
+/[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:word:][:xdigit:]]/
+(?s)\A[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:word:][:xdigit:]](?<!/)\z
+
+"[/-/]"
+(?s)\A[/-/](?<!/)\z
+
+/[-----]/
+(?s)\A[\--\-\-\-]\z
+
+/[------]/
+(?s)\A[\--\-\--\-]\z
+
+/[!------]/
+(?s)\A[^/\--\-\--\-]\z
+
+/[[:alpha:]-a]/
+(?s)\A[[:alpha:]\-a]\z
+
+/[[:alpha:]][[:punct:]][[:ascii:]]/
+(?s)\A[[:alpha:]][[:punct:]](?<!/)[[:ascii:]](?<!/)\z
+
+/[a-[:alpha:]]/
+** Pattern conversion error at offset 4: invalid syntax
+
+/[[:alpha:/
+** Pattern conversion error at offset 9: missing terminating ] for character class
+
+/[[:alpha:]/
+** Pattern conversion error at offset 10: missing terminating ] for character class
+
+/[[:alphaa:]]/
+(?s)\A[\[:alphaa:]\]\z
+
+/[[:xdigi:]]/
+(?s)\A[\[:xdigi:]\]\z
+
+/[[:xdigit::]]/
+(?s)\A[\[:xdigit::]\]\z
+
+/****/
+(?s)
+
+/**\/abc/
+(?s)(?:\A|/)abc\z
+  abc
+ 0: abc
+  x/abc
+ 0: /abc
+  xabc
+No match
+
+/abc\/**/
+(?s)\Aabc/
+
+/abc\/**\/abc/
+(?s)\Aabc/(*COMMIT)(?:.*?/)??abc\z
+
+/**\/*a*b*g*n*t/
+(?s)(?:\A|/)(?>[^/]*?a)(?>[^/]*?b)(?>[^/]*?g)(?>[^/]*?n)(?>[^/]*?t\z)
+  abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt
+ 0: /abcdefghijklmnop.txt
+
+/**\/*a*\/**/
+(?s)(?:\A|/)(?>[^/]*?a)(?>[^/]*?/)
+  xx/xx/xx/xax/xx/xb
+ 0: /xax/
+
+/**\/*a*/
+(?s)(?:\A|/)(?>[^/]*?a)(?>[^/]*+\z)
+  xx/xx/xx/xax
+ 0: /xax
+  xx/xx/xx/xax/xx
+No match
+
+/**\/*a*\/**\/*b*/
+(?s)(?:\A|/)(?>[^/]*?a)(?>[^/]*?/)(*COMMIT)(?:.*?/)??(?>[^/]*?b)(?>[^/]*+\z)
+  xx/xx/xx/xax/xx/xb
+ 0: /xax/xx/xb
+  xx/xx/xx/xax/xx/x
+No match
+
+"**a"convert=glob
+(?s)a\z
+  a
+ 0: a
+  c/b/a
+ 0: a
+  c/b/aaa
+ 0: a
+
+"a**/b"convert=glob
+(?s)\Aa(*COMMIT).*?/b\z
+  a/b
+ 0: a/b
+  ab
+No match
+
+"a/**b"convert=glob
+(?s)\Aa/(*COMMIT).*?b\z
+  a/b
+ 0: a/b
+  ab
+No match
+
+#pattern convert=glob:glob_no_starstar
+
+/***/
+(?s)\A[^/]*+\z
+
+/**a**/
+(?s)\A[^/]*?a(*COMMIT)[^/]*+\z
+
+#pattern convert=unset
+#pattern convert=glob:glob_no_wild_separator
+
+/*/
+(?s)
+
+/*a*/
+(?s)a
+
+/**a**/
+(?s)a
+
+/a*b/
+(?s)\Aa(*COMMIT).*?b\z
+
+/*a*b*/
+(?s)a(*COMMIT).*?b
+
+/??a??/
+(?s)\A..a..\z
+
+#pattern convert=unset
+#pattern convert=glob,convert_glob_escape=0
+
+/a\b\cd/
+(?s)\Aa\\b\\cd\z
+
+/**\/a/
+(?s)\\/a\z
+
+/a`*b/convert_glob_escape=`
+(?s)\Aa\*b\z
+
+/a`*b/convert_glob_escape=0
+(?s)\Aa`(*COMMIT)[^/]*?b\z
+
+/a`*b/convert_glob_escape=x
+** Invalid glob escape 'x'
+
+# -------- Tests of extended POSIX conversion --------
+
+#pattern convert=unset:posix_extended
+
+/<[[:a[:digit:]b]>/
+(*NUL)<[[:a[:digit:]b]>
+    <[>
+ 0: <[>
+    <:>
+ 0: <:>
+    <a>
+ 0: <a>
+    <9>
+ 0: <9>
+    <b>
+ 0: <b>
+\= Expect no match
+    <d>
+No match
+
+/a+\1b\\c|d[ab\c]/
+(*NUL)a+1b\\c|d[ab\\c]
+
+/<[]bc]>/
+(*NUL)<[]bc]>
+    <]>
+ 0: <]>
+    <b>
+ 0: <b>
+    <c>
+ 0: <c>
+
+/<[^]bc]>/
+(*NUL)<[^]bc]>
+    <.>
+ 0: <.>
+\= Expect no match
+    <]>
+No match
+    <b>
+No match
+
+/(a)\1b/
+(*NUL)(a)1b
+    a1b
+ 0: a1b
+ 1: a
+\= Expect no match
+    aab
+No match
+
+/(ab)c)d]/
+(*NUL)(ab)c\)d\]
+    Xabc)d]Y
+ 0: abc)d]
+ 1: ab
+
+/a***b/
+(*NUL)a*b
+
+# -------- Tests of basic POSIX conversion --------
+
+#pattern convert=unset:posix_basic
+
+/a*b+c\+[def](ab)\(cd\)/
+(*NUL)a*b\+c\+[def]\(ab\)(cd)
+
+/\(a\)\1b/
+(*NUL)(a)\1b
+    aab
+ 0: aab
+ 1: a
+\= Expect no match
+    a1b
+No match
+
+/how.to how\.to/
+(*NUL)how.to how\.to
+    how\nto how.to
+ 0: how\x0ato how.to
+\= Expect no match     
+    how\x{0}to how.to
+No match
+
+/^how to \^how to/
+(*NUL)^how to \^how to
+
+/^*abc/
+(*NUL)^\*abc
+
+/*abc/
+(*NUL)\*abc
+    X*abcY
+ 0: *abc
+
+/**abc/
+(*NUL)\**abc
+    XabcY
+ 0: abc
+    X*abcY
+ 0: *abc
+    X**abcY
+ 0: **abc
+    
+/*ab\(*cd\)/ 
+(*NUL)\*ab(\*cd)
+
+/^b\(c^d\)\(^e^f\)/
+(*NUL)^b(c\^d)(^e\^f)
+
+/a***b/
+(*NUL)a*b
+
+# End of testinput24
diff --git a/dist2/testdata/testoutput25 b/dist2/testdata/testoutput25
new file mode 100644
index 0000000..4990293
--- /dev/null
+++ b/dist2/testdata/testoutput25
@@ -0,0 +1,19 @@
+# This file tests the auxiliary pattern conversion features of the PCRE2 
+# library, in UTF mode.
+
+#newline_default lf any anycrlf
+
+# -------- Tests of glob conversion --------
+
+# Set the glob separator explicitly so that different OS defaults are not a
+# problem. Then test various errors.
+
+#pattern convert=glob,convert_glob_escape=\,convert_glob_separator=/
+
+# The fact that this one works in 13 bytes in the 8-bit library shows that the
+# output is in UTF-8, though pcre2test shows the character as an escape.
+
+/'>' c4 a3 '<'/hex,utf,convert_length=13
+(?s)\A>\x{123}<\z
+
+# End of testinput25
diff --git a/dist2/testdata/testoutput4 b/dist2/testdata/testoutput4
index 701d411..6056e6d 100644
--- a/dist2/testdata/testoutput4
+++ b/dist2/testdata/testoutput4
@@ -958,7 +958,7 @@
  0: M
  0: \x{442}
 
-/[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽƁƂƄƆƇƉƊƋƎƏƐƑƓƔƖƗƘƜƝƟƠƢƤƦƧƩƬƮƯƱƲƳƵƷƸƼDŽLJNJǍǏǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎȐȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾɁΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎҐҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀӁӃӅӇӉӋӍӐӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌἍἎἏἘἙἚἛἜἝἨἩἪἫἬἭἮἯἸἹἺἻἼἽἾἿὈὉὊὋὌὍὙὛὝὟὨὩὪὫὬὭὮὯᾸᾹᾺΆῈΈῊΉῘῙῚΊῨῩῪΎῬῸΌῺΏabcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżžſƀƃƅƈƌƍƒƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎǐǒǔǖǘǚǜǝǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿȁȃȅȇȉȋȍȏȑȓȕȗșțȝȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϐϑϕϖϗϙϛϝϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿҁҋҍҏґғҕҗҙқҝҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛӝӟӡӣӥӧөӫӭӯӱӳӵӷӹԁԃԅԇԉԋԍԏաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹἀἁἂἃἄἅἆἇἐἑἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀὁὂὃὄὅὐὑὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇῐῑῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣⳤⴀⴁⴂⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌⴍⴎⴏⴐⴑⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜⴝⴞⴟⴠⴡⴢⴣⴤⴥfffiflffifflſtstﬓﬔﬕﬖﬗ\d-_^]/utf
+/[^ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽƁƂƄƆƇƉƊƋƎƏƐƑƓƔƖƗƘƜƝƟƠƢƤƦƧƩƬƮƯƱƲƳƵƷƸƼDŽLJNJǍǏǑǓǕǗǙǛǞǠǢǤǦǨǪǬǮDZǴǶǷǸǺǼǾȀȂȄȆȈȊȌȎȐȒȔȖȘȚȜȞȠȢȤȦȨȪȬȮȰȲȺȻȽȾɁΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫϒϓϔϘϚϜϞϠϢϤϦϨϪϬϮϴϷϹϺϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎҐҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӀӁӃӅӇӉӋӍӐӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӶӸԀԂԄԆԈԊԌԎԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸἈἉἊἋἌἍἎἏἘἙἚἛἜἝἨἩἪἫἬἭἮἯἸἹἺἻἼἽἾἿὈὉὊὋὌὍὙὛὝὟὨὩὪὫὬὭὮὯᾸᾹᾺΆῈΈῊΉῘῙῚΊῨῩῪΎῬῸΌῺΏabcdefghijklmnopqrstuvwxyzªµºßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķĸĺļľŀłńņňʼnŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżžſƀƃƅƈƌƍƒƕƙƚƛƞơƣƥƨƪƫƭưƴƶƹƺƽƾƿdžljnjǎǐǒǔǖǘǚǜǝǟǡǣǥǧǩǫǭǯǰdzǵǹǻǽǿȁȃȅȇȉȋȍȏȑȓȕȗșțȝȟȡȣȥȧȩȫȭȯȱȳȴȵȶȷȸȹȼȿɀɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϐϑϕϖϗϙϛϝϟϡϣϥϧϩϫϭϯϰϱϲϳϵϸϻϼабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿҁҋҍҏґғҕҗҙқҝҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӂӄӆӈӊӌӎӑӓӕӗәӛӝӟӡӣӥӧөӫӭӯӱӳӵӷӹԁԃԅԇԉԋԍԏաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆևᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩᴪᴫᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯᵰᵱᵲᵳᵴᵵᵶᵷᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚẛạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹἀἁἂἃἄἅἆἇἐἑἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀὁὂὃὄὅὐὑὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾰᾱᾲᾳᾴᾶᾷιῂῃῄῆῇῐῑῒΐῖῗῠῡῢΰῤῥῦῧῲῳῴῶῷⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣⳤⴀⴁⴂⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌⴍⴎⴏⴐⴑⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜⴝⴞⴟⴠⴡⴢⴣⴤⴥfffiflffifflſtstﬓﬔﬕﬖﬗ\d_^]/utf
 
 /^[^d]*?$/
     abc
@@ -2716,6 +2716,13 @@
     \x{1f88}\x{1f80} 
  0: \x{1f88}\x{1f80}
     
+# Check a reference with more than one other case
+
+/^(\x{00b5})\1{2}$/i,utf        
+    \x{00b5}\x{039c}\x{03bc} 
+ 0: \x{b5}\x{39c}\x{3bc}
+ 1: \x{b5}
+    
 # Characters with more than one other case; test in classes 
 
 /[z\x{00b5}]+/i,utf
@@ -3703,4 +3710,23 @@
     \x{20ac}
 No match
 
+/(?=.*b)\pL/
+    11bb
+ 0: b
+    
+/(?(?=.*b)(?=.*b)\pL|.*c)/
+    11bb
+ 0: b
+
+/^\x{123}+?$/utf,no_auto_possess
+    \x{123}\x{123}\x{123}
+ 0: \x{123}\x{123}\x{123}
+
+/^\x{123}+?$/i,utf,no_auto_possess
+    \x{123}\x{122}\x{123}
+ 0: \x{123}\x{122}\x{123}
+\= Expect no match     
+    \x{123}\x{124}\x{123}
+No match
+
 # End of testinput4
diff --git a/dist2/testdata/testoutput5 b/dist2/testdata/testoutput5
index f19ad8c..4b3171c 100644
--- a/dist2/testdata/testoutput5
+++ b/dist2/testdata/testoutput5
Binary files differ
diff --git a/dist2/testdata/testoutput6 b/dist2/testdata/testoutput6
index 17616c8..b409fe0 100644
--- a/dist2/testdata/testoutput6
+++ b/dist2/testdata/testoutput6
@@ -713,7 +713,7 @@
 /(ab|cd){3,4}/auto_callout
   ababab
 --->ababab
- +0 ^          (ab|cd){3,4}
+ +0 ^          (
  +1 ^          a
  +4 ^          c
  +2 ^^         b
@@ -726,13 +726,13 @@
  +4 ^   ^      c
  +2 ^    ^     b
  +3 ^     ^    |
-+12 ^     ^    
++12 ^     ^    End of pattern
  +1 ^     ^    a
  +4 ^     ^    c
  0: ababab
   abcdabcd
 --->abcdabcd
- +0 ^            (ab|cd){3,4}
+ +0 ^            (
  +1 ^            a
  +4 ^            c
  +2 ^^           b
@@ -740,22 +740,22 @@
  +1 ^ ^          a
  +4 ^ ^          c
  +5 ^  ^         d
- +6 ^   ^        )
+ +6 ^   ^        ){3,4}
  +1 ^   ^        a
  +4 ^   ^        c
  +2 ^    ^       b
  +3 ^     ^      |
-+12 ^     ^      
++12 ^     ^      End of pattern
  +1 ^     ^      a
  +4 ^     ^      c
  +5 ^      ^     d
- +6 ^       ^    )
-+12 ^       ^    
+ +6 ^       ^    ){3,4}
++12 ^       ^    End of pattern
  0: abcdabcd
  1: abcdab
   abcdcdcdcdcd  
 --->abcdcdcdcdcd
- +0 ^                (ab|cd){3,4}
+ +0 ^                (
  +1 ^                a
  +4 ^                c
  +2 ^^               b
@@ -763,17 +763,17 @@
  +1 ^ ^              a
  +4 ^ ^              c
  +5 ^  ^             d
- +6 ^   ^            )
+ +6 ^   ^            ){3,4}
  +1 ^   ^            a
  +4 ^   ^            c
  +5 ^    ^           d
- +6 ^     ^          )
-+12 ^     ^          
+ +6 ^     ^          ){3,4}
++12 ^     ^          End of pattern
  +1 ^     ^          a
  +4 ^     ^          c
  +5 ^      ^         d
- +6 ^       ^        )
-+12 ^       ^        
+ +6 ^       ^        ){3,4}
++12 ^       ^        End of pattern
  0: abcdcdcd
  1: abcdcd
 
@@ -2674,13 +2674,6 @@
     aaa
 No match
 
-/[\d-z]+/
-    12-34z
- 0: 12-34z
-\= Expect no match
-    aaa
-No match
-
 /\x5c/
     \\
  0: \
@@ -5715,17 +5708,6 @@
  0: 
  0: 
 
-/^[\d-a]/
-    abcde
- 0: a
-    -things
- 0: -
-    0digit
- 0: 0
-\= Expect no match
-    bcdef    
-No match
-    
 /[[:space:]]+/
     > \x09\x0a\x0c\x0d\x0b<
  0:  \x09\x0a\x0c\x0d\x0b
@@ -6628,14 +6610,14 @@
  +0 ^       x
  +1 ^^      y
  +2 ^ ^     z
- +3 ^  ^    
+ +3 ^  ^    End of pattern
  0: xyz
   abcxyz 
 --->abcxyz
  +0    ^       x
  +1    ^^      y
  +2    ^ ^     z
- +3    ^  ^    
+ +3    ^  ^    End of pattern
  0: xyz
 \= Expect no match 
   abc
@@ -6652,7 +6634,7 @@
  +0    ^       x
  +1    ^^      y
  +2    ^ ^     z
- +3    ^  ^    
+ +3    ^  ^    End of pattern
  0: xyz
 \= Expect no match 
   abc
@@ -6686,7 +6668,7 @@
 +15    ^       x
 +16    ^^      y
 +17    ^ ^     z
-+18    ^  ^    
++18    ^  ^    End of pattern
  0: xyz
   
 /(?C)ab/
@@ -6702,7 +6684,7 @@
 --->ab
  +0 ^      a
  +1 ^^     b
- +2 ^ ^    
+ +2 ^ ^    End of pattern
  0: ab
   ab\=callout_none
  0: ab
@@ -6712,30 +6694,30 @@
 --->"ab"
  +0 ^        ^
  +1 ^        "
- +2 ^^       ((?(?=[a])[^"])|b)*
+ +2 ^^       (
 +21 ^^       "
- +3 ^^       (?(?=[a])[^"])
+ +3 ^^       (?
 +18 ^^       b
- +5 ^^       (?=[a])
+ +5 ^^       (?=
  +8  ^       [a]
 +11  ^^      )
 +12 ^^       [^"]
 +16 ^ ^      )
 +17 ^ ^      |
 +21 ^ ^      "
- +3 ^ ^      (?(?=[a])[^"])
+ +3 ^ ^      (?
 +18 ^ ^      b
- +5 ^ ^      (?=[a])
+ +5 ^ ^      (?=
  +8   ^      [a]
-+19 ^  ^     )
++19 ^  ^     )*
 +21 ^  ^     "
- +3 ^  ^     (?(?=[a])[^"])
+ +3 ^  ^     (?
 +18 ^  ^     b
- +5 ^  ^     (?=[a])
+ +5 ^  ^     (?=
  +8    ^     [a]
 +17 ^  ^     |
 +22 ^   ^    $
-+23 ^   ^    
++23 ^   ^    End of pattern
  0: "ab"
     "ab"\=callout_none
  0: "ab"
@@ -7154,7 +7136,7 @@
     aaaabcde
  0: aaaab
 
-/((?(R2)a+|(?1)b))/
+/((?(R2)a+|(?1)b))()/
     aaaabcde
 Failed: error -40: backreference condition or recursion test is not supported for DFA matching
 
@@ -7517,7 +7499,6 @@
 /^a(b)c(?C1)def/
       abcdef\=callout_capture
 Callout 1: last capture = 0
- 0: 
 --->abcdef
     ^  ^       d
  0: abcdef
@@ -7538,7 +7519,6 @@
 ------------------------------------------------------------------
       abcdef\=callout_capture
 Callout (10): {AB} last capture = 0
- 0: 
 --->abcdef
     ^  ^       d
  0: abcdef
@@ -7548,7 +7528,7 @@
         Bra
         ^
         Cond
-        Callout 25 9 7
+        Callout 25 9 3
         Assert
         abc
         Ket
@@ -7561,11 +7541,11 @@
 ------------------------------------------------------------------
     abcdefg
 --->abcdefg
- 25 ^           (?=abc)
+ 25 ^           (?=
  0: abcd
     xyz123 
 --->xyz123
- 25 ^          (?=abc)
+ 25 ^          (?=
  0: xyz
 
 /^(?(?C$abc$)(?=abc)abcd|xyz)/B
@@ -7573,7 +7553,7 @@
         Bra
         ^
         Cond
-        CalloutStr $abc$ 7 12 7
+        CalloutStr $abc$ 7 12 3
         Assert
         abc
         Ket
@@ -7587,12 +7567,12 @@
     abcdefg
 Callout (7): $abc$
 --->abcdefg
-    ^           (?=abc)
+    ^           (?=
  0: abcd
     xyz123 
 Callout (7): $abc$
 --->xyz123
-    ^          (?=abc)
+    ^          (?=
  0: xyz
 
 /^ab(?C'first')cd(?C"second")ef/
@@ -7609,13 +7589,13 @@
     aaaXY
 Callout (8): `code`
 --->aaaXY
-    ^^        )
+    ^^        ){3}
 Callout (8): `code`
 --->aaaXY
-    ^ ^       )
+    ^ ^       ){3}
 Callout (8): `code`
 --->aaaXY
-    ^  ^      )
+    ^  ^      ){3}
  0: aaaX
 
 # Binary zero in callout string
@@ -7673,13 +7653,122 @@
  0: abcd
 
 /()()a+/no_auto_possess
-    aaa\=dfa,allcaptures
+    aaa\=allcaptures
 ** Ignored after DFA matching: allcaptures
  0: aaa
  1: aa
  2: a
-    a\=dfa,allcaptures
+    a\=allcaptures
 ** Ignored after DFA matching: allcaptures
  0: a
 
+/(*LIMIT_DEPTH=100)^((.)(?1)|.)$/
+\= Expect depth limit exceeded
+    a[00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]
+Failed: error -53: matching depth limit exceeded
+
+/(02-)?[0-9]{3}-[0-9]{3}/
+    02-123-123
+ 0: 02-123-123
+
+/^(a(?2))(b)(?1)/
+    abbab\=find_limits 
+Minimum match limit = 4
+Minimum depth limit = 2
+ 0: abbab
+
+/abc/endanchored
+    xyzabc
+ 0: abc
+\= Expect no match
+    xyzabcdef
+No match
+\= Expect error
+    xyzabc\=ph
+Failed: error -34: bad option value
+
+/abc/
+    xyzabc\=endanchored
+ 0: abc
+\= Expect no match
+    xyzabcdef\=endanchored
+No match
+\= Expect error
+    xyzabc\=ps,endanchored
+Failed: error -34: bad option value
+
+/abc|bcd/endanchored
+    xyzabcd
+ 0: bcd
+\= Expect no match
+    xyzabcdef
+No match
+
+/(*NUL)^.*/
+    a\nb\x00ccc
+ 0: a\x0ab
+    
+/(*NUL)^.*/s
+    a\nb\x00ccc
+ 0: a\x0ab\x00ccc
+    
+/^x/m,newline=nul
+    ab\x00xy
+ 0: x
+    
+/'#comment' 0d 0a 00 '^x\' 0a 'y'/x,newline=nul,hex
+    x\nyz 
+ 0: x\x0ay
+ 
+/(*NUL)^X\NY/
+    X\nY
+ 0: X\x0aY
+    X\rY
+ 0: X\x0dY
+\= Expect no match
+    X\x00Y      
+No match
+
+/(?<=abc|)/
+    abcde\=aftertext
+ 0: 
+ 0+ abcde
+    
+/(?<=|abc)/ 
+    abcde\=aftertext
+ 0: 
+ 0+ abcde
+
+/(?<=abc|)/endanchored
+    abcde\=aftertext
+ 0: 
+ 0+ 
+    
+/(?<=|abc)/endanchored
+    abcde\=aftertext
+ 0: 
+ 0+ 
+
+/(*LIMIT_MATCH=100).*(?![|H]?.*(?![|H]?););.*(?![|H]?.*(?![|H]?););\x00\x00\x00\x00\x00\x00\x00(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?![|);)?.*(![|H]?);)?.*(?![|H]?);)?.*(?![|H]?);)?.*(?![|H]););![|H]?););[|H]?);|H]?);)\x00\x00\x00\x00\x00\x00H]?););?![|H]?);)?.*(?![|H]?););[||H]?);)?.*(?![|H]?););[|H]?);(?![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););;[\x00\x00\x00\x00\x00\x00\x00![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););/no_dotstar_anchor
+.*(?![|H]?.*(?![|H]?););.*(?![|H]?.*(?![|H]?););\x00\x00\x00\x00\x00\x00\x00(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?!(?![|);)?.*(![|H]?);)?.*(?![|H]?);)?.*(?![|H]?);)?.*(?![|H]););![|H]?););[|H]?);|H]?);)\x00\x00\x00\x00\x00\x00H]?););?![|H]?);)?.*(?![|H]?););[||H]?);)?.*(?![|H]?););[|H]?);(?![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););;[\x00\x00\x00\x00\x00\x00\x00![|H]?););![|H]?););[|H]?);|H]?);)?.*(?![|H]?););
+Failed: error -47: match limit exceeded
+
+/\n/firstline
+    xyz\nabc
+ 0: \x0a
+
+/\nabc/firstline
+    xyz\nabc
+ 0: \x0aabc
+
+/\x{0a}abc/firstline,newline=crlf
+\= Expect no match
+    xyz\r\nabc
+No match
+
+/[abc]/firstline
+\= Expect no match
+    \na
+No match
+    
 # End of testinput6
diff --git a/dist2/testdata/testoutput8-16-2 b/dist2/testdata/testoutput8-16-2
index 39415b7..47c9e56 100644
--- a/dist2/testdata/testoutput8-16-2
+++ b/dist2/testdata/testoutput8-16-2
@@ -187,7 +187,7 @@
   0  17 Bra
   2  13 CBra 1
   5     a
-  7   4 Once
+  7   4 SBra
   9   2 Recurse
  11   4 KetRmax
  13     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  21 Bra
-  2   4 Once
-  4  14 Recurse
-  6   4 Ket
-  8   4 Once
- 10  14 Recurse
- 12   4 Ket
- 14   5 CBra 1
- 17     a
- 19   5 Ket
- 21  21 Ket
- 23     End
+  0  13 Bra
+  2   6 Recurse
+  4   6 Recurse
+  6   5 CBra 1
+  9     a
+ 11   5 Ket
+ 13  13 Ket
+ 15     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -850,27 +846,19 @@
 /(?|(?|(?J:(?|(?x:(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|
 )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
 /parens_nest_limit=1000,-fullbincode
-Failed: error 184 at offset 1540: (?| and/or (?J: or (?x: parentheses are too deeply nested
+Failed: error 184 at offset 1504: (?| and/or (?J: or (?x: parentheses are too deeply nested
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
-Failed: error 186 at offset 594: regular expression is too complicated
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
-Failed: error 186 at offset 594: regular expression is too complicated
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-Failed: error 186 at offset 594: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-Failed: error 186 at offset 594: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 594: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
@@ -1031,6 +1019,5 @@
 Failed: error 114 at offset 509: missing closing parenthesis
 
 /([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))/-fullbincode
-Failed: error 186 at offset 490: regular expression is too complicated
 
 # End of testinput8
diff --git a/dist2/testdata/testoutput8-16-3 b/dist2/testdata/testoutput8-16-3
index 61a98eb..722b0e1 100644
--- a/dist2/testdata/testoutput8-16-3
+++ b/dist2/testdata/testoutput8-16-3
@@ -187,7 +187,7 @@
   0  23 Bra
   3  17 CBra 1
   7     a
-  9   6 Once
+  9   6 SBra
  12   3 Recurse
  15   6 KetRmax
  18     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  30 Bra
-  3   6 Once
-  6  21 Recurse
-  9   6 Ket
- 12   6 Once
- 15  21 Recurse
- 18   6 Ket
- 21   6 CBra 1
- 25     a
- 27   6 Ket
- 30  30 Ket
- 33     End
+  0  18 Bra
+  3   9 Recurse
+  6   9 Recurse
+  9   6 CBra 1
+ 13     a
+ 15   6 Ket
+ 18  18 Ket
+ 21     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -853,20 +849,15 @@
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-Failed: error 186 at offset 1147: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 1147: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
diff --git a/dist2/testdata/testoutput8-32-2 b/dist2/testdata/testoutput8-32-2
index 49ef506..30667a3 100644
--- a/dist2/testdata/testoutput8-32-2
+++ b/dist2/testdata/testoutput8-32-2
@@ -187,7 +187,7 @@
   0  17 Bra
   2  13 CBra 1
   5     a
-  7   4 Once
+  7   4 SBra
   9   2 Recurse
  11   4 KetRmax
  13     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  21 Bra
-  2   4 Once
-  4  14 Recurse
-  6   4 Ket
-  8   4 Once
- 10  14 Recurse
- 12   4 Ket
- 14   5 CBra 1
- 17     a
- 19   5 Ket
- 21  21 Ket
- 23     End
+  0  13 Bra
+  2   6 Recurse
+  4   6 Recurse
+  6   5 CBra 1
+  9     a
+ 11   5 Ket
+ 13  13 Ket
+ 15     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -853,20 +849,15 @@
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-Failed: error 186 at offset 979: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 979: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
diff --git a/dist2/testdata/testoutput8-32-3 b/dist2/testdata/testoutput8-32-3
index 49ef506..30667a3 100644
--- a/dist2/testdata/testoutput8-32-3
+++ b/dist2/testdata/testoutput8-32-3
@@ -187,7 +187,7 @@
   0  17 Bra
   2  13 CBra 1
   5     a
-  7   4 Once
+  7   4 SBra
   9   2 Recurse
  11   4 KetRmax
  13     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  21 Bra
-  2   4 Once
-  4  14 Recurse
-  6   4 Ket
-  8   4 Once
- 10  14 Recurse
- 12   4 Ket
- 14   5 CBra 1
- 17     a
- 19   5 Ket
- 21  21 Ket
- 23     End
+  0  13 Bra
+  2   6 Recurse
+  4   6 Recurse
+  6   5 CBra 1
+  9     a
+ 11   5 Ket
+ 13  13 Ket
+ 15     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -853,20 +849,15 @@
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-Failed: error 186 at offset 979: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 979: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
diff --git a/dist2/testdata/testoutput8-32-4 b/dist2/testdata/testoutput8-32-4
index 49ef506..30667a3 100644
--- a/dist2/testdata/testoutput8-32-4
+++ b/dist2/testdata/testoutput8-32-4
@@ -187,7 +187,7 @@
   0  17 Bra
   2  13 CBra 1
   5     a
-  7   4 Once
+  7   4 SBra
   9   2 Recurse
  11   4 KetRmax
  13     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  21 Bra
-  2   4 Once
-  4  14 Recurse
-  6   4 Ket
-  8   4 Once
- 10  14 Recurse
- 12   4 Ket
- 14   5 CBra 1
- 17     a
- 19   5 Ket
- 21  21 Ket
- 23     End
+  0  13 Bra
+  2   6 Recurse
+  4   6 Recurse
+  6   5 CBra 1
+  9     a
+ 11   5 Ket
+ 13  13 Ket
+ 15     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -853,20 +849,15 @@
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-Failed: error 186 at offset 979: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 979: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
diff --git a/dist2/testdata/testoutput8-8-2 b/dist2/testdata/testoutput8-8-2
index 0d15a82..4b03356 100644
--- a/dist2/testdata/testoutput8-8-2
+++ b/dist2/testdata/testoutput8-8-2
@@ -187,7 +187,7 @@
   0  24 Bra
   3  18 CBra 1
   8     a
- 10   6 Once
+ 10   6 SBra
  13   3 Recurse
  16   6 KetRmax
  19     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  31 Bra
-  3   6 Once
-  6  21 Recurse
-  9   6 Ket
- 12   6 Once
- 15  21 Recurse
- 18   6 Ket
- 21   7 CBra 1
- 26     a
- 28   7 Ket
- 31  31 Ket
- 34     End
+  0  19 Bra
+  3   9 Recurse
+  6   9 Recurse
+  9   7 CBra 1
+ 14     a
+ 16   7 Ket
+ 19  19 Ket
+ 22     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -850,26 +846,19 @@
 /(?|(?|(?J:(?|(?x:(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|(?|
 )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
 /parens_nest_limit=1000,-fullbincode
-Failed: error 184 at offset 1540: (?| and/or (?J: or (?x: parentheses are too deeply nested
+Failed: error 184 at offset 1504: (?| and/or (?J: or (?x: parentheses are too deeply nested
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
-Failed: error 186 at offset 637: regular expression is too complicated
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-Failed: error 186 at offset 637: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-Failed: error 186 at offset 637: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 637: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
diff --git a/dist2/testdata/testoutput8-8-3 b/dist2/testdata/testoutput8-8-3
index 50d715d..3d33c77 100644
--- a/dist2/testdata/testoutput8-8-3
+++ b/dist2/testdata/testoutput8-8-3
@@ -187,7 +187,7 @@
   0  30 Bra
   4  22 CBra 1
  10     a
- 12   8 Once
+ 12   8 SBra
  16   4 Recurse
  20   8 KetRmax
  24     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  40 Bra
-  4   8 Once
-  8  28 Recurse
- 12   8 Ket
- 16   8 Once
- 20  28 Recurse
- 24   8 Ket
- 28   8 CBra 1
- 34     a
- 36   8 Ket
- 40  40 Ket
- 44     End
+  0  24 Bra
+  4  12 Recurse
+  8  12 Recurse
+ 12   8 CBra 1
+ 18     a
+ 20   8 Ket
+ 24  24 Ket
+ 28     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -853,21 +849,15 @@
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-Failed: error 186 at offset 936: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-Failed: error 186 at offset 936: regular expression is too complicated
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 936: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
diff --git a/dist2/testdata/testoutput8-8-4 b/dist2/testdata/testoutput8-8-4
index 8ebfad5..db04971 100644
--- a/dist2/testdata/testoutput8-8-4
+++ b/dist2/testdata/testoutput8-8-4
@@ -187,7 +187,7 @@
   0  36 Bra
   5  26 CBra 1
  12     a
- 14  10 Once
+ 14  10 SBra
  19   5 Recurse
  24  10 KetRmax
  29     b
@@ -759,18 +759,14 @@
 
 "(?1)(?#?'){2}(a)"
 ------------------------------------------------------------------
-  0  49 Bra
-  5  10 Once
- 10  35 Recurse
- 15  10 Ket
- 20  10 Once
- 25  35 Recurse
- 30  10 Ket
- 35   9 CBra 1
- 42     a
- 44   9 Ket
- 49  49 Ket
- 54     End
+  0  29 Bra
+  5  15 Recurse
+ 10  15 Recurse
+ 15   9 CBra 1
+ 22     a
+ 24   9 Ket
+ 29  29 Ket
+ 34     End
 ------------------------------------------------------------------
 
 /.((?2)(?R)|\1|$)()/
@@ -853,19 +849,15 @@
 
 # Use "expand" to create some very long patterns with nested parentheses, in
 # order to test workspace overflow. Again, this varies with code unit width,
-# and even with it fails in two modes, the error offset differs. It also varies
+# and even when it fails in two modes, the error offset differs. It also varies
 # with link size - hence multiple tests with different values.
 
-/(?'ABC'\[[bar](]{105}*THEN:\[A]{255}\[)]{106}/expand,-fullbincode
+/(?'ABC'\[[bar](]{792}*THEN:\[A]{255}\[)]{793}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{106}*THEN:\[A]{255}\[)]{107}/expand,-fullbincode
+/(?'ABC'\[[bar](]{793}*THEN:\[A]{255}\[)]{794}/expand,-fullbincode,parens_nest_limit=1000
 
-/(?'ABC'\[[bar](]{159}*THEN:\[A]{255}\[)]{160}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{199}*THEN:\[A]{255}\[)]{200}/expand,-fullbincode
-
-/(?'ABC'\[[bar](]{299}*THEN:\[A]{255}\[)]{300}/expand,-fullbincode
-Failed: error 186 at offset 1224: regular expression is too complicated
+/(?'ABC'\[[bar](]{1793}*THEN:\[A]{255}\[)]{1794}/expand,-fullbincode,parens_nest_limit=2000
+Failed: error 186 at offset 12820: regular expression is too complicated
 
 /(?(1)(?1)){8,}+()/debug
 ------------------------------------------------------------------
diff --git a/dist2/testdata/testoutput9 b/dist2/testdata/testoutput9
index 750a7e0..6b014e5 100644
--- a/dist2/testdata/testoutput9
+++ b/dist2/testdata/testoutput9
@@ -307,14 +307,14 @@
 ------------------------------------------------------------------
 
 /\777/I
-Failed: error 151 at offset 3: octal value is greater than \377 in 8-bit non-UTF-8 mode
+Failed: error 151 at offset 4: octal value is greater than \377 in 8-bit non-UTF-8 mode
 
 /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/mark
 Failed: error 176 at offset 259: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
     XX
      
 /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/mark,alt_verbnames
-Failed: error 176 at offset 258: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
+Failed: error 176 at offset 259: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
     XX
      
 /(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/mark
@@ -328,10 +328,10 @@
 MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
 
 /\u0100/alt_bsux,allow_empty_class,match_unset_backref,dupnames
-Failed: error 177 at offset 5: character code point value in \u.... sequence is too large
+Failed: error 177 at offset 6: character code point value in \u.... sequence is too large
 
 /[\u0100-\u0200]/alt_bsux,allow_empty_class,match_unset_backref,dupnames
-Failed: error 177 at offset 6: character code point value in \u.... sequence is too large
+Failed: error 177 at offset 7: character code point value in \u.... sequence is too large
 
 /[^\x00-a]{12,}[^b-\xff]*/B
 ------------------------------------------------------------------
@@ -364,4 +364,7 @@
 /(*MARK:a\x{100}b)z/alt_verbnames 
 Failed: error 134 at offset 14: character code point value in \x{} or \o{} is too large
 
+/(*:*++++++++++++''''''''''''''''''''+''+++'+++x+++++++++++++++++++++++++++++++++++(++++++++++++++++++++:++++++%++:''''''''''''''''''''''''+++++++++++++++++++++++++++++++++++++++++++++++++++++-++++++++k+++++++''''+++'+++++++++++++++++++++++''''++++++++++++':ƿ)/
+Failed: error 176 at offset 259: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
+
 # End of testinput9
diff --git a/include_internal/config.h b/include_internal/config.h
index 5c52b8a..775f55f 100644
--- a/include_internal/config.h
+++ b/include_internal/config.h
@@ -1,6 +1,7 @@
 /* src/config.h.  Generated from config.h.in by configure.  */
 /* src/config.h.in.  Generated from configure.ac by autoheader.  */
 
+
 /* PCRE2 is written in Standard C, but there are a few non-standard things it
 can cope with, allowing it to run on SunOS4 and other "close to standard"
 systems.
@@ -78,6 +79,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #define HAVE_MEMORY_H 1
 
+/* Define to 1 if you have the `mkostemp' function. */
+#define HAVE_MKOSTEMP 1
+
 /* Define if you have POSIX threads libraries and header files. */
 /* #undef HAVE_PTHREAD */
 
@@ -90,6 +94,9 @@
 /* Define to 1 if you have the <readline/readline.h> header file. */
 /* #undef HAVE_READLINE_READLINE_H */
 
+/* Define to 1 if you have the `secure_getenv' function. */
+/* #undef HAVE_SECURE_GETENV */
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #define HAVE_STDINT_H 1
 
@@ -111,6 +118,9 @@
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
 
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #define HAVE_UNISTD_H 1
 
@@ -123,75 +133,56 @@
 /* Define to 1 if you have the <zlib.h> header file. */
 #define HAVE_ZLIB_H 1
 
-/* PCRE2 uses recursive function calls to handle backtracking while matching.
-   This can sometimes be a problem on systems that have stacks of limited
-   size. Define HEAP_MATCH_RECURSE to any value to get a version that doesn't
-   use recursion in the match() function; instead it creates its own stack by
-   steam using memory from the heap. For more detail, see the comments and
-   other stuff just above the match() function. */
-/* #undef HEAP_MATCH_RECURSE */
+/* This limits the amount of memory that pcre2_match() may use while matching
+   a pattern. The value is in kilobytes. */
+#define HEAP_LIMIT 20000000
 
 /* The value of LINK_SIZE determines the number of bytes used to store links
    as offsets within the compiled regex. The default is 2, which allows for
    compiled patterns up to 64K long. This covers the vast majority of cases.
    However, PCRE2 can also be compiled to use 3 or 4 bytes instead. This
    allows for longer patterns in extreme cases. */
-#ifndef LINK_SIZE
 #define LINK_SIZE 2
-#endif
 
 /* Define to the sub-directory where libtool stores uninstalled libraries. */
-/* This is ignored unless you are using libtool. */
-#ifndef LT_OBJDIR
 #define LT_OBJDIR ".libs/"
-#endif
 
 /* The value of MATCH_LIMIT determines the default number of times the
-   internal match() function can be called during a single execution of
-   pcre2_match(). There is a runtime interface for setting a different limit.
-   The limit exists in order to catch runaway regular expressions that take
-   for ever to determine that they do not match. The default is set very large
-   so that it does not accidentally catch legitimate cases. */
-#ifndef MATCH_LIMIT
+   pcre2_match() function can record a backtrack position during a single
+   matching attempt. There is a runtime interface for setting a different
+   limit. The limit exists in order to catch runaway regular expressions that
+   take for ever to determine that they do not match. The default is set very
+   large so that it does not accidentally catch legitimate cases. */
 #define MATCH_LIMIT 10000000
-#endif
 
-/* The above limit applies to all calls of match(), whether or not they
-   increase the recursion depth. In some environments it is desirable to limit
-   the depth of recursive calls of match() more strictly, in order to restrict
-   the maximum amount of stack (or heap, if HEAP_MATCH_RECURSE is defined)
-   that is used. The value of MATCH_LIMIT_RECURSION applies only to recursive
-   calls of match(). To have any useful effect, it must be less than the value
-   of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There
-   is a runtime method for setting a different limit. */
-#ifndef MATCH_LIMIT_RECURSION
-#define MATCH_LIMIT_RECURSION MATCH_LIMIT
-#endif
+/* The above limit applies to all backtracks, whether or not they are nested.
+   In some environments it is desirable to limit the nesting of backtracking
+   (that is, the depth of tree that is searched) more strictly, in order to
+   restrict the maximum amount of heap memory that is used. The value of
+   MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it
+   must be less than the value of MATCH_LIMIT. The default is to use the same
+   value as MATCH_LIMIT. There is a runtime method for setting a different
+   limit. */
+#define MATCH_LIMIT_DEPTH MATCH_LIMIT
 
 /* This limit is parameterized just in case anybody ever wants to change it.
    Care must be taken if it is increased, because it guards against integer
    overflow caused by enormously large patterns. */
-#ifndef MAX_NAME_COUNT
 #define MAX_NAME_COUNT 10000
-#endif
 
 /* This limit is parameterized just in case anybody ever wants to change it.
    Care must be taken if it is increased, because it guards against integer
    overflow caused by enormously large patterns. */
-#ifndef MAX_NAME_SIZE
 #define MAX_NAME_SIZE 32
-#endif
 
 /* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */
 /* #undef NEVER_BACKSLASH_C */
 
 /* 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), and 5
-   (ANYCRLF). */
-#ifndef NEWLINE_DEFAULT
+   at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5
+   (ANYCRLF), and 6 (NUL). */
 #define NEWLINE_DEFAULT 2
-#endif
 
 /* Name of package */
 #define PACKAGE "pcre2"
@@ -203,7 +194,7 @@
 #define PACKAGE_NAME "PCRE2"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE2 10.21"
+#define PACKAGE_STRING "PCRE2 10.31"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "pcre2"
@@ -212,27 +203,40 @@
 #define PACKAGE_URL ""
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "10.21"
+#define PACKAGE_VERSION "10.31"
 
 /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
    parentheses (of any kind) in a pattern. This limits the amount of system
    stack that is used while compiling a pattern. */
-#ifndef PARENS_NEST_LIMIT
 #define PARENS_NEST_LIMIT 250
-#endif
 
-/* The value of PCRE2GREP_BUFSIZE determines the size of buffer used by
-   pcre2grep to hold parts of the file it is searching. This is also the
-   minimum value. 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
+/* 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. */
 #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. */
+#define PCRE2GREP_MAX_BUFSIZE 1048576
+
+/* to make a symbol visible */
+#define PCRE2POSIX_EXP_DECL extern __attribute__ ((visibility ("default")))
+
+/* to make a symbol visible */
+#define PCRE2POSIX_EXP_DEFN extern __attribute__ ((visibility ("default")))
 
 /* Define to any value to include debugging code. */
 /* #undef PCRE2_DEBUG */
 
+/* to make a symbol visible */
+#define PCRE2_EXP_DECL extern __attribute__ ((visibility ("default")))
+
+
 /* If you are compiling for a system other than a Unix-like system or
    Win32, and it needs some magic to be inserted before the definition
    of a function that is exported by the library, define this macro to
@@ -242,7 +246,7 @@
    This macro apears at the start of every exported function that is part
    of the external API. It does not appear on functions that are "external"
    in the C sense, but which are internal to the library. */
-/* #undef PCRE2_EXP_DEFN */
+#define PCRE2_EXP_DEFN __attribute__ ((visibility ("default")))
 
 /* Define to any value if linking statically (TODO: make nice with Libtool) */
 /* #undef PCRE2_STATIC */
@@ -251,11 +255,16 @@
    your system. */
 /* #undef PTHREAD_CREATE_JOINABLE */
 
+/* Define to any non-zero number to enable support for SELinux compatible
+   executable memory allocator in JIT. Note that this will have no effect
+   unless SUPPORT_JIT is also defined. */
+/* #undef SLJIT_PROT_EXECUTABLE_ALLOCATOR */
+
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Define to any value to enable support for Just-In-Time compiling. */
-/* #undef SUPPORT_JIT  */
+/* #undef SUPPORT_JIT */
 
 /* Define to any value to allow pcre2grep to be linked with libbz2, so that it
    is able to handle .bz2 files. */
@@ -271,7 +280,11 @@
    is able to handle .gz files. */
 /* #undef SUPPORT_LIBZ */
 
-/* Define to any value to enable JIT support in pcre2grep. */
+/* Define to any value to enable callout script support in pcre2grep. */
+#define SUPPORT_PCRE2GREP_CALLOUT /**/
+
+/* Define to any value to enable JIT support in pcre2grep. Note that this will
+   have no effect unless SUPPORT_JIT is also defined. */
 /* #undef SUPPORT_PCRE2GREP_JIT */
 
 /* Define to any value to enable the 16 bit PCRE2 library. */
@@ -281,19 +294,51 @@
 /* #undef SUPPORT_PCRE2_32 */
 
 /* Define to any value to enable the 8 bit PCRE2 library. */
-#define SUPPORT_PCRE2_8 1
+#define SUPPORT_PCRE2_8 /**/
 
 /* Define to any value to enable support for Unicode and UTF encoding. This
    will work even in an EBCDIC environment, but it is incompatible with the
    EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or*
    ASCII/Unicode, but not both at once. */
-/* #undef SUPPORT_UNICODE */
+#define SUPPORT_UNICODE /**/
 
 /* Define to any value for valgrind support to find invalid memory reads. */
 /* #undef SUPPORT_VALGRIND */
 
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
 /* Version number of package */
-#define VERSION "10.21"
+#define VERSION "10.31"
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */